1import unittest 2from test import support 3from test.support import import_helper 4import builtins 5import contextlib 6import copy 7import enum 8import io 9import os 10import pickle 11import sys 12import weakref 13from unittest import mock 14 15py_uuid = import_helper.import_fresh_module('uuid', blocked=['_uuid']) 16c_uuid = import_helper.import_fresh_module('uuid', fresh=['_uuid']) 17 18def importable(name): 19 try: 20 __import__(name) 21 return True 22 except: 23 return False 24 25 26def mock_get_command_stdout(data): 27 def get_command_stdout(command, args): 28 return io.BytesIO(data.encode()) 29 return get_command_stdout 30 31 32class BaseTestUUID: 33 uuid = None 34 35 def test_safe_uuid_enum(self): 36 class CheckedSafeUUID(enum.Enum): 37 safe = 0 38 unsafe = -1 39 unknown = None 40 enum._test_simple_enum(CheckedSafeUUID, py_uuid.SafeUUID) 41 42 def test_UUID(self): 43 equal = self.assertEqual 44 ascending = [] 45 for (string, curly, hex, bytes, bytes_le, fields, integer, urn, 46 time, clock_seq, variant, version) in [ 47 ('00000000-0000-0000-0000-000000000000', 48 '{00000000-0000-0000-0000-000000000000}', 49 '00000000000000000000000000000000', 50 b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', 51 b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', 52 (0, 0, 0, 0, 0, 0), 53 0, 54 'urn:uuid:00000000-0000-0000-0000-000000000000', 55 0, 0, self.uuid.RESERVED_NCS, None), 56 ('00010203-0405-0607-0809-0a0b0c0d0e0f', 57 '{00010203-0405-0607-0809-0a0b0c0d0e0f}', 58 '000102030405060708090a0b0c0d0e0f', 59 b'\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\x0d\x0e\x0f', 60 b'\x03\x02\x01\0\x05\x04\x07\x06\x08\t\n\x0b\x0c\x0d\x0e\x0f', 61 (0x00010203, 0x0405, 0x0607, 8, 9, 0x0a0b0c0d0e0f), 62 0x000102030405060708090a0b0c0d0e0f, 63 'urn:uuid:00010203-0405-0607-0809-0a0b0c0d0e0f', 64 0x607040500010203, 0x809, self.uuid.RESERVED_NCS, None), 65 ('02d9e6d5-9467-382e-8f9b-9300a64ac3cd', 66 '{02d9e6d5-9467-382e-8f9b-9300a64ac3cd}', 67 '02d9e6d59467382e8f9b9300a64ac3cd', 68 b'\x02\xd9\xe6\xd5\x94\x67\x38\x2e\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd', 69 b'\xd5\xe6\xd9\x02\x67\x94\x2e\x38\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd', 70 (0x02d9e6d5, 0x9467, 0x382e, 0x8f, 0x9b, 0x9300a64ac3cd), 71 0x02d9e6d59467382e8f9b9300a64ac3cd, 72 'urn:uuid:02d9e6d5-9467-382e-8f9b-9300a64ac3cd', 73 0x82e946702d9e6d5, 0xf9b, self.uuid.RFC_4122, 3), 74 ('12345678-1234-5678-1234-567812345678', 75 '{12345678-1234-5678-1234-567812345678}', 76 '12345678123456781234567812345678', 77 b'\x12\x34\x56\x78'*4, 78 b'\x78\x56\x34\x12\x34\x12\x78\x56\x12\x34\x56\x78\x12\x34\x56\x78', 79 (0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678), 80 0x12345678123456781234567812345678, 81 'urn:uuid:12345678-1234-5678-1234-567812345678', 82 0x678123412345678, 0x1234, self.uuid.RESERVED_NCS, None), 83 ('6ba7b810-9dad-11d1-80b4-00c04fd430c8', 84 '{6ba7b810-9dad-11d1-80b4-00c04fd430c8}', 85 '6ba7b8109dad11d180b400c04fd430c8', 86 b'\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 87 b'\x10\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 88 (0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8), 89 0x6ba7b8109dad11d180b400c04fd430c8, 90 'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8', 91 0x1d19dad6ba7b810, 0xb4, self.uuid.RFC_4122, 1), 92 ('6ba7b811-9dad-11d1-80b4-00c04fd430c8', 93 '{6ba7b811-9dad-11d1-80b4-00c04fd430c8}', 94 '6ba7b8119dad11d180b400c04fd430c8', 95 b'\x6b\xa7\xb8\x11\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 96 b'\x11\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 97 (0x6ba7b811, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8), 98 0x6ba7b8119dad11d180b400c04fd430c8, 99 'urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8', 100 0x1d19dad6ba7b811, 0xb4, self.uuid.RFC_4122, 1), 101 ('6ba7b812-9dad-11d1-80b4-00c04fd430c8', 102 '{6ba7b812-9dad-11d1-80b4-00c04fd430c8}', 103 '6ba7b8129dad11d180b400c04fd430c8', 104 b'\x6b\xa7\xb8\x12\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 105 b'\x12\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 106 (0x6ba7b812, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8), 107 0x6ba7b8129dad11d180b400c04fd430c8, 108 'urn:uuid:6ba7b812-9dad-11d1-80b4-00c04fd430c8', 109 0x1d19dad6ba7b812, 0xb4, self.uuid.RFC_4122, 1), 110 ('6ba7b814-9dad-11d1-80b4-00c04fd430c8', 111 '{6ba7b814-9dad-11d1-80b4-00c04fd430c8}', 112 '6ba7b8149dad11d180b400c04fd430c8', 113 b'\x6b\xa7\xb8\x14\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 114 b'\x14\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', 115 (0x6ba7b814, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8), 116 0x6ba7b8149dad11d180b400c04fd430c8, 117 'urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8', 118 0x1d19dad6ba7b814, 0xb4, self.uuid.RFC_4122, 1), 119 ('7d444840-9dc0-11d1-b245-5ffdce74fad2', 120 '{7d444840-9dc0-11d1-b245-5ffdce74fad2}', 121 '7d4448409dc011d1b2455ffdce74fad2', 122 b'\x7d\x44\x48\x40\x9d\xc0\x11\xd1\xb2\x45\x5f\xfd\xce\x74\xfa\xd2', 123 b'\x40\x48\x44\x7d\xc0\x9d\xd1\x11\xb2\x45\x5f\xfd\xce\x74\xfa\xd2', 124 (0x7d444840, 0x9dc0, 0x11d1, 0xb2, 0x45, 0x5ffdce74fad2), 125 0x7d4448409dc011d1b2455ffdce74fad2, 126 'urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2', 127 0x1d19dc07d444840, 0x3245, self.uuid.RFC_4122, 1), 128 ('e902893a-9d22-3c7e-a7b8-d6e313b71d9f', 129 '{e902893a-9d22-3c7e-a7b8-d6e313b71d9f}', 130 'e902893a9d223c7ea7b8d6e313b71d9f', 131 b'\xe9\x02\x89\x3a\x9d\x22\x3c\x7e\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f', 132 b'\x3a\x89\x02\xe9\x22\x9d\x7e\x3c\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f', 133 (0xe902893a, 0x9d22, 0x3c7e, 0xa7, 0xb8, 0xd6e313b71d9f), 134 0xe902893a9d223c7ea7b8d6e313b71d9f, 135 'urn:uuid:e902893a-9d22-3c7e-a7b8-d6e313b71d9f', 136 0xc7e9d22e902893a, 0x27b8, self.uuid.RFC_4122, 3), 137 ('eb424026-6f54-4ef8-a4d0-bb658a1fc6cf', 138 '{eb424026-6f54-4ef8-a4d0-bb658a1fc6cf}', 139 'eb4240266f544ef8a4d0bb658a1fc6cf', 140 b'\xeb\x42\x40\x26\x6f\x54\x4e\xf8\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf', 141 b'\x26\x40\x42\xeb\x54\x6f\xf8\x4e\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf', 142 (0xeb424026, 0x6f54, 0x4ef8, 0xa4, 0xd0, 0xbb658a1fc6cf), 143 0xeb4240266f544ef8a4d0bb658a1fc6cf, 144 'urn:uuid:eb424026-6f54-4ef8-a4d0-bb658a1fc6cf', 145 0xef86f54eb424026, 0x24d0, self.uuid.RFC_4122, 4), 146 ('f81d4fae-7dec-11d0-a765-00a0c91e6bf6', 147 '{f81d4fae-7dec-11d0-a765-00a0c91e6bf6}', 148 'f81d4fae7dec11d0a76500a0c91e6bf6', 149 b'\xf8\x1d\x4f\xae\x7d\xec\x11\xd0\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6', 150 b'\xae\x4f\x1d\xf8\xec\x7d\xd0\x11\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6', 151 (0xf81d4fae, 0x7dec, 0x11d0, 0xa7, 0x65, 0x00a0c91e6bf6), 152 0xf81d4fae7dec11d0a76500a0c91e6bf6, 153 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6', 154 0x1d07decf81d4fae, 0x2765, self.uuid.RFC_4122, 1), 155 ('fffefdfc-fffe-fffe-fffe-fffefdfcfbfa', 156 '{fffefdfc-fffe-fffe-fffe-fffefdfcfbfa}', 157 'fffefdfcfffefffefffefffefdfcfbfa', 158 b'\xff\xfe\xfd\xfc\xff\xfe\xff\xfe\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa', 159 b'\xfc\xfd\xfe\xff\xfe\xff\xfe\xff\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa', 160 (0xfffefdfc, 0xfffe, 0xfffe, 0xff, 0xfe, 0xfffefdfcfbfa), 161 0xfffefdfcfffefffefffefffefdfcfbfa, 162 'urn:uuid:fffefdfc-fffe-fffe-fffe-fffefdfcfbfa', 163 0xffefffefffefdfc, 0x3ffe, self.uuid.RESERVED_FUTURE, None), 164 ('ffffffff-ffff-ffff-ffff-ffffffffffff', 165 '{ffffffff-ffff-ffff-ffff-ffffffffffff}', 166 'ffffffffffffffffffffffffffffffff', 167 b'\xff'*16, 168 b'\xff'*16, 169 (0xffffffff, 0xffff, 0xffff, 0xff, 0xff, 0xffffffffffff), 170 0xffffffffffffffffffffffffffffffff, 171 'urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff', 172 0xfffffffffffffff, 0x3fff, self.uuid.RESERVED_FUTURE, None), 173 ]: 174 equivalents = [] 175 # Construct each UUID in several different ways. 176 for u in [self.uuid.UUID(string), self.uuid.UUID(curly), self.uuid.UUID(hex), 177 self.uuid.UUID(bytes=bytes), self.uuid.UUID(bytes_le=bytes_le), 178 self.uuid.UUID(fields=fields), self.uuid.UUID(int=integer), 179 self.uuid.UUID(urn)]: 180 # Test all conversions and properties of the UUID object. 181 equal(str(u), string) 182 equal(int(u), integer) 183 equal(u.bytes, bytes) 184 equal(u.bytes_le, bytes_le) 185 equal(u.fields, fields) 186 equal(u.time_low, fields[0]) 187 equal(u.time_mid, fields[1]) 188 equal(u.time_hi_version, fields[2]) 189 equal(u.clock_seq_hi_variant, fields[3]) 190 equal(u.clock_seq_low, fields[4]) 191 equal(u.node, fields[5]) 192 equal(u.hex, hex) 193 equal(u.int, integer) 194 equal(u.urn, urn) 195 equal(u.time, time) 196 equal(u.clock_seq, clock_seq) 197 equal(u.variant, variant) 198 equal(u.version, version) 199 equivalents.append(u) 200 201 # Different construction methods should give the same UUID. 202 for u in equivalents: 203 for v in equivalents: 204 equal(u, v) 205 206 # Bug 7380: "bytes" and "bytes_le" should give the same type. 207 equal(type(u.bytes), builtins.bytes) 208 equal(type(u.bytes_le), builtins.bytes) 209 210 ascending.append(u) 211 212 # Test comparison of UUIDs. 213 for i in range(len(ascending)): 214 for j in range(len(ascending)): 215 equal(i < j, ascending[i] < ascending[j]) 216 equal(i <= j, ascending[i] <= ascending[j]) 217 equal(i == j, ascending[i] == ascending[j]) 218 equal(i > j, ascending[i] > ascending[j]) 219 equal(i >= j, ascending[i] >= ascending[j]) 220 equal(i != j, ascending[i] != ascending[j]) 221 222 # Test sorting of UUIDs (above list is in ascending order). 223 resorted = ascending[:] 224 resorted.reverse() 225 resorted.sort() 226 equal(ascending, resorted) 227 228 def test_exceptions(self): 229 badvalue = lambda f: self.assertRaises(ValueError, f) 230 badtype = lambda f: self.assertRaises(TypeError, f) 231 232 # Badly formed hex strings. 233 badvalue(lambda: self.uuid.UUID('')) 234 badvalue(lambda: self.uuid.UUID('abc')) 235 badvalue(lambda: self.uuid.UUID('1234567812345678123456781234567')) 236 badvalue(lambda: self.uuid.UUID('123456781234567812345678123456789')) 237 badvalue(lambda: self.uuid.UUID('123456781234567812345678z2345678')) 238 239 # Badly formed bytes. 240 badvalue(lambda: self.uuid.UUID(bytes='abc')) 241 badvalue(lambda: self.uuid.UUID(bytes='\0'*15)) 242 badvalue(lambda: self.uuid.UUID(bytes='\0'*17)) 243 244 # Badly formed bytes_le. 245 badvalue(lambda: self.uuid.UUID(bytes_le='abc')) 246 badvalue(lambda: self.uuid.UUID(bytes_le='\0'*15)) 247 badvalue(lambda: self.uuid.UUID(bytes_le='\0'*17)) 248 249 # Badly formed fields. 250 badvalue(lambda: self.uuid.UUID(fields=(1,))) 251 badvalue(lambda: self.uuid.UUID(fields=(1, 2, 3, 4, 5))) 252 badvalue(lambda: self.uuid.UUID(fields=(1, 2, 3, 4, 5, 6, 7))) 253 254 # Field values out of range. 255 badvalue(lambda: self.uuid.UUID(fields=(-1, 0, 0, 0, 0, 0))) 256 badvalue(lambda: self.uuid.UUID(fields=(0x100000000, 0, 0, 0, 0, 0))) 257 badvalue(lambda: self.uuid.UUID(fields=(0, -1, 0, 0, 0, 0))) 258 badvalue(lambda: self.uuid.UUID(fields=(0, 0x10000, 0, 0, 0, 0))) 259 badvalue(lambda: self.uuid.UUID(fields=(0, 0, -1, 0, 0, 0))) 260 badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0x10000, 0, 0, 0))) 261 badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, -1, 0, 0))) 262 badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0x100, 0, 0))) 263 badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, -1, 0))) 264 badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, 0x100, 0))) 265 badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, 0, -1))) 266 badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, 0, 0x1000000000000))) 267 268 # Version number out of range. 269 badvalue(lambda: self.uuid.UUID('00'*16, version=0)) 270 badvalue(lambda: self.uuid.UUID('00'*16, version=6)) 271 272 # Integer value out of range. 273 badvalue(lambda: self.uuid.UUID(int=-1)) 274 badvalue(lambda: self.uuid.UUID(int=1<<128)) 275 276 # Must supply exactly one of hex, bytes, fields, int. 277 h, b, f, i = '00'*16, b'\0'*16, (0, 0, 0, 0, 0, 0), 0 278 self.uuid.UUID(h) 279 self.uuid.UUID(hex=h) 280 self.uuid.UUID(bytes=b) 281 self.uuid.UUID(bytes_le=b) 282 self.uuid.UUID(fields=f) 283 self.uuid.UUID(int=i) 284 285 # Wrong number of arguments (positional). 286 badtype(lambda: self.uuid.UUID()) 287 badtype(lambda: self.uuid.UUID(h, b)) 288 badtype(lambda: self.uuid.UUID(h, b, b)) 289 badtype(lambda: self.uuid.UUID(h, b, b, f)) 290 badtype(lambda: self.uuid.UUID(h, b, b, f, i)) 291 292 # Duplicate arguments. 293 for hh in [[], [('hex', h)]]: 294 for bb in [[], [('bytes', b)]]: 295 for bble in [[], [('bytes_le', b)]]: 296 for ii in [[], [('int', i)]]: 297 for ff in [[], [('fields', f)]]: 298 args = dict(hh + bb + bble + ii + ff) 299 if len(args) != 0: 300 badtype(lambda: self.uuid.UUID(h, **args)) 301 if len(args) != 1: 302 badtype(lambda: self.uuid.UUID(**args)) 303 304 # Immutability. 305 u = self.uuid.UUID(h) 306 badtype(lambda: setattr(u, 'hex', h)) 307 badtype(lambda: setattr(u, 'bytes', b)) 308 badtype(lambda: setattr(u, 'bytes_le', b)) 309 badtype(lambda: setattr(u, 'fields', f)) 310 badtype(lambda: setattr(u, 'int', i)) 311 badtype(lambda: setattr(u, 'time_low', 0)) 312 badtype(lambda: setattr(u, 'time_mid', 0)) 313 badtype(lambda: setattr(u, 'time_hi_version', 0)) 314 badtype(lambda: setattr(u, 'time_hi_version', 0)) 315 badtype(lambda: setattr(u, 'clock_seq_hi_variant', 0)) 316 badtype(lambda: setattr(u, 'clock_seq_low', 0)) 317 badtype(lambda: setattr(u, 'node', 0)) 318 319 # Comparison with a non-UUID object 320 badtype(lambda: u < object()) 321 badtype(lambda: u > object()) 322 323 def test_getnode(self): 324 node1 = self.uuid.getnode() 325 self.assertTrue(0 < node1 < (1 << 48), '%012x' % node1) 326 327 # Test it again to ensure consistency. 328 node2 = self.uuid.getnode() 329 self.assertEqual(node1, node2, '%012x != %012x' % (node1, node2)) 330 331 def test_pickle_roundtrip(self): 332 def check(actual, expected): 333 self.assertEqual(actual, expected) 334 self.assertEqual(actual.is_safe, expected.is_safe) 335 336 with support.swap_item(sys.modules, 'uuid', self.uuid): 337 for is_safe in self.uuid.SafeUUID: 338 u = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5', 339 is_safe=is_safe) 340 check(copy.copy(u), u) 341 check(copy.deepcopy(u), u) 342 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 343 with self.subTest(protocol=proto): 344 check(pickle.loads(pickle.dumps(u, proto)), u) 345 346 def test_unpickle_previous_python_versions(self): 347 def check(actual, expected): 348 self.assertEqual(actual, expected) 349 self.assertEqual(actual.is_safe, expected.is_safe) 350 351 pickled_uuids = [ 352 # Python 2.7, protocol 0 353 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 354 b'tR(dS\'int\'\nL287307832597519156748809049798316161701L\nsb.', 355 # Python 2.7, protocol 1 356 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 357 b'tR}U\x03intL287307832597519156748809049798316161701L\nsb.', 358 # Python 2.7, protocol 2 359 b'\x80\x02cuuid\nUUID\n)\x81}U\x03int\x8a\x11\xa5z\xecz\nI\xdf}' 360 b'\xde\xa0Bf\xcey%\xd8\x00sb.', 361 # Python 3.6, protocol 0 362 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 363 b'tR(dVint\nL287307832597519156748809049798316161701L\nsb.', 364 # Python 3.6, protocol 1 365 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 366 b'tR}X\x03\x00\x00\x00intL287307832597519156748809049798316161701L' 367 b'\nsb.', 368 # Python 3.6, protocol 2 369 b'\x80\x02cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec' 370 b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.', 371 # Python 3.6, protocol 3 372 b'\x80\x03cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec' 373 b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.', 374 # Python 3.6, protocol 4 375 b'\x80\x04\x95+\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x8c\x04UUI' 376 b'D\x93)\x81}\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0Bf\xcey%' 377 b'\xd8\x00sb.', 378 # Python 3.7, protocol 0 379 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 380 b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n' 381 b'cuuid\nSafeUUID\n(NtRsb.', 382 # Python 3.7, protocol 1 383 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 384 b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701' 385 b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(NtRub.', 386 # Python 3.7, protocol 2 387 b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' 388 b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' 389 b'id\nSafeUUID\nN\x85Rub.', 390 # Python 3.7, protocol 3 391 b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' 392 b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' 393 b'id\nSafeUUID\nN\x85Rub.', 394 # Python 3.7, protocol 4 395 b'\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c' 396 b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0' 397 b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93N\x85Rub' 398 b'.', 399 ] 400 pickled_uuids_safe = [ 401 # Python 3.7, protocol 0 402 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 403 b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n' 404 b'cuuid\nSafeUUID\n(I0\ntRsb.', 405 # Python 3.7, protocol 1 406 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 407 b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701' 408 b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(K\x00tRub.', 409 # Python 3.7, protocol 2 410 b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' 411 b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' 412 b'id\nSafeUUID\nK\x00\x85Rub.', 413 # Python 3.7, protocol 3 414 b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' 415 b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' 416 b'id\nSafeUUID\nK\x00\x85Rub.', 417 # Python 3.7, protocol 4 418 b'\x80\x04\x95G\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c' 419 b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0' 420 b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93K\x00' 421 b'\x85Rub.', 422 ] 423 pickled_uuids_unsafe = [ 424 # Python 3.7, protocol 0 425 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 426 b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n' 427 b'cuuid\nSafeUUID\n(I-1\ntRsb.', 428 # Python 3.7, protocol 1 429 b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' 430 b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701' 431 b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(J\xff\xff\xff\xfftR' 432 b'ub.', 433 # Python 3.7, protocol 2 434 b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' 435 b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' 436 b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.', 437 # Python 3.7, protocol 3 438 b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' 439 b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' 440 b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.', 441 # Python 3.7, protocol 4 442 b'\x80\x04\x95J\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c' 443 b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0' 444 b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93J\xff' 445 b'\xff\xff\xff\x85Rub.', 446 ] 447 448 u = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5') 449 u_safe = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5', 450 is_safe=self.uuid.SafeUUID.safe) 451 u_unsafe = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5', 452 is_safe=self.uuid.SafeUUID.unsafe) 453 454 with support.swap_item(sys.modules, 'uuid', self.uuid): 455 for pickled in pickled_uuids: 456 # is_safe was added in 3.7. When unpickling values from older 457 # versions, is_safe will be missing, so it should be set to 458 # SafeUUID.unknown. 459 check(pickle.loads(pickled), u) 460 for pickled in pickled_uuids_safe: 461 check(pickle.loads(pickled), u_safe) 462 for pickled in pickled_uuids_unsafe: 463 check(pickle.loads(pickled), u_unsafe) 464 465 # bpo-32502: UUID1 requires a 48-bit identifier, but hardware identifiers 466 # need not necessarily be 48 bits (e.g., EUI-64). 467 def test_uuid1_eui64(self): 468 # Confirm that uuid.getnode ignores hardware addresses larger than 48 469 # bits. Mock out each platform's *_getnode helper functions to return 470 # something just larger than 48 bits to test. This will cause 471 # uuid.getnode to fall back on uuid._random_getnode, which will 472 # generate a valid value. 473 too_large_getter = lambda: 1 << 48 474 with mock.patch.multiple( 475 self.uuid, 476 _node=None, # Ignore any cached node value. 477 _GETTERS=[too_large_getter], 478 ): 479 node = self.uuid.getnode() 480 self.assertTrue(0 < node < (1 << 48), '%012x' % node) 481 482 # Confirm that uuid1 can use the generated node, i.e., the that 483 # uuid.getnode fell back on uuid._random_getnode() rather than using 484 # the value from too_large_getter above. 485 try: 486 self.uuid.uuid1(node=node) 487 except ValueError: 488 self.fail('uuid1 was given an invalid node ID') 489 490 def test_uuid1(self): 491 equal = self.assertEqual 492 493 # Make sure uuid1() generates UUIDs that are actually version 1. 494 for u in [self.uuid.uuid1() for i in range(10)]: 495 equal(u.variant, self.uuid.RFC_4122) 496 equal(u.version, 1) 497 self.assertIn(u.is_safe, {self.uuid.SafeUUID.safe, 498 self.uuid.SafeUUID.unsafe, 499 self.uuid.SafeUUID.unknown}) 500 501 # Make sure the generated UUIDs are actually unique. 502 uuids = {} 503 for u in [self.uuid.uuid1() for i in range(1000)]: 504 uuids[u] = 1 505 equal(len(uuids.keys()), 1000) 506 507 # Make sure the supplied node ID appears in the UUID. 508 u = self.uuid.uuid1(0) 509 equal(u.node, 0) 510 u = self.uuid.uuid1(0x123456789abc) 511 equal(u.node, 0x123456789abc) 512 u = self.uuid.uuid1(0xffffffffffff) 513 equal(u.node, 0xffffffffffff) 514 515 # Make sure the supplied clock sequence appears in the UUID. 516 u = self.uuid.uuid1(0x123456789abc, 0) 517 equal(u.node, 0x123456789abc) 518 equal(((u.clock_seq_hi_variant & 0x3f) << 8) | u.clock_seq_low, 0) 519 u = self.uuid.uuid1(0x123456789abc, 0x1234) 520 equal(u.node, 0x123456789abc) 521 equal(((u.clock_seq_hi_variant & 0x3f) << 8) | 522 u.clock_seq_low, 0x1234) 523 u = self.uuid.uuid1(0x123456789abc, 0x3fff) 524 equal(u.node, 0x123456789abc) 525 equal(((u.clock_seq_hi_variant & 0x3f) << 8) | 526 u.clock_seq_low, 0x3fff) 527 528 # bpo-29925: On Mac OS X Tiger, self.uuid.uuid1().is_safe returns 529 # self.uuid.SafeUUID.unknown 530 @support.requires_mac_ver(10, 5) 531 @unittest.skipUnless(os.name == 'posix', 'POSIX-only test') 532 def test_uuid1_safe(self): 533 try: 534 import _uuid 535 except ImportError: 536 has_uuid_generate_time_safe = False 537 else: 538 has_uuid_generate_time_safe = _uuid.has_uuid_generate_time_safe 539 540 if not has_uuid_generate_time_safe or not self.uuid._generate_time_safe: 541 self.skipTest('requires uuid_generate_time_safe(3)') 542 543 u = self.uuid.uuid1() 544 # uuid_generate_time_safe() may return 0 or -1 but what it returns is 545 # dependent on the underlying platform support. At least it cannot be 546 # unknown (unless I suppose the platform is buggy). 547 self.assertNotEqual(u.is_safe, self.uuid.SafeUUID.unknown) 548 549 @contextlib.contextmanager 550 def mock_generate_time_safe(self, safe_value): 551 """ 552 Mock uuid._generate_time_safe() to return a given *safe_value*. 553 """ 554 if os.name != 'posix': 555 self.skipTest('POSIX-only test') 556 f = self.uuid._generate_time_safe 557 if f is None: 558 self.skipTest('need uuid._generate_time_safe') 559 with mock.patch.object(self.uuid, '_generate_time_safe', 560 lambda: (f()[0], safe_value)): 561 yield 562 563 @unittest.skipUnless(os.name == 'posix', 'POSIX-only test') 564 def test_uuid1_unknown(self): 565 # Even if the platform has uuid_generate_time_safe(), let's mock it to 566 # be uuid_generate_time() and ensure the safety is unknown. 567 with self.mock_generate_time_safe(None): 568 u = self.uuid.uuid1() 569 self.assertEqual(u.is_safe, self.uuid.SafeUUID.unknown) 570 571 @unittest.skipUnless(os.name == 'posix', 'POSIX-only test') 572 def test_uuid1_is_safe(self): 573 with self.mock_generate_time_safe(0): 574 u = self.uuid.uuid1() 575 self.assertEqual(u.is_safe, self.uuid.SafeUUID.safe) 576 577 @unittest.skipUnless(os.name == 'posix', 'POSIX-only test') 578 def test_uuid1_is_unsafe(self): 579 with self.mock_generate_time_safe(-1): 580 u = self.uuid.uuid1() 581 self.assertEqual(u.is_safe, self.uuid.SafeUUID.unsafe) 582 583 @unittest.skipUnless(os.name == 'posix', 'POSIX-only test') 584 def test_uuid1_bogus_return_value(self): 585 with self.mock_generate_time_safe(3): 586 u = self.uuid.uuid1() 587 self.assertEqual(u.is_safe, self.uuid.SafeUUID.unknown) 588 589 def test_uuid1_time(self): 590 with mock.patch.object(self.uuid, '_generate_time_safe', None), \ 591 mock.patch.object(self.uuid, '_last_timestamp', None), \ 592 mock.patch.object(self.uuid, 'getnode', return_value=93328246233727), \ 593 mock.patch('time.time_ns', return_value=1545052026752910643), \ 594 mock.patch('random.getrandbits', return_value=5317): # guaranteed to be random 595 u = self.uuid.uuid1() 596 self.assertEqual(u, self.uuid.UUID('a7a55b92-01fc-11e9-94c5-54e1acf6da7f')) 597 598 with mock.patch.object(self.uuid, '_generate_time_safe', None), \ 599 mock.patch.object(self.uuid, '_last_timestamp', None), \ 600 mock.patch('time.time_ns', return_value=1545052026752910643): 601 u = self.uuid.uuid1(node=93328246233727, clock_seq=5317) 602 self.assertEqual(u, self.uuid.UUID('a7a55b92-01fc-11e9-94c5-54e1acf6da7f')) 603 604 def test_uuid3(self): 605 equal = self.assertEqual 606 607 # Test some known version-3 UUIDs with name passed as a byte object 608 for u, v in [(self.uuid.uuid3(self.uuid.NAMESPACE_DNS, b'python.org'), 609 '6fa459ea-ee8a-3ca4-894e-db77e160355e'), 610 (self.uuid.uuid3(self.uuid.NAMESPACE_URL, b'http://python.org/'), 611 '9fe8e8c4-aaa8-32a9-a55c-4535a88b748d'), 612 (self.uuid.uuid3(self.uuid.NAMESPACE_OID, b'1.3.6.1'), 613 'dd1a1cef-13d5-368a-ad82-eca71acd4cd1'), 614 (self.uuid.uuid3(self.uuid.NAMESPACE_X500, b'c=ca'), 615 '658d3002-db6b-3040-a1d1-8ddd7d189a4d'), 616 ]: 617 equal(u.variant, self.uuid.RFC_4122) 618 equal(u.version, 3) 619 equal(u, self.uuid.UUID(v)) 620 equal(str(u), v) 621 622 # Test some known version-3 UUIDs with name passed as a string 623 for u, v in [(self.uuid.uuid3(self.uuid.NAMESPACE_DNS, 'python.org'), 624 '6fa459ea-ee8a-3ca4-894e-db77e160355e'), 625 (self.uuid.uuid3(self.uuid.NAMESPACE_URL, 'http://python.org/'), 626 '9fe8e8c4-aaa8-32a9-a55c-4535a88b748d'), 627 (self.uuid.uuid3(self.uuid.NAMESPACE_OID, '1.3.6.1'), 628 'dd1a1cef-13d5-368a-ad82-eca71acd4cd1'), 629 (self.uuid.uuid3(self.uuid.NAMESPACE_X500, 'c=ca'), 630 '658d3002-db6b-3040-a1d1-8ddd7d189a4d'), 631 ]: 632 equal(u.variant, self.uuid.RFC_4122) 633 equal(u.version, 3) 634 equal(u, self.uuid.UUID(v)) 635 equal(str(u), v) 636 637 def test_uuid4(self): 638 equal = self.assertEqual 639 640 # Make sure uuid4() generates UUIDs that are actually version 4. 641 for u in [self.uuid.uuid4() for i in range(10)]: 642 equal(u.variant, self.uuid.RFC_4122) 643 equal(u.version, 4) 644 645 # Make sure the generated UUIDs are actually unique. 646 uuids = {} 647 for u in [self.uuid.uuid4() for i in range(1000)]: 648 uuids[u] = 1 649 equal(len(uuids.keys()), 1000) 650 651 def test_uuid5(self): 652 equal = self.assertEqual 653 654 # Test some known version-5 UUIDs with names given as byte objects 655 for u, v in [(self.uuid.uuid5(self.uuid.NAMESPACE_DNS, b'python.org'), 656 '886313e1-3b8a-5372-9b90-0c9aee199e5d'), 657 (self.uuid.uuid5(self.uuid.NAMESPACE_URL, b'http://python.org/'), 658 '4c565f0d-3f5a-5890-b41b-20cf47701c5e'), 659 (self.uuid.uuid5(self.uuid.NAMESPACE_OID, b'1.3.6.1'), 660 '1447fa61-5277-5fef-a9b3-fbc6e44f4af3'), 661 (self.uuid.uuid5(self.uuid.NAMESPACE_X500, b'c=ca'), 662 'cc957dd1-a972-5349-98cd-874190002798'), 663 ]: 664 equal(u.variant, self.uuid.RFC_4122) 665 equal(u.version, 5) 666 equal(u, self.uuid.UUID(v)) 667 equal(str(u), v) 668 669 # Test some known version-5 UUIDs with names given as strings 670 for u, v in [(self.uuid.uuid5(self.uuid.NAMESPACE_DNS, 'python.org'), 671 '886313e1-3b8a-5372-9b90-0c9aee199e5d'), 672 (self.uuid.uuid5(self.uuid.NAMESPACE_URL, 'http://python.org/'), 673 '4c565f0d-3f5a-5890-b41b-20cf47701c5e'), 674 (self.uuid.uuid5(self.uuid.NAMESPACE_OID, '1.3.6.1'), 675 '1447fa61-5277-5fef-a9b3-fbc6e44f4af3'), 676 (self.uuid.uuid5(self.uuid.NAMESPACE_X500, 'c=ca'), 677 'cc957dd1-a972-5349-98cd-874190002798'), 678 ]: 679 equal(u.variant, self.uuid.RFC_4122) 680 equal(u.version, 5) 681 equal(u, self.uuid.UUID(v)) 682 equal(str(u), v) 683 684 @support.requires_fork() 685 def testIssue8621(self): 686 # On at least some versions of OSX self.uuid.uuid4 generates 687 # the same sequence of UUIDs in the parent and any 688 # children started using fork. 689 fds = os.pipe() 690 pid = os.fork() 691 if pid == 0: 692 os.close(fds[0]) 693 value = self.uuid.uuid4() 694 os.write(fds[1], value.hex.encode('latin-1')) 695 os._exit(0) 696 697 else: 698 os.close(fds[1]) 699 self.addCleanup(os.close, fds[0]) 700 parent_value = self.uuid.uuid4().hex 701 support.wait_process(pid, exitcode=0) 702 child_value = os.read(fds[0], 100).decode('latin-1') 703 704 self.assertNotEqual(parent_value, child_value) 705 706 def test_uuid_weakref(self): 707 # bpo-35701: check that weak referencing to a UUID object can be created 708 strong = self.uuid.uuid4() 709 weak = weakref.ref(strong) 710 self.assertIs(strong, weak()) 711 712 @mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-n", "@dns"]) 713 @mock.patch('sys.stderr', new_callable=io.StringIO) 714 def test_cli_namespace_required_for_uuid3(self, mock_err): 715 with self.assertRaises(SystemExit) as cm: 716 self.uuid.main() 717 718 # Check that exception code is the same as argparse.ArgumentParser.error 719 self.assertEqual(cm.exception.code, 2) 720 self.assertIn("error: Incorrect number of arguments", mock_err.getvalue()) 721 722 @mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-N", "python.org"]) 723 @mock.patch('sys.stderr', new_callable=io.StringIO) 724 def test_cli_name_required_for_uuid3(self, mock_err): 725 with self.assertRaises(SystemExit) as cm: 726 self.uuid.main() 727 # Check that exception code is the same as argparse.ArgumentParser.error 728 self.assertEqual(cm.exception.code, 2) 729 self.assertIn("error: Incorrect number of arguments", mock_err.getvalue()) 730 731 @mock.patch.object(sys, "argv", [""]) 732 def test_cli_uuid4_outputted_with_no_args(self): 733 stdout = io.StringIO() 734 with contextlib.redirect_stdout(stdout): 735 self.uuid.main() 736 737 output = stdout.getvalue().strip() 738 uuid_output = self.uuid.UUID(output) 739 740 # Output uuid should be in the format of uuid4 741 self.assertEqual(output, str(uuid_output)) 742 self.assertEqual(uuid_output.version, 4) 743 744 @mock.patch.object(sys, "argv", 745 ["", "-u", "uuid3", "-n", "@dns", "-N", "python.org"]) 746 def test_cli_uuid3_ouputted_with_valid_namespace_and_name(self): 747 stdout = io.StringIO() 748 with contextlib.redirect_stdout(stdout): 749 self.uuid.main() 750 751 output = stdout.getvalue().strip() 752 uuid_output = self.uuid.UUID(output) 753 754 # Output should be in the form of uuid5 755 self.assertEqual(output, str(uuid_output)) 756 self.assertEqual(uuid_output.version, 3) 757 758 @mock.patch.object(sys, "argv", 759 ["", "-u", "uuid5", "-n", "@dns", "-N", "python.org"]) 760 def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self): 761 stdout = io.StringIO() 762 with contextlib.redirect_stdout(stdout): 763 self.uuid.main() 764 765 output = stdout.getvalue().strip() 766 uuid_output = self.uuid.UUID(output) 767 768 # Output should be in the form of uuid5 769 self.assertEqual(output, str(uuid_output)) 770 self.assertEqual(uuid_output.version, 5) 771 772 773class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase): 774 uuid = py_uuid 775 776@unittest.skipUnless(c_uuid, 'requires the C _uuid module') 777class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase): 778 uuid = c_uuid 779 780 781class BaseTestInternals: 782 _uuid = py_uuid 783 784 def check_parse_mac(self, aix): 785 if not aix: 786 patch = mock.patch.multiple(self.uuid, 787 _MAC_DELIM=b':', 788 _MAC_OMITS_LEADING_ZEROES=False) 789 else: 790 patch = mock.patch.multiple(self.uuid, 791 _MAC_DELIM=b'.', 792 _MAC_OMITS_LEADING_ZEROES=True) 793 794 with patch: 795 # Valid MAC addresses 796 if not aix: 797 tests = ( 798 (b'52:54:00:9d:0e:67', 0x5254009d0e67), 799 (b'12:34:56:78:90:ab', 0x1234567890ab), 800 ) 801 else: 802 # AIX format 803 tests = ( 804 (b'fe.ad.c.1.23.4', 0xfead0c012304), 805 ) 806 for mac, expected in tests: 807 self.assertEqual(self.uuid._parse_mac(mac), expected) 808 809 # Invalid MAC addresses 810 for mac in ( 811 b'', 812 # IPv6 addresses with same length than valid MAC address 813 # (17 characters) 814 b'fe80::5054:ff:fe9', 815 b'123:2:3:4:5:6:7:8', 816 # empty 5rd field 817 b'52:54:00:9d::67', 818 # only 5 fields instead of 6 819 b'52:54:00:9d:0e' 820 # invalid character 'x' 821 b'52:54:00:9d:0e:6x' 822 # dash separator 823 b'52-54-00-9d-0e-67', 824 ): 825 if aix: 826 mac = mac.replace(b':', b'.') 827 with self.subTest(mac=mac): 828 self.assertIsNone(self.uuid._parse_mac(mac)) 829 830 def test_parse_mac(self): 831 self.check_parse_mac(False) 832 833 def test_parse_mac_aix(self): 834 self.check_parse_mac(True) 835 836 def test_find_under_heading(self): 837 data = '''\ 838Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll 839en0 1500 link#2 fe.ad.c.1.23.4 1714807956 0 711348489 0 0 840 01:00:5e:00:00:01 841en0 1500 192.168.129 x071 1714807956 0 711348489 0 0 842 224.0.0.1 843en0 1500 192.168.90 x071 1714807956 0 711348489 0 0 844 224.0.0.1 845''' 846 847 # The above data is from AIX - with '.' as _MAC_DELIM and strings 848 # shorter than 17 bytes (no leading 0). (_MAC_OMITS_LEADING_ZEROES=True) 849 with mock.patch.multiple(self.uuid, 850 _MAC_DELIM=b'.', 851 _MAC_OMITS_LEADING_ZEROES=True, 852 _get_command_stdout=mock_get_command_stdout(data)): 853 mac = self.uuid._find_mac_under_heading( 854 command='netstat', 855 args='-ian', 856 heading=b'Address', 857 ) 858 859 self.assertEqual(mac, 0xfead0c012304) 860 861 def test_find_under_heading_ipv6(self): 862 # bpo-39991: IPv6 address "fe80::5054:ff:fe9" looks like a MAC address 863 # (same string length) but must be skipped 864 data = '''\ 865Name Mtu Network Address Ipkts Ierrs Idrop Opkts Oerrs Coll 866vtnet 1500 <Link#1> 52:54:00:9d:0e:67 10017 0 0 8174 0 0 867vtnet - fe80::%vtnet0 fe80::5054:ff:fe9 0 - - 4 - - 868vtnet - 192.168.122.0 192.168.122.45 8844 - - 8171 - - 869lo0 16384 <Link#2> lo0 260148 0 0 260148 0 0 870lo0 - ::1/128 ::1 193 - - 193 - - 871 ff01::1%lo0 872 ff02::2:2eb7:74fa 873 ff02::2:ff2e:b774 874 ff02::1%lo0 875 ff02::1:ff00:1%lo 876lo0 - fe80::%lo0/64 fe80::1%lo0 0 - - 0 - - 877 ff01::1%lo0 878 ff02::2:2eb7:74fa 879 ff02::2:ff2e:b774 880 ff02::1%lo0 881 ff02::1:ff00:1%lo 882lo0 - 127.0.0.0/8 127.0.0.1 259955 - - 259955 - - 883 224.0.0.1 884''' 885 886 with mock.patch.multiple(self.uuid, 887 _MAC_DELIM=b':', 888 _MAC_OMITS_LEADING_ZEROES=False, 889 _get_command_stdout=mock_get_command_stdout(data)): 890 mac = self.uuid._find_mac_under_heading( 891 command='netstat', 892 args='-ian', 893 heading=b'Address', 894 ) 895 896 self.assertEqual(mac, 0x5254009d0e67) 897 898 def test_find_mac_near_keyword(self): 899 # key and value are on the same line 900 data = ''' 901fake Link encap:UNSPEC hwaddr 00-00 902cscotun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 903eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab 904''' 905 906 # The above data will only be parsed properly on non-AIX unixes. 907 with mock.patch.multiple(self.uuid, 908 _MAC_DELIM=b':', 909 _MAC_OMITS_LEADING_ZEROES=False, 910 _get_command_stdout=mock_get_command_stdout(data)): 911 mac = self.uuid._find_mac_near_keyword( 912 command='ifconfig', 913 args='', 914 keywords=[b'hwaddr'], 915 get_word_index=lambda x: x + 1, 916 ) 917 918 self.assertEqual(mac, 0x1234567890ab) 919 920 def check_node(self, node, requires=None): 921 if requires and node is None: 922 self.skipTest('requires ' + requires) 923 hex = '%012x' % node 924 if support.verbose >= 2: 925 print(hex, end=' ') 926 self.assertTrue(0 < node < (1 << 48), 927 "%s is not an RFC 4122 node ID" % hex) 928 929 @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, 930 "ifconfig is not used for introspection on this platform") 931 def test_ifconfig_getnode(self): 932 node = self.uuid._ifconfig_getnode() 933 self.check_node(node, 'ifconfig') 934 935 @unittest.skipUnless(_uuid._ip_getnode in _uuid._GETTERS, 936 "ip is not used for introspection on this platform") 937 def test_ip_getnode(self): 938 node = self.uuid._ip_getnode() 939 self.check_node(node, 'ip') 940 941 @unittest.skipUnless(_uuid._arp_getnode in _uuid._GETTERS, 942 "arp is not used for introspection on this platform") 943 def test_arp_getnode(self): 944 node = self.uuid._arp_getnode() 945 self.check_node(node, 'arp') 946 947 @unittest.skipUnless(_uuid._lanscan_getnode in _uuid._GETTERS, 948 "lanscan is not used for introspection on this platform") 949 def test_lanscan_getnode(self): 950 node = self.uuid._lanscan_getnode() 951 self.check_node(node, 'lanscan') 952 953 @unittest.skipUnless(_uuid._netstat_getnode in _uuid._GETTERS, 954 "netstat is not used for introspection on this platform") 955 def test_netstat_getnode(self): 956 node = self.uuid._netstat_getnode() 957 self.check_node(node, 'netstat') 958 959 def test_random_getnode(self): 960 node = self.uuid._random_getnode() 961 # The multicast bit, i.e. the least significant bit of first octet, 962 # must be set for randomly generated MAC addresses. See RFC 4122, 963 # $4.1.6. 964 self.assertTrue(node & (1 << 40), '%012x' % node) 965 self.check_node(node) 966 967 node2 = self.uuid._random_getnode() 968 self.assertNotEqual(node2, node, '%012x' % node) 969 970class TestInternalsWithoutExtModule(BaseTestInternals, unittest.TestCase): 971 uuid = py_uuid 972 973@unittest.skipUnless(c_uuid, 'requires the C _uuid module') 974class TestInternalsWithExtModule(BaseTestInternals, unittest.TestCase): 975 uuid = c_uuid 976 977 @unittest.skipUnless(os.name == 'posix', 'requires Posix') 978 def test_unix_getnode(self): 979 if not importable('_uuid') and not importable('ctypes'): 980 self.skipTest("neither _uuid extension nor ctypes available") 981 try: # Issues 1481, 3581: _uuid_generate_time() might be None. 982 node = self.uuid._unix_getnode() 983 except TypeError: 984 self.skipTest('requires uuid_generate_time') 985 self.check_node(node, 'unix') 986 987 @unittest.skipUnless(os.name == 'nt', 'requires Windows') 988 def test_windll_getnode(self): 989 node = self.uuid._windll_getnode() 990 self.check_node(node) 991 992 993if __name__ == '__main__': 994 unittest.main() 995