| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Module to get random numbers, strings, etc. | 5 """Module to get random numbers, strings, etc. |
| 6 | 6 |
| 7 The values returned by the various functions can be replaced in | 7 The values returned by the various functions can be replaced in |
| 8 templates to generate test cases. | 8 templates to generate test cases. |
| 9 """ | 9 """ |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 # fields are replaced by Get*Base() functions below to generate valid test | 27 # fields are replaced by Get*Base() functions below to generate valid test |
| 28 # cases. | 28 # cases. |
| 29 BASIC_BASE = \ | 29 BASIC_BASE = \ |
| 30 ' return setBluetoothFakeAdapter({fake_adapter_name})\n'\ | 30 ' return setBluetoothFakeAdapter({fake_adapter_name})\n'\ |
| 31 ' .then(() => {{\n' | 31 ' .then(() => {{\n' |
| 32 | 32 |
| 33 DEVICE_DISCOVERY_BASE = BASIC_BASE + \ | 33 DEVICE_DISCOVERY_BASE = BASIC_BASE + \ |
| 34 ' return requestDeviceWithKeyDown({{\n'\ | 34 ' return requestDeviceWithKeyDown({{\n'\ |
| 35 ' filters: [{{services: [{service_uuid}]}}]}});\n'\ | 35 ' filters: [{{services: [{service_uuid}]}}]}});\n'\ |
| 36 ' }})\n'\ | 36 ' }})\n'\ |
| 37 ' .then(device => {{\n' | 37 ' .then(device => {{\n'\ |
| 38 ' var gatt = device.gatt;\n' |
| 38 | 39 |
| 39 CONNECTABLE_BASE = DEVICE_DISCOVERY_BASE + \ | 40 CONNECTABLE_BASE = DEVICE_DISCOVERY_BASE + \ |
| 40 ' return device.gatt.connect();\n'\ | 41 ' return gatt.connect();\n'\ |
| 41 ' }})\n'\ | 42 ' }})\n'\ |
| 42 ' .then(gatt => {{\n' | 43 ' .then(gatt => {{\n'\ |
| 44 ' var device = gatt.device;\n' |
| 43 | 45 |
| 44 SERVICE_RETRIEVED_BASE = CONNECTABLE_BASE + \ | 46 SERVICE_RETRIEVED_BASE = CONNECTABLE_BASE + \ |
| 45 ' return gatt.getPrimaryService({service_uuid});\n'\ | 47 ' return gatt.getPrimaryService({service_uuid});\n'\ |
| 46 ' }})\n'\ | 48 ' }})\n'\ |
| 47 ' .then(service => {{\n' | 49 ' .then(services => {{\n'\ |
| 50 ' var device = services.device;\n'\ |
| 51 ' var gatt = device.gatt;\n' |
| 48 | 52 |
| 53 SERVICES_RETRIEVED_BASE = CONNECTABLE_BASE + \ |
| 54 ' return gatt.getPrimaryServices({optional_service_uuid});\n'\ |
| 55 ' }})\n'\ |
| 56 ' .then(services => {{\n'\ |
| 57 ' var device = services[0].device;\n'\ |
| 58 ' var gatt = device.gatt;\n' |
| 59 |
| 60 CHARACTERISTIC_RETRIEVED_BASE = \ |
| 61 ' TRANSFORM_PICK_A_SERVICE;\n'\ |
| 62 ' return service.getCharacteristic({characteristic_uuid});\n'\ |
| 63 ' }})\n'\ |
| 64 ' .then(characteristics => {{\n'\ |
| 65 ' var service = characteristics.service;\n'\ |
| 66 ' var device = service.device;\n'\ |
| 67 ' var gatt = device.gatt;\n' |
| 68 |
| 69 CHARACTERISTICS_RETRIEVED_BASE = \ |
| 70 ' TRANSFORM_PICK_A_SERVICE;\n'\ |
| 71 ' return service.getCharacteristics({optional_characteristic_uuid});\n'
\ |
| 72 ' }})\n'\ |
| 73 ' .then(characteristics => {{\n'\ |
| 74 ' var service = characteristics[0].service;\n'\ |
| 75 ' var device = service.device;\n'\ |
| 76 ' var gatt = device.gatt;\n' |
| 49 | 77 |
| 50 def _ToJsStr(s): | 78 def _ToJsStr(s): |
| 51 return u'\'{}\''.format(s) | 79 return u'\'{}\''.format(s) |
| 52 | 80 |
| 53 | 81 |
| 82 def _GetOptional(s): |
| 83 return random.choice(['', s]) |
| 84 |
| 85 |
| 86 def _GetRandomNumber(): |
| 87 return utils.UniformExpoInteger(0, sys.maxsize.bit_length() + 1) |
| 88 |
| 89 |
| 54 def _GetFuzzedJsString(s): | 90 def _GetFuzzedJsString(s): |
| 55 """Returns a fuzzed string based on |s|. | 91 """Returns a fuzzed string based on |s|. |
| 56 | 92 |
| 57 Args: | 93 Args: |
| 58 s: The base string to fuzz. | 94 s: The base string to fuzz. |
| 59 Returns: | 95 Returns: |
| 60 A single line string surrounded by quotes. | 96 A single line string surrounded by quotes. |
| 61 """ | 97 """ |
| 62 while True: | 98 while True: |
| 63 fuzzed_string = fuzzy_types.FuzzyString(s) | 99 fuzzed_string = fuzzy_types.FuzzyString(s) |
| 64 try: | 100 try: |
| 65 fuzzed_string = fuzzed_string.decode('utf8') | 101 fuzzed_string = fuzzed_string.decode('utf8') |
| 66 except UnicodeDecodeError: | 102 except UnicodeDecodeError: |
| 67 print 'Can\'t decode fuzzed string. Trying again.' | 103 print 'Can\'t decode fuzzed string. Trying again.' |
| 68 else: | 104 else: |
| 69 fuzzed_string = '\\n'.join(fuzzed_string.split()) | 105 fuzzed_string = '\\n'.join(fuzzed_string.split()) |
| 106 fuzzed_string = fuzzed_string.replace('\\', r'\\') |
| 70 fuzzed_string = fuzzed_string.replace('\'', r'\'') | 107 fuzzed_string = fuzzed_string.replace('\'', r'\'') |
| 71 return _ToJsStr(fuzzed_string) | 108 return _ToJsStr(fuzzed_string) |
| 72 | 109 |
| 73 | 110 |
| 74 def GetAdvertisedServiceUUIDFromFakes(): | 111 def GetAdvertisedServiceUUIDFromFakes(): |
| 75 """Returns a random service string from the list of fake services.""" | 112 """Returns a random service string from the list of fake services.""" |
| 76 return _ToJsStr(random.choice(wbt_fakes.ADVERTISED_SERVICES)) | 113 return _ToJsStr(random.choice(wbt_fakes.ADVERTISED_SERVICES)) |
| 77 | 114 |
| 78 | 115 |
| 116 def GetServiceUUIDFromFakes(): |
| 117 """Returns a random service string from the list of fake services.""" |
| 118 return _ToJsStr(random.choice(wbt_fakes.SERVICES)) |
| 119 |
| 120 |
| 121 def GetCharacteristicUUIDFromFakes(): |
| 122 return _ToJsStr(random.choice(wbt_fakes.CHARACTERISTICS)) |
| 123 |
| 124 |
| 79 def GetValidServiceAlias(): | 125 def GetValidServiceAlias(): |
| 80 """Returns a valid service alias from the list of services aliases.""" | 126 """Returns a valid service alias from the list of services aliases.""" |
| 81 return _ToJsStr(random.choice(gatt_aliases.SERVICES)) | 127 return _ToJsStr(random.choice(gatt_aliases.SERVICES)) |
| 82 | 128 |
| 83 | 129 |
| 84 def GetRandomUUID(): | 130 def GetRandomUUID(): |
| 85 """Returns a random UUID, a random number or a fuzzed uuid or alias.""" | 131 """Returns a random UUID, a random number or a fuzzed uuid or alias.""" |
| 86 choice = random.choice(['uuid', 'number', 'fuzzed string']) | 132 choice = random.choice(['uuid', 'number', 'fuzzed string']) |
| 87 if choice == 'uuid': | 133 if choice == 'uuid': |
| 88 return _ToJsStr(uuid.uuid4()) | 134 return _ToJsStr(uuid.uuid4()) |
| 89 elif choice == 'number': | 135 elif choice == 'number': |
| 90 return utils.UniformExpoInteger(0, sys.maxsize.bit_length() + 1) | 136 return _GetRandomNumber() |
| 91 elif choice == 'fuzzed string': | 137 elif choice == 'fuzzed string': |
| 92 choice2 = random.choice(['uuid', 'alias']) | 138 choice2 = random.choice(['uuid', 'alias']) |
| 93 if choice2 == 'uuid': | 139 if choice2 == 'uuid': |
| 94 random_uuid = str(uuid.uuid4()) | 140 random_uuid = str(uuid.uuid4()) |
| 95 return _GetFuzzedJsString(random_uuid) | 141 return _GetFuzzedJsString(random_uuid) |
| 96 elif choice2 == 'alias': | 142 elif choice2 == 'alias': |
| 97 alias = random.choice(gatt_aliases.SERVICES) | 143 alias = random.choice(gatt_aliases.SERVICES) |
| 98 return _GetFuzzedJsString(alias) | 144 return _GetFuzzedJsString(alias) |
| 99 | 145 |
| 100 | 146 |
| 101 def GetAdvertisedServiceUUID(): | 147 def GetAdvertisedServiceUUID(): |
| 102 """Generates a random Service UUID from a set of functions. | 148 """Generates a random Service UUID from a set of functions. |
| 103 | 149 |
| 104 See GetServiceUUIDFromFakes(), GetValidServiceAlias() and GetRandomUUID() | 150 See GetAdvertisedServiceUUIDFromFakes(), GetValidServiceAlias() and |
| 105 for the different values this function can return. | 151 GetRandomUUID() for the different values this function can return. |
| 106 | 152 |
| 107 This function weights GetServiceUUIDFromFakes() more heavily to increase the | 153 This function weights GetServiceUUIDFromFakes() more heavily to increase the |
| 108 probability of generating test pages that can interact with the fake | 154 probability of generating test pages that can interact with the fake |
| 109 adapters. | 155 adapters. |
| 110 | 156 |
| 111 Returns: | 157 Returns: |
| 112 A string or a number that can be used as a Service UUID by the Web | 158 A string or a number that can be used as a Service UUID by the Web |
| 113 Bluetooth API. | 159 Bluetooth API. |
| 114 """ | 160 """ |
| 115 roll = random.random() | 161 roll = random.random() |
| 116 if roll < 0.8: | 162 if roll < 0.8: |
| 117 return GetAdvertisedServiceUUIDFromFakes() | 163 return GetAdvertisedServiceUUIDFromFakes() |
| 118 elif roll < 0.9: | 164 elif roll < 0.9: |
| 119 return GetValidServiceAlias() | 165 return GetValidServiceAlias() |
| 120 else: | 166 else: |
| 121 return GetRandomUUID() | 167 return GetRandomUUID() |
| 122 | 168 |
| 123 | 169 |
| 170 def GetServiceUUID(): |
| 171 """Generates a random Service UUID from a set of functions. |
| 172 |
| 173 Similar to GetAdvertisedServiceUUID() but weights GetServiceUUIDFromFakes() |
| 174 more heavily to increase the probability of generating test pages that can |
| 175 interact with the fake adapters. |
| 176 |
| 177 See GetServiceUUIDFromFakes(), GetValidServiceAlias() and |
| 178 GetRandomUUID() for the different values this function can return. |
| 179 |
| 180 Returns: |
| 181 A string or a number that can be used as a Service UUID by the Web |
| 182 Bluetooth API. |
| 183 """ |
| 184 roll = random.random() |
| 185 if roll < 0.8: |
| 186 return GetServiceUUIDFromFakes() |
| 187 elif roll < 0.9: |
| 188 return GetValidServiceAlias() |
| 189 else: |
| 190 return GetRandomUUID() |
| 191 |
| 192 |
| 193 def GetCharacteristicUUID(): |
| 194 roll = random.random() |
| 195 if roll < 0.8: |
| 196 return GetCharacteristicUUIDFromFakes() |
| 197 elif roll < 0.9: |
| 198 return GetCharacteristicUUIDFromFakes() |
| 199 else: |
| 200 return GetRandomUUID() |
| 201 |
| 202 |
| 124 def GetRequestDeviceOptions(): | 203 def GetRequestDeviceOptions(): |
| 125 """Returns an object used by navigator.bluetooth.requestDevice.""" | 204 """Returns an object used by navigator.bluetooth.requestDevice.""" |
| 126 # TODO(ortuno): Randomize the members, number of filters, services, etc. | 205 # TODO(ortuno): Randomize the members, number of filters, services, etc. |
| 127 | 206 |
| 128 return '{filters: [{services: [ %s ]}]}' % GetAdvertisedServiceUUID() | 207 return '{filters: [{services: [ %s ]}]}' % GetAdvertisedServiceUUID() |
| 129 | 208 |
| 130 | 209 |
| 131 def GetBasicBase(): | 210 def GetBasicBase(): |
| 132 """Returns a string that sets a random fake adapter.""" | 211 """Returns a string that sets a random fake adapter.""" |
| 133 adapter = _ToJsStr(random.choice(wbt_fakes.ALL_ADAPTERS)) | 212 adapter = _ToJsStr(random.choice(wbt_fakes.ALL_ADAPTERS)) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 149 1. Sets an adapter to a fake adapter with a connectable device. | 228 1. Sets an adapter to a fake adapter with a connectable device. |
| 150 2. Looks for the connectable device. | 229 2. Looks for the connectable device. |
| 151 3. Connects to it. | 230 3. Connects to it. |
| 152 """ | 231 """ |
| 153 adapter, services = random.choice(wbt_fakes.ADAPTERS_WITH_DEVICES) | 232 adapter, services = random.choice(wbt_fakes.ADAPTERS_WITH_DEVICES) |
| 154 return DEVICE_DISCOVERY_BASE.format( | 233 return DEVICE_DISCOVERY_BASE.format( |
| 155 fake_adapter_name=_ToJsStr(adapter), | 234 fake_adapter_name=_ToJsStr(adapter), |
| 156 service_uuid=_ToJsStr(random.choice(services))) | 235 service_uuid=_ToJsStr(random.choice(services))) |
| 157 | 236 |
| 158 | 237 |
| 159 def GetServiceRetrievedBase(): | 238 def GetServicesRetrievedBase(): |
| 160 """Returns a string that contains all steps to retrieve a service. | 239 """Returns a string that contains all steps to retrieve a service. |
| 161 | 240 |
| 162 Returns: A string that: | 241 Returns: A string that: |
| 163 1. Sets an adapter to a fake adapter with a connectable device with | 242 1. Sets an adapter to a fake adapter with a connectable device with |
| 164 services. | 243 services. |
| 165 2. Use one of the device's services to look for that device. | 244 2. Use one of the device's services to look for that device. |
| 166 3. Connects to it. | 245 3. Connects to it. |
| 167 4. Retrieve the device's service used in 2. | 246 4. Retrieve the device's service used in 2. |
| 168 """ | 247 """ |
| 169 adapter, services = random.choice(wbt_fakes.ADAPTERS_WITH_SERVICES) | 248 adapter, services = random.choice(wbt_fakes.ADAPTERS_WITH_SERVICES) |
| 170 return SERVICE_RETRIEVED_BASE.format( | 249 service_uuid = _ToJsStr(random.choice(services)) |
| 250 |
| 251 base = random.choice([SERVICE_RETRIEVED_BASE, SERVICES_RETRIEVED_BASE]) |
| 252 return base.format( |
| 171 fake_adapter_name=_ToJsStr(adapter), | 253 fake_adapter_name=_ToJsStr(adapter), |
| 172 service_uuid=_ToJsStr(random.choice(services))) | 254 service_uuid=service_uuid, |
| 255 optional_service_uuid=_GetOptional(service_uuid)) |
| 256 |
| 257 def GetCharacteristicsRetrievedBase(): |
| 258 adapter, services = random.choice(wbt_fakes.ADAPTERS_WITH_CHARACTERISTICS) |
| 259 |
| 260 service_uuid, characteristics = random.choice(services) |
| 261 service_uuid = _ToJsStr(service_uuid) |
| 262 characteristic_uuid = _ToJsStr(random.choice(characteristics)) |
| 263 |
| 264 optional_service_uuid = _GetOptional(service_uuid) |
| 265 optional_characteristic_uuid = _GetOptional(characteristic_uuid) |
| 266 |
| 267 services_base = random.choice([SERVICE_RETRIEVED_BASE, |
| 268 SERVICES_RETRIEVED_BASE]) |
| 269 characteristics_base = services_base + random.choice( |
| 270 [CHARACTERISTIC_RETRIEVED_BASE, |
| 271 CHARACTERISTICS_RETRIEVED_BASE]) |
| 272 |
| 273 return characteristics_base.format( |
| 274 fake_adapter_name=_ToJsStr(adapter), |
| 275 service_uuid=service_uuid, |
| 276 optional_service_uuid=optional_service_uuid, |
| 277 characteristic_uuid=characteristic_uuid, |
| 278 optional_characteristic_uuid=optional_characteristic_uuid) |
| 279 |
| 280 def GetGetPrimaryServicesCall(): |
| 281 call = random.choice([u'getPrimaryService({service_uuid})', |
| 282 u'getPrimaryServices({optional_service_uuid})']) |
| 283 |
| 284 return call.format( |
| 285 service_uuid=GetServiceUUID(), |
| 286 optional_service_uuid=_GetOptional(GetServiceUUID())) |
| 287 |
| 288 |
| 289 def GetCatch(): |
| 290 return ".catch(e => console.log(e.name + \' \' + e.message))" |
| 291 |
| 292 def GetPickAService(): |
| 293 s = \ |
| 294 'var service; '\ |
| 295 'if (typeof services !== \'undefined\') '\ |
| 296 ' service = Array.isArray(services) ? services[{} % services.length] :'\ |
| 297 ' services' |
| 298 return s.format(random.randint(0, 10)) |
| 299 |
| 300 def GetPickACharacteristic(): |
| 301 s = \ |
| 302 'var characteristic; '\ |
| 303 'if (typeof characteristics !== \'undefined\') '\ |
| 304 ' characteristic = Array.isArray(characteristics)'\ |
| 305 ' ? characteristics[{} % characteristics.length]'\ |
| 306 ' : characteristics' |
| 307 return s.format(random.randint(0, 10)) |
| 308 |
| 309 |
| 310 def GetGetCharacteristicsCall(): |
| 311 call = random.choice([u'getCharacteristic({characteristic_uuid})', |
| 312 u'getCharacteristics({optional_characteristic_uuid})']) |
| 313 |
| 314 return call.format( |
| 315 characteristic_uuid=GetCharacteristicUUID(), |
| 316 optional_characteristic_uuid=_GetOptional(GetCharacteristicUUID())) |
| 317 |
| 318 |
| 319 def GetWriteValue(): |
| 320 return 'new Uint8Array([1,2,3,4])'; |
| 321 |
| 322 |
| 323 def GetReturnArgs(): |
| 324 return \ |
| 325 'if (typeof characteristics !== \'undefined\') return characteristics; '\ |
| 326 'if (typeof services !== \'undefined\') return services; '\ |
| 327 'if (typeof gatt !== \'undefined\') return gatt; '\ |
| 328 'if (typeof device !== \'undefined\') return device;' |
| 329 |
| 330 def GetReloadId(): |
| 331 return _ToJsStr(_GetRandomNumber()) |
| OLD | NEW |