11
11
# ANY KIND, either express or implied. See the License for the specific
12
12
# language governing permissions and limitations under the License.
13
13
"""Unit test suite for aws_encryption_sdk.streaming_client._EncryptionStream"""
14
+ import copy
14
15
import io
15
- import unittest
16
16
17
17
import attr
18
18
import pytest
19
- import six
20
19
from mock import MagicMock , PropertyMock , call , patch , sentinel
21
20
22
21
import aws_encryption_sdk .exceptions
@@ -45,20 +44,22 @@ def _read_bytes(self, b):
45
44
return self .config .mock_read_bytes
46
45
47
46
48
- class TestEncryptionStream (unittest . TestCase ):
49
- def setUp (self ):
50
- self . mock_source_stream = MagicMock ()
51
- self . mock_source_stream . __class__ = io . IOBase
52
- self . mock_source_stream . tell . side_effect = ( 10 , 500 )
47
+ class TestEncryptionStream (object ):
48
+ def _mock_key_provider (self ):
49
+ mock_key_provider = MagicMock ()
50
+ mock_key_provider . __class__ = MasterKeyProvider
51
+ return mock_key_provider
53
52
54
- self .mock_key_provider = MagicMock ()
55
- self .mock_key_provider .__class__ = MasterKeyProvider
53
+ def _mock_source_stream (self ):
54
+ mock_source_stream = MagicMock ()
55
+ mock_source_stream .__class__ = io .IOBase
56
+ mock_source_stream .tell .side_effect = (10 , 500 )
57
+ return mock_source_stream
56
58
57
- self .mock_line_length = MagicMock ()
58
- self .mock_line_length .__class__ = int
59
-
60
- self .mock_source_length = MagicMock ()
61
- self .mock_source_length .__class__ = int
59
+ @pytest .fixture (autouse = True )
60
+ def apply_fixtures (self ):
61
+ self .mock_key_provider = self ._mock_key_provider ()
62
+ self .mock_source_stream = self ._mock_source_stream ()
62
63
63
64
def test_read_bytes_enforcement (self ):
64
65
class TestStream (_EncryptionStream ):
@@ -67,19 +68,23 @@ class TestStream(_EncryptionStream):
67
68
def _prep_message (self ):
68
69
pass
69
70
70
- with six . assertRaisesRegex ( self , TypeError , "Can't instantiate abstract class TestStream" ) :
71
+ with pytest . raises ( TypeError ) as excinfo :
71
72
TestStream ()
72
73
74
+ excinfo .match ("Can't instantiate abstract class TestStream" )
75
+
73
76
def test_prep_message_enforcement (self ):
74
77
class TestStream (_EncryptionStream ):
75
78
_config_class = MockClientConfig
76
79
77
80
def _read_bytes (self ):
78
81
pass
79
82
80
- with six . assertRaisesRegex ( self , TypeError , "Can't instantiate abstract class TestStream" ) :
83
+ with pytest . raises ( TypeError ) as excinfo :
81
84
TestStream ()
82
85
86
+ excinfo .match ("Can't instantiate abstract class TestStream" )
87
+
83
88
def test_config_class_enforcement (self ):
84
89
class TestStream (_EncryptionStream ):
85
90
def _read_bytes (self ):
@@ -88,29 +93,32 @@ def _read_bytes(self):
88
93
def _prep_message (self ):
89
94
pass
90
95
91
- with six . assertRaisesRegex ( self , TypeError , "Can't instantiate abstract class TestStream" ) :
96
+ with pytest . raises ( TypeError ) as excinfo :
92
97
TestStream ()
93
98
99
+ excinfo .match ("Can't instantiate abstract class TestStream" )
100
+
94
101
def test_new_with_params (self ):
102
+ mock_int_sentinel = MagicMock (__class__ = int )
95
103
mock_stream = MockEncryptionStream (
96
104
source = self .mock_source_stream ,
97
105
key_provider = self .mock_key_provider ,
98
106
mock_read_bytes = sentinel .read_bytes ,
99
- line_length = self . mock_line_length ,
100
- source_length = self . mock_source_length ,
107
+ line_length = io . DEFAULT_BUFFER_SIZE ,
108
+ source_length = mock_int_sentinel ,
101
109
)
102
110
assert mock_stream .config == MockClientConfig (
103
111
source = self .mock_source_stream ,
104
112
key_provider = self .mock_key_provider ,
105
113
mock_read_bytes = sentinel .read_bytes ,
106
- line_length = self . mock_line_length ,
107
- source_length = self . mock_source_length ,
114
+ line_length = io . DEFAULT_BUFFER_SIZE ,
115
+ source_length = mock_int_sentinel ,
108
116
)
109
117
assert mock_stream .bytes_read == 0
110
118
assert mock_stream .output_buffer == b""
111
119
assert not mock_stream ._message_prepped
112
120
assert mock_stream .source_stream is self .mock_source_stream
113
- assert mock_stream ._stream_length is self . mock_source_length
121
+ assert mock_stream ._stream_length is mock_int_sentinel
114
122
assert mock_stream .line_length == io .DEFAULT_BUFFER_SIZE
115
123
116
124
def test_new_with_config (self ):
@@ -154,7 +162,8 @@ class CustomUnknownError(Exception):
154
162
mock_stream = MockEncryptionStream (
155
163
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
156
164
)
157
- with self .assertRaises (CustomUnknownError ):
165
+
166
+ with pytest .raises (CustomUnknownError ):
158
167
mock_stream .__exit__ (None , None , None )
159
168
160
169
def test_stream_length (self ):
@@ -173,9 +182,12 @@ def test_stream_length_unsupported(self):
173
182
mock_stream = MockEncryptionStream (
174
183
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
175
184
)
176
- with six .assertRaisesRegex (self , aws_encryption_sdk .exceptions .NotSupportedError , "Unexpected exception!" ):
185
+
186
+ with pytest .raises (aws_encryption_sdk .exceptions .NotSupportedError ) as excinfo :
177
187
mock_stream .stream_length # pylint: disable=pointless-statement
178
188
189
+ excinfo .match ("Unexpected exception!" )
190
+
179
191
def test_header_property (self ):
180
192
mock_prep_message = MagicMock ()
181
193
mock_stream = MockEncryptionStream (
@@ -205,31 +217,37 @@ def test_read_closed(self):
205
217
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
206
218
)
207
219
mock_stream .close ()
208
- with six .assertRaisesRegex (self , ValueError , "I/O operation on closed file" ):
220
+
221
+ with pytest .raises (ValueError ) as excinfo :
209
222
mock_stream .read ()
210
223
211
- def test_read_b (self ):
224
+ excinfo .match ("I/O operation on closed file" )
225
+
226
+ @pytest .mark .parametrize ("bytes_to_read" , range (1 , 11 ))
227
+ def test_read_b (self , bytes_to_read ):
212
228
mock_stream = MockEncryptionStream (
213
229
source = io .BytesIO (VALUES ["data_128" ]),
214
230
key_provider = self .mock_key_provider ,
215
231
mock_read_bytes = sentinel .read_bytes ,
216
232
)
233
+ data = b"1234567890"
217
234
mock_stream ._read_bytes = MagicMock ()
218
- mock_stream .output_buffer = b"1234567890"
219
- test = mock_stream .read (5 )
220
- mock_stream ._read_bytes .assert_called_once_with (5 )
221
- assert test == b"12345"
222
- assert mock_stream .output_buffer == b"67890"
223
-
224
- def test_read_all (self ):
235
+ mock_stream .output_buffer = copy .copy (data )
236
+ test = mock_stream .read (bytes_to_read )
237
+ mock_stream ._read_bytes .assert_called_once_with (bytes_to_read )
238
+ assert test == data [:bytes_to_read ]
239
+ assert mock_stream .output_buffer == data [bytes_to_read :]
240
+
241
+ @pytest .mark .parametrize ("bytes_to_read" , (None , - 1 , - 99 ))
242
+ def test_read_all (self , bytes_to_read ):
225
243
mock_stream = MockEncryptionStream (
226
244
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
227
245
)
228
246
mock_stream ._stream_length = 5
229
247
mock_stream .output_buffer = b"1234567890"
230
248
mock_stream .source_stream = MagicMock ()
231
249
type(mock_stream .source_stream ).closed = PropertyMock (side_effect = (False , False , True ))
232
- test = mock_stream .read ()
250
+ test = mock_stream .read (bytes_to_read )
233
251
assert test == b"1234567890"
234
252
235
253
def test_read_all_empty_source (self ):
@@ -262,23 +280,32 @@ def test_writelines(self):
262
280
mock_stream = MockEncryptionStream (
263
281
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
264
282
)
265
- with six .assertRaisesRegex (self , NotImplementedError , "writelines is not available for this object" ):
283
+
284
+ with pytest .raises (NotImplementedError ) as excinfo :
266
285
mock_stream .writelines (None )
267
286
287
+ excinfo .match ("writelines is not available for this object" )
288
+
268
289
def test_write (self ):
269
290
mock_stream = MockEncryptionStream (
270
291
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
271
292
)
272
- with six .assertRaisesRegex (self , NotImplementedError , "write is not available for this object" ):
293
+
294
+ with pytest .raises (NotImplementedError ) as excinfo :
273
295
mock_stream .write (None )
274
296
297
+ excinfo .match ("write is not available for this object" )
298
+
275
299
def test_seek (self ):
276
300
mock_stream = MockEncryptionStream (
277
301
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
278
302
)
279
- with six .assertRaisesRegex (self , NotImplementedError , "seek is not available for this object" ):
303
+
304
+ with pytest .raises (NotImplementedError ) as excinfo :
280
305
mock_stream .seek (None )
281
306
307
+ excinfo .match ("seek is not available for this object" )
308
+
282
309
def test_readline (self ):
283
310
test_line = "TEST_LINE_AAAA"
284
311
test_line_length = len (test_line )
@@ -319,7 +346,8 @@ def test_next_stream_closed(self):
319
346
source = self .mock_source_stream , key_provider = self .mock_key_provider , mock_read_bytes = sentinel .read_bytes
320
347
)
321
348
mock_stream .close ()
322
- with self .assertRaises (StopIteration ):
349
+
350
+ with pytest .raises (StopIteration ):
323
351
mock_stream .next ()
324
352
325
353
def test_next_source_stream_closed_and_buffer_empty (self ):
@@ -328,7 +356,8 @@ def test_next_source_stream_closed_and_buffer_empty(self):
328
356
)
329
357
self .mock_source_stream .closed = True
330
358
mock_stream .output_buffer = b""
331
- with self .assertRaises (StopIteration ):
359
+
360
+ with pytest .raises (StopIteration ):
332
361
mock_stream .next ()
333
362
334
363
@patch ("aws_encryption_sdk.streaming_client._EncryptionStream.closed" , new_callable = PropertyMock )
0 commit comments