Issues (43)

starstruct/tests/test_elementnone.py (11 issues)

1
#!/usr/bin/env python3
2
3
"""Tests for the starstruct class"""
4
5
import struct
6
import unittest
7
from hashlib import md5
8
9
from starstruct.message import Message
10
11
12
class TestStarStructNone(unittest.TestCase):
13
    """StarStruct module tests"""
14
    # TODO: Clean up these tests, change names, and move a bunch of the items to a helper function
15
16
    VarTest = Message('VarTest', [
17
        ('x', 'B'),
18
        ('y', 'B'),
19
    ])
20
21
    def test_single_element_1(self):
22
        def pseudo_salted_md5(salt, original):
23
            temp_md5 = md5(original)
24
25
            if salt is None:
26
                salt = b''
27
28
            return md5(salt + temp_md5.digest()).digest()
29
30
        def pack_salt(data):
31
            return b''.join(item.to_bytes(1, 'little') for item in data)
32
33
        TestStruct = Message('TestStruct', [
34
            ('length_in_objects', 'H', 'vardata'),
35
            ('vardata', self.VarTest, 'length_in_objects'),
36
        ])
37
38
        CRCedMessage = Message('CRCedMessage', [
39
            ('data', TestStruct),
40
            ('salted', None),
41
            ('function_data', '16B', {
42
                'make': (pseudo_salted_md5, 'salted', b'data'),
43
                'pack': (pseudo_salted_md5, 'salted', b'data'),
44
                'unpack': (pack_salt, 'function_data'),
45
            }, False),
46
        ])
47
48
        test_data = {
49
            'data': {
50
                'length_in_objects': 2,
51
                'vardata': [
52
                    {'x': 1, 'y': 2},
53
                    {'x': 3, 'y': 4},
54
                ],
55
            },
56
            'salted': b'random_salter',
57
        }
58
59
        made = CRCedMessage.make(test_data)
60
        assert len(made.data.vardata) == 2
61
        assert made.data.vardata[0].x == 1
62
        assert made.data.vardata[0].y == 2
63
64
        no_data = made.pack()
65
        regular = CRCedMessage.pack(**test_data)
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
66
        assert regular == no_data
67
68
        # Show that there's no room to have the random salter be packed
69
        len_data = len(no_data) - 16
70
        assert no_data[0:len_data] == struct.pack('HBBBB', 2, 1, 2, 3, 4)
71
        assert md5(
72
            b'random_salter' +
73
            md5(no_data[0:len_data]).digest()
74
        ).digest() == no_data[len_data:]
75
76
        unpacked = CRCedMessage.unpack(no_data)
77
78
        assert unpacked.salted is None
79
        assert unpacked.function_data == made.function_data
80
81
        # TEMP
82
        new = unpacked._replace(**{'salted': b'random_salter'})
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
83
        assert new.salted == b'random_salter'
84
        # print(new._asdict())
85
86 View Code Duplication
    def test_single_element_2(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
87
        def pseudo_salted_md5(salt, original):
88
            temp_md5 = md5(original)
89
90
            if salt is None:
91
                salt = b''
92
93
            return md5(salt + temp_md5.digest()).digest()
94
95
        def do_nothing(data):
96
            return data
97
98
        TestStruct = Message('TestStruct', [
99
            ('length_in_objects', 'H', 'vardata'),
100
            ('vardata', self.VarTest, 'length_in_objects'),
101
        ])
102
103
        CRCedMessage = Message('CRCedMessage', [
104
            ('data', TestStruct),
105
            ('salted', None),
106
            ('function_data', '16B', {
107
                'make': (pseudo_salted_md5, 'salted', b'data'),
108
                'pack': (pseudo_salted_md5, 'salted', b'data'),
109
                'unpack': (do_nothing, 'function_data'),
110
            }, False),
111
        ])
112
113
        test_data = {
114
            'data': {
115
                'length_in_objects': 2,
116
                'vardata': [
117
                    {'x': 1, 'y': 2},
118
                    {'x': 3, 'y': 4},
119
                ],
120
            },
121
            'salted': b'random_salter',
122
        }
123
124
        made = CRCedMessage.make(test_data)
125
        assert len(made.data.vardata) == 2
126
        assert made.data.vardata[0].x == 1
127
        assert made.data.vardata[0].y == 2
128
129
        no_data = made.pack()
130
        regular = CRCedMessage.pack(**test_data)
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
131
        assert regular == no_data
132
133
        # Show that there's no room to have the random salter be packed
134
        len_data = len(no_data) - 16
135
        assert no_data[0:len_data] == struct.pack('HBBBB', 2, 1, 2, 3, 4)
136
        assert md5(
137
            b'random_salter' +
138
            md5(no_data[0:len_data]).digest()
139
        ).digest() == no_data[len_data:]
140
141
        unpacked = CRCedMessage.unpack(no_data)
142
143
        assert unpacked.salted is None
144
        # This is non symmetric for this test, so we can't just check based on the made item
145
        assert unpacked.function_data == (157, 38, 247, 245, 5, 71, 43, 227, 80, 44, 10, 243, 48, 248, 163, 207)
146
147
        # TEMP
148
        new = unpacked._replace(**{'salted': b'random_salter'})
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
149
        assert new.salted == b'random_salter'
150
        # print(new._asdict())
151
152 View Code Duplication
    def test_single_element_3(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
153
        def pseudo_salted_md5(salt, original):
154
            temp_md5 = md5(original)
155
156
            if salt is None:
157
                salt = b''
158
159
            return md5(salt + temp_md5.digest()).digest()
160
161
        def double(data):
162
            return [item * 2 for item in data]
163
164
        TestStruct = Message('TestStruct', [
165
            ('length_in_objects', 'H', 'vardata'),
166
            ('vardata', self.VarTest, 'length_in_objects'),
167
        ])
168
169
        CRCedMessage = Message('CRCedMessage', [
170
            ('data', TestStruct),
171
            ('salted', None),
172
            ('function_data', '16B', {
173
                'make': (pseudo_salted_md5, 'salted', b'data'),
174
                'pack': (pseudo_salted_md5, 'salted', b'data'),
175
                'unpack': (double, 'function_data'),
176
            }, False),
177
        ])
178
179
        test_data = {
180
            'data': {
181
                'length_in_objects': 2,
182
                'vardata': [
183
                    {'x': 1, 'y': 2},
184
                    {'x': 3, 'y': 4},
185
                ],
186
            },
187
            'salted': b'random_salter',
188
        }
189
190
        made = CRCedMessage.make(test_data)
191
        assert len(made.data.vardata) == 2
192
        assert made.data.vardata[0].x == 1
193
        assert made.data.vardata[0].y == 2
194
195
        no_data = made.pack()
196
        regular = CRCedMessage.pack(**test_data)
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
197
        assert regular == no_data
198
199
        # Show that there's no room to have the random salter be packed
200
        len_data = len(no_data) - 16
201
        assert no_data[0:len_data] == struct.pack('HBBBB', 2, 1, 2, 3, 4)
202
        assert md5(
203
            b'random_salter' +
204
            md5(no_data[0:len_data]).digest()
205
        ).digest() == no_data[len_data:]
206
207
        unpacked = CRCedMessage.unpack(no_data)
208
209
        assert unpacked.salted is None
210
        # This is non symmetric for this test, so we can't just check based on the made item
211
        assert unpacked.function_data == [314, 76, 494, 490, 10, 142, 86, 454, 160, 88, 20, 486, 96, 496, 326, 414]
212
213 View Code Duplication
    def test_single_element_4(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
214
        def pseudo_salted_md5(salt, original):
215
            temp_md5 = md5(original)
216
217
            if salt is None:
218
                salt = b''
219
220
            return md5(salt + temp_md5.digest()).digest()
221
222
        def double(data):
223
            return [item * 2 for item in data]
224
225
        TestStruct = Message('TestStruct', [
226
            ('length_in_objects', 'H', 'vardata'),
227
            ('vardata', self.VarTest, 'length_in_objects'),
228
        ])
229
230
        # This one has nothing to do with the original packed message
231
        CRCedMessage = Message('CRCedMessage', [
232
            ('data', TestStruct),
233
            ('salted', None),
234
            ('function_data', '16B', {
235
                'make': (pseudo_salted_md5, 'salted', b'data'),
236
                'pack': (pseudo_salted_md5, 'salted', b'data'),
237
                'unpack': (double, b'data'),
238
            }, False),
239
        ])
240
241
        test_data = {
242
            'data': {
243
                'length_in_objects': 2,
244
                'vardata': [
245
                    {'x': 1, 'y': 2},
246
                    {'x': 3, 'y': 4},
247
                ],
248
            },
249
            'salted': b'random_salter',
250
        }
251
252
        made = CRCedMessage.make(test_data)
253
        assert len(made.data.vardata) == 2
254
        assert made.data.vardata[0].x == 1
255
        assert made.data.vardata[0].y == 2
256
257
        no_data = made.pack()
258
        regular = CRCedMessage.pack(**test_data)
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
259
        assert regular == no_data
260
261
        # Show that there's no room to have the random salter be packed
262
        len_data = len(no_data) - 16
263
        assert no_data[0:len_data] == struct.pack('HBBBB', 2, 1, 2, 3, 4)
264
        assert md5(
265
            b'random_salter' +
266
            md5(no_data[0:len_data]).digest()
267
        ).digest() == no_data[len_data:]
268
269
        unpacked = CRCedMessage.unpack(no_data)
270
271
        assert unpacked.salted is None
272
        # This is non symmetric for this test, so we can't just check based on the made item
273
        assert unpacked.function_data == [4, 0, 2, 4, 6, 8]
274
275
    def test_nounpack_function(self):
276
        def pseudo_salted_md5(salt, original):
277
            temp_md5 = md5(original)
278
279
            if salt is None:
280
                salt = b''
281
282
            return md5(salt + temp_md5.digest()).digest()
283
284
        TestStruct = Message('TestStruct', [
285
            ('length_in_objects', 'H', 'vardata'),
286
            ('vardata', self.VarTest, 'length_in_objects'),
287
        ])
288
289
        # This one has nothing to do with the original packed message
290
        ExplicitNone = Message('Explicit', [
291
            ('data', TestStruct),
292
            ('salted', None),
293
            ('function_data', '16B', {
294
                'make': (pseudo_salted_md5, 'salted', b'data'),
295
                'pack': (pseudo_salted_md5, 'salted', b'data'),
296
                'unpack': (None, ),
297
            }, False),
298
        ])
299
300
        ImplicitNone = Message('Implicit', [
301
            ('data', TestStruct),
302
            ('salted', None),
303
            ('function_data', '16B', {
304
                'make': (pseudo_salted_md5, 'salted', b'data'),
305
                'pack': (pseudo_salted_md5, 'salted', b'data'),
306
            }, False),
307
        ])
308
309
        test_data = {
310
            'data': {
311
                'length_in_objects': 2,
312
                'vardata': [
313
                    {'x': 1, 'y': 2},
314
                    {'x': 3, 'y': 4},
315
                ],
316
            },
317
            'salted': b'random_salter',
318
        }
319
320
        made = ExplicitNone.make(test_data)
321
        assert len(made.data.vardata) == 2
322
        assert made.data.vardata[0].x == 1
323
        assert made.data.vardata[0].y == 2
324
325
        no_data = made.pack()
326
        regular = ExplicitNone.pack(**test_data)
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
327
        assert regular == no_data
328
329
        # Show that there's no room to have the random salter be packed
330
        len_data = len(no_data) - 16
331
        assert no_data[0:len_data] == struct.pack('HBBBB', 2, 1, 2, 3, 4)
332
        assert md5(
333
            b'random_salter' +
334
            md5(no_data[0:len_data]).digest()
335
        ).digest() == no_data[len_data:]
336
337
        unpacked = ExplicitNone.unpack(no_data)
338
339
        assert unpacked.salted is None
340
        assert unpacked.function_data == (157, 38, 247, 245, 5, 71, 43, 227, 80, 44, 10, 243, 48, 248, 163, 207)
341
342
        made = ImplicitNone.make(test_data)
343
        assert len(made.data.vardata) == 2
344
        assert made.data.vardata[0].x == 1
345
        assert made.data.vardata[0].y == 2
346
347
        no_data = made.pack()
348
        regular = ImplicitNone.pack(**test_data)
0 ignored issues
show
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
349
        assert regular == no_data
350
351
        # Show that there's no room to have the random salter be packed
352
        len_data = len(no_data) - 16
353
        assert no_data[0:len_data] == struct.pack('HBBBB', 2, 1, 2, 3, 4)
354
        assert md5(
355
            b'random_salter' +
356
            md5(no_data[0:len_data]).digest()
357
        ).digest() == no_data[len_data:]
358
359
        unpacked = ImplicitNone.unpack(no_data)
360
361
        assert unpacked.salted is None
362
        assert unpacked.function_data == (157, 38, 247, 245, 5, 71, 43, 227, 80, 44, 10, 243, 48, 248, 163, 207)
363