xref: /aosp_15_r20/external/openthread/tests/scripts/thread-cert/test_network_layer.py (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1#!/usr/bin/env python3
2#
3#  Copyright (c) 2016, The OpenThread Authors.
4#  All rights reserved.
5#
6#  Redistribution and use in source and binary forms, with or without
7#  modification, are permitted provided that the following conditions are met:
8#  1. Redistributions of source code must retain the above copyright
9#     notice, this list of conditions and the following disclaimer.
10#  2. Redistributions in binary form must reproduce the above copyright
11#     notice, this list of conditions and the following disclaimer in the
12#     documentation and/or other materials provided with the distribution.
13#  3. Neither the name of the copyright holder nor the
14#     names of its contributors may be used to endorse or promote products
15#     derived from this software without specific prior written permission.
16#
17#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27#  POSSIBILITY OF SUCH DAMAGE.
28#
29
30import io
31import random
32import struct
33import unittest
34
35import common
36import network_layer
37
38
39def any_eid():
40    return bytearray([random.getrandbits(8) for _ in range(16)])
41
42
43def any_mac_extended_address():
44    return bytearray([random.getrandbits(8) for _ in range(8)])
45
46
47def any_rloc16():
48    return random.getrandbits(16)
49
50
51def any_ml_eid():
52    return bytearray([random.getrandbits(8) for _ in range(8)])
53
54
55def any_status():
56    return random.getrandbits(1)
57
58
59def any_seconds():
60    return random.getrandbits(32)
61
62
63def any_id_sequence():
64    return random.getrandbits(8)
65
66
67def any_router_id_mask():
68    return random.getrandbits(64)
69
70
71def any_options(count=None):
72    count = count if count is not None else random.randint(0, 255)
73    return [random.getrandbits(8) for _ in range(count)]
74
75
76def any_tlv_data(length=None):
77    _type = random.getrandbits(8)
78    length = length if length is not None else random.getrandbits(8)
79    value = bytearray([random.getrandbits(8) for _ in range(length)])
80
81    return bytearray([_type, length]) + value
82
83
84def any_tlvs_data(count=None):
85    count = count if count is not None else random.randint(0, 16)
86    data = bytearray()
87
88    for _ in range(count):
89        data += any_tlv_data(random.randint(1, 15))
90
91    return data
92
93
94class TestTargetEid(unittest.TestCase):
95
96    def test_should_return_eid_value_when_eid_property_is_called(self):
97        # GIVEN
98        eid = any_eid()
99
100        target_eid = network_layer.TargetEid(eid)
101
102        # WHEN
103        actual_eid = target_eid.eid
104
105        # THEN
106        self.assertEqual(eid, actual_eid)
107
108    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
109        # GIVEN
110        eid = any_eid()
111
112        target_eid = network_layer.TargetEid(eid)
113
114        # THEN
115        self.assertEqual(target_eid, network_layer.TargetEid(eid))
116
117
118class TestTargetEidFactory(unittest.TestCase):
119
120    def test_should_create_TargetEid_from_bytearray_when_parse_method_is_called(self):
121        # GIVEN
122        eid = any_eid()
123
124        factory = network_layer.TargetEidFactory()
125
126        # WHEN
127        target_eid = factory.parse(io.BytesIO(eid), common.MessageInfo())
128
129        # THEN
130        self.assertTrue(isinstance(target_eid, network_layer.TargetEid))
131        self.assertEqual(eid, target_eid.eid)
132
133
134class TestMacExtendedAddress(unittest.TestCase):
135
136    def test_should_return_mac_address_value_when_mac_address_property_is_called(self):
137        # GIVEN
138        mac_address = any_mac_extended_address()
139
140        mac_extended_address = network_layer.MacExtendedAddress(mac_address)
141
142        # WHEN
143        actual_mac_address = mac_extended_address.mac_address
144
145        # THEN
146        self.assertEqual(mac_address, actual_mac_address)
147
148    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
149        # GIVEN
150        mac_address = any_mac_extended_address()
151
152        mac_extended_address = network_layer.MacExtendedAddress(mac_address)
153
154        # THEN
155        self.assertEqual(mac_extended_address, network_layer.MacExtendedAddress(mac_address))
156
157
158class TestMacExtendedAddressFactory(unittest.TestCase):
159
160    def test_should_create_MacExtendedAddress_from_bytearray_when_parse_method_is_called(self):
161        # GIVEN
162        mac_address = any_mac_extended_address()
163
164        factory = network_layer.MacExtendedAddressFactory()
165
166        # WHEN
167        mac_extended_address = factory.parse(io.BytesIO(mac_address), common.MessageInfo())
168
169        # THEN
170        self.assertTrue(isinstance(mac_extended_address, network_layer.MacExtendedAddress))
171        self.assertEqual(mac_address, mac_extended_address.mac_address)
172
173
174class TestRloc16(unittest.TestCase):
175
176    def test_should_return_rloc16_value_when_rloc16_property_is_called(self):
177        # GIVEN
178        rloc16 = any_rloc16()
179
180        rloc16_obj = network_layer.Rloc16(rloc16)
181
182        # WHEN
183        actual_rloc16 = rloc16_obj.rloc16
184
185        # THEN
186        self.assertEqual(rloc16, actual_rloc16)
187
188    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
189        # GIVEN
190        rloc16 = any_rloc16()
191
192        rloc16_obj = network_layer.Rloc16(rloc16)
193
194        # THEN
195        self.assertEqual(rloc16_obj, network_layer.Rloc16(rloc16))
196
197
198class TestRloc16Factory(unittest.TestCase):
199
200    def test_should_create_Rloc16_from_bytearray_when_parse_method_is_called(self):
201        # GIVEN
202        rloc16 = any_rloc16()
203
204        factory = network_layer.Rloc16Factory()
205
206        data = bytearray(struct.pack(">H", rloc16))
207
208        # WHEN
209        rloc16_obj = factory.parse(io.BytesIO(data), common.MessageInfo())
210
211        # THEN
212        self.assertTrue(isinstance(rloc16_obj, network_layer.Rloc16))
213        self.assertEqual(rloc16, rloc16_obj.rloc16)
214
215
216class TestMlEid(unittest.TestCase):
217
218    def test_should_return_ml_eid_value_when_ml_eid_property_is_called(self):
219        # GIVEN
220        ml_eid = any_ml_eid()
221
222        ml_eid_obj = network_layer.MlEid(ml_eid)
223
224        # WHEN
225        actual_ml_eid = ml_eid_obj.ml_eid
226
227        # THEN
228        self.assertEqual(ml_eid, actual_ml_eid)
229
230    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
231        # GIVEN
232        ml_eid = any_ml_eid()
233
234        ml_eid_obj = network_layer.MlEid(ml_eid)
235
236        # THEN
237        self.assertEqual(ml_eid_obj, network_layer.MlEid(ml_eid))
238
239
240class TestMlEidFactory(unittest.TestCase):
241
242    def test_should_create_MlEid_from_bytearray_when_parse_method_is_called(self):
243        # GIVEN
244        ml_eid = any_ml_eid()
245
246        factory = network_layer.MlEidFactory()
247
248        # WHEN
249        ml_eid_obj = factory.parse(io.BytesIO(ml_eid), common.MessageInfo())
250
251        # THEN
252        self.assertTrue(isinstance(ml_eid_obj, network_layer.MlEid))
253        self.assertEqual(ml_eid, ml_eid_obj.ml_eid)
254
255
256class TestStatus(unittest.TestCase):
257
258    def test_should_return_status_value_when_status_property_is_called(self):
259        # GIVEN
260        status = any_status()
261
262        status_obj = network_layer.Status(status)
263
264        # WHEN
265        actual_status = status_obj.status
266
267        # THEN
268        self.assertEqual(status, actual_status)
269
270    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
271        # GIVEN
272        status = any_status()
273
274        status_obj = network_layer.Status(status)
275
276        # THEN
277        self.assertEqual(status_obj, network_layer.Status(status))
278
279
280class TestStatusFactory(unittest.TestCase):
281
282    def test_should_create_Status_from_bytearray_when_parse_method_is_called(self):
283        # GIVEN
284        status = any_status()
285
286        factory = network_layer.StatusFactory()
287
288        data = bytearray([status])
289
290        # WHEN
291        status_obj = factory.parse(io.BytesIO(data), common.MessageInfo())
292
293        # THEN
294        self.assertTrue(isinstance(status_obj, network_layer.Status))
295        self.assertEqual(status, status_obj.status)
296
297
298class TestTimeSinceLastTransaction(unittest.TestCase):
299
300    def test_should_return_seconds_value_when_seconds_property_is_called(self):
301        # GIVEN
302        seconds = any_seconds()
303
304        time_since_last_transaction = network_layer.TimeSinceLastTransaction(seconds)
305
306        # WHEN
307        actual_seconds = time_since_last_transaction.seconds
308
309        # THEN
310        self.assertEqual(seconds, actual_seconds)
311
312    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
313        # GIVEN
314        seconds = any_seconds()
315
316        time_since_last_transaction = network_layer.TimeSinceLastTransaction(seconds)
317
318        # THEN
319        self.assertEqual(
320            time_since_last_transaction,
321            network_layer.TimeSinceLastTransaction(seconds),
322        )
323
324
325class TestTimeSinceLastTransactionFactory(unittest.TestCase):
326
327    def test_should_create_TimeSinceLastTransaction_from_bytearray_when_parse_method_is_called(self):
328        # GIVEN
329        seconds = any_seconds()
330
331        factory = network_layer.TimeSinceLastTransactionFactory()
332
333        data = bytearray(struct.pack(">L", seconds))
334
335        # WHEN
336        time_since_last_transaction = factory.parse(io.BytesIO(data), common.MessageInfo())
337
338        # THEN
339        self.assertTrue(isinstance(
340            time_since_last_transaction,
341            network_layer.TimeSinceLastTransaction,
342        ))
343        self.assertEqual(seconds, time_since_last_transaction.seconds)
344
345
346class TestRouterMask(unittest.TestCase):
347
348    def test_should_return_id_sequence_value_when_id_sequence_property_is_called(self):
349        # GIVEN
350        id_sequence = any_id_sequence()
351
352        router_mask = network_layer.RouterMask(id_sequence, any_router_id_mask())
353
354        # WHEN
355        actual_id_sequence = router_mask.id_sequence
356
357        # THEN
358        self.assertEqual(id_sequence, actual_id_sequence)
359
360    def test_should_return_router_id_mask_value_when_router_id_mask_property_is_called(self):
361        # GIVEN
362        router_id_mask = any_router_id_mask()
363
364        router_mask = network_layer.RouterMask(any_id_sequence(), router_id_mask)
365
366        # WHEN
367        actual_router_id_mask = router_mask.router_id_mask
368
369        # THEN
370        self.assertEqual(router_id_mask, actual_router_id_mask)
371
372    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
373        # GIVEN
374        id_sequence = any_id_sequence()
375        router_id_mask = any_router_id_mask()
376
377        router_mask = network_layer.RouterMask(id_sequence, router_id_mask)
378
379        # THEN
380        self.assertEqual(router_mask, network_layer.RouterMask(id_sequence, router_id_mask))
381
382
383class TestRouterMaskFactory(unittest.TestCase):
384
385    def test_should_create_RouterMask_from_bytearray_when_parse_method_is_called(self):
386        # GIVEN
387        id_sequence = any_id_sequence()
388        router_id_mask = any_router_id_mask()
389
390        factory = network_layer.RouterMaskFactory()
391
392        data = bytearray([id_sequence]) + struct.pack(">Q", router_id_mask)
393
394        # WHEN
395        router_mask = factory.parse(io.BytesIO(data), common.MessageInfo())
396
397        # THEN
398        self.assertTrue(isinstance(router_mask, network_layer.RouterMask))
399        self.assertEqual(id_sequence, router_mask.id_sequence)
400        self.assertEqual(router_id_mask, router_mask.router_id_mask)
401
402
403class TestNdOption(unittest.TestCase):
404
405    def test_should_return_options_value_when_options_property_is_called(self):
406        # GIVEN
407        options = any_options()
408
409        nd_option = network_layer.NdOption(options)
410
411        # WHEN
412        actual_options = nd_option.options
413
414        # THEN
415        self.assertEqual(options, actual_options)
416
417    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
418        # GIVEN
419        options = any_options()
420
421        nd_option = network_layer.NdOption(options)
422
423        # THEN
424        self.assertEqual(nd_option, network_layer.NdOption(options))
425
426
427class TestNdOptionFactory(unittest.TestCase):
428
429    def test_should_create_NdOption_from_bytearray_when_parse_method_is_called(self):
430        # GIVEN
431        options = any_options()
432
433        factory = network_layer.NdOptionFactory()
434
435        data = bytearray(options)
436
437        # WHEN
438        nd_option = factory.parse(io.BytesIO(data), common.MessageInfo())
439
440        # THEN
441        self.assertTrue(isinstance(nd_option, network_layer.NdOption))
442        self.assertEqual(options, nd_option.options)
443
444
445class TestThreadNetworkData(unittest.TestCase):
446
447    def test_should_return_options_value_when_options_property_is_called(self):
448        # GIVEN
449        tlvs = any_tlvs_data()
450
451        thread_network_data = network_layer.ThreadNetworkData(tlvs)
452
453        # WHEN
454        actual_tlvs = thread_network_data.tlvs
455
456        # THEN
457        self.assertEqual(tlvs, actual_tlvs)
458
459    def test_should_return_True_when_try_to_equal_two_the_same_type_objects_with_the_same_values(self):
460        # GIVEN
461        tlvs = any_tlvs_data()
462
463        thread_network_data = network_layer.ThreadNetworkData(tlvs)
464
465        # THEN
466        self.assertEqual(thread_network_data, network_layer.ThreadNetworkData(tlvs))
467
468
469class TestThreadNetworkDataFactory(unittest.TestCase):
470
471    def test_should_create_ThreadNetworkData_from_bytearray_when_parse_method_is_called(self):
472        # GIVEN
473        tlvs = any_tlvs_data()
474
475        class DummyNetworkDataTlvsFactory:
476
477            def parse(self, data, message_info):
478                return bytearray(data.read())
479
480        factory = network_layer.ThreadNetworkDataFactory(DummyNetworkDataTlvsFactory())
481
482        # WHEN
483        thread_network_data = factory.parse(io.BytesIO(tlvs), common.MessageInfo())
484
485        # THEN
486        self.assertTrue(isinstance(thread_network_data, network_layer.ThreadNetworkData))
487        self.assertEqual(tlvs, thread_network_data.tlvs)
488
489
490if __name__ == "__main__":
491    unittest.main()
492