Chromium Code Reviews| 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 |
| 11 import os | |
| 11 import random | 12 import random |
| 13 import sys | |
| 14 import uuid | |
| 15 | |
| 16 import gatt_aliases | |
| 17 | |
| 18 # This file is uploaded next to 'common' to ClusterFuzz so we try to import | |
| 19 # the necessary modules from there. If we fail then we try the parent directory, | |
| 20 # where common is usually located when developing locally. | |
| 21 try: | |
| 22 # pylint: disable=E0611 | |
| 23 from common import utils | |
| 24 from common import fuzzy_types | |
| 25 except ImportError: | |
| 26 sys.path.append(os.pardir) | |
|
ortuno
2016/07/21 21:35:24
Now the setup.py script copies these files.
| |
| 27 # pylint: disable=E0611 | |
| 28 from common import utils | |
| 29 from common import fuzzy_types | |
| 12 | 30 |
| 13 | 31 |
| 14 def GetValidUUIDString(): | 32 # List of services that are included in our fake adapters. |
|
ortuno
2016/07/21 21:35:24
Done.
| |
| 15 """Constructs a valid UUID string. | 33 FAKE_SERVICES = [ |
| 34 'generic_access', | |
| 35 'glucose', | |
| 36 'heart_rate', | |
| 37 'battery_service', | |
| 38 'human_interface_device', | |
| 39 '000000a0-97e5-4cd7-b9f1-f5a427670c59', # Error UUID | |
| 40 'device_information', | |
| 41 '611c954a-263b-4f4a-aab6-01ddb953f985', # Blacklist | |
| 42 '01d7d889-7451-419f-aeb8-d65e7b9277af', # Request Disconnection | |
| 43 ] | |
| 44 | |
| 45 # List of available fake adapters. | |
| 46 FAKE_ADAPTERS = [ | |
| 47 'BaseAdapter', | |
| 48 'NotPresentAdapter', | |
| 49 'NotPoweredAdapter', | |
| 50 'EmptyAdapter', | |
| 51 'FailStartDiscoveryAdapter', | |
| 52 'GlucoseHeartRateAdapter', | |
| 53 'UnicodeDeviceAdapter', | |
| 54 'MissingServiceHeartRateAdapter', | |
| 55 'MissingCharacteristicHeartRateAdapter', | |
| 56 'HeartRateAdapter', | |
| 57 'TwoHeartRateServicesAdapter', | |
| 58 'DisconnectingHeartRateAdapter', | |
| 59 'BlacklistTestAdapter', | |
| 60 'FailingConnectionsAdapter', | |
| 61 'FailingGATTOperationsAdapter', | |
| 62 'DelayedServicesDiscoveryAdapter', | |
| 63 ] | |
| 64 | |
| 65 | |
| 66 def _ToJsStr(s): | |
| 67 return u'\'{}\''.format(s) | |
| 68 | |
| 69 | |
| 70 def GetFakeAdapter(): | |
| 71 return _ToJsStr(random.choice(FAKE_ADAPTERS)) | |
| 72 | |
| 73 | |
| 74 def _GetFuzzedJsString(s): | |
| 75 """Returns a fuzzed string based on |s|. | |
| 76 | |
| 77 Args: | |
| 78 s: The base string to fuzz. | |
| 79 Returns: | |
| 80 A single line string surrounded by quotes. | |
| 81 """ | |
| 82 while True: | |
| 83 fuzzed_string = fuzzy_types.FuzzyString(s) | |
| 84 try: | |
| 85 fuzzed_string = fuzzed_string.decode('utf8') | |
| 86 except UnicodeDecodeError: | |
| 87 print 'Can\'t decode fuzzed string. Trying again.' | |
| 88 else: | |
| 89 fuzzed_string = '\\n'.join(fuzzed_string.split()) | |
| 90 fuzzed_string = fuzzed_string.replace('\'', r'\'') | |
| 91 return _ToJsStr(fuzzed_string) | |
| 92 | |
| 93 | |
| 94 def GetServiceUUIDFromFakes(): | |
| 95 """Returns a random service string from the list of fake services.""" | |
| 96 return _ToJsStr(random.choice(FAKE_SERVICES)) | |
| 97 | |
| 98 | |
| 99 def GetValidServiceAlias(): | |
| 100 """Returns a valid service alias from the list of services aliases.""" | |
| 101 return _ToJsStr(random.choice(gatt_aliases.SERVICES)) | |
| 102 | |
| 103 | |
| 104 def GetRandomUUID(): | |
| 105 """Returns a random UUID, a random number or a fuzzed uuid or alias.""" | |
| 106 roll = random.random() | |
|
ortuno
2016/07/21 21:35:24
Done.
| |
| 107 if roll < 1 / 3: | |
| 108 # Random UUID | |
| 109 return _ToJsStr(uuid.uuid4()) | |
| 110 elif roll < 2 / 3: | |
| 111 # Random number | |
| 112 return utils.UniformExpoInteger(0, sys.maxsize.bit_length() + 1) | |
| 113 else: | |
| 114 # Fuzzed UUID or alias | |
| 115 if random.getrandbits(1): | |
| 116 random_uuid = str(uuid.uuid4()) | |
| 117 return _GetFuzzedJsString(random_uuid) | |
| 118 else: | |
| 119 alias = random.choice(gatt_aliases.SERVICES) | |
| 120 return _GetFuzzedJsString(alias) | |
| 121 | |
| 122 | |
| 123 def GetServiceUUID(): | |
| 124 """Generates a random Service UUID from a set of functions. | |
| 125 | |
| 126 See GetServiceUUIDFromFakes(), GetValidServiceAlias() and GetRandomUUID() | |
| 127 for the different values this function can return. | |
| 128 | |
| 129 This function weights GetServiceUUIDFromFakes() more heavily to increase the | |
| 130 probability of generating test pages that can interact with the fake | |
| 131 adapters. | |
| 16 | 132 |
| 17 Returns: | 133 Returns: |
| 18 A string representating a valid UUID according to: | 134 A string or a number that can be used as a Service UUID by the Web |
| 19 https://webbluetoothcg.github.io/web-bluetooth/#valid-uuid | 135 Bluetooth API. |
| 20 """ | 136 """ |
| 21 | 137 roll = random.random() |
| 22 return '\'{:08x}-{:04x}-{:04x}-{:04x}-{:012x}\''.format( | 138 if roll < 0.8: |
| 23 random.getrandbits(32), | 139 return GetServiceUUIDFromFakes() |
| 24 random.getrandbits(16), | 140 elif roll < 0.9: |
| 25 random.getrandbits(16), | 141 return GetValidServiceAlias() |
| 26 random.getrandbits(16), | 142 else: |
| 27 random.getrandbits(48)) | 143 return GetRandomUUID() |
| 28 | 144 |
| 29 | 145 |
| 30 def GetRequestDeviceOptions(): | 146 def GetRequestDeviceOptions(): |
| 31 """Returns an object used by navigator.bluetooth.requestDevice.""" | 147 """Returns an object used by navigator.bluetooth.requestDevice.""" |
| 32 # TODO(ortuno): Randomize the members, number of filters, services, etc. | 148 # TODO(ortuno): Randomize the members, number of filters, services, etc. |
| 33 | 149 |
| 34 return '{filters: [{services: [ %s ]}]}' % GetValidUUIDString() | 150 return '{filters: [{services: [ %s ]}]}' % GetServiceUUID() |
| OLD | NEW |