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