diff options
-rw-r--r-- | tempest_lib/common/rest_client.py | 34 | ||||
-rw-r--r-- | tempest_lib/common/utils/data_utils.py | 69 | ||||
-rw-r--r-- | tempest_lib/tests/fake_auth_provider.py | 13 | ||||
-rw-r--r-- | tempest_lib/tests/test_rest_client.py | 56 | ||||
-rw-r--r-- | tempest_lib/tests/test_tempest_lib.py | 2 | ||||
-rw-r--r-- | test-requirements.txt | 3 | ||||
-rw-r--r-- | tox.ini | 5 |
7 files changed, 154 insertions, 28 deletions
diff --git a/tempest_lib/common/rest_client.py b/tempest_lib/common/rest_client.py index b9691a0..7988061 100644 --- a/tempest_lib/common/rest_client.py +++ b/tempest_lib/common/rest_client.py @@ -270,8 +270,8 @@ class RestClient(object): """Send a HTTP DELETE request using keystone service catalog and auth :param str url: the relative url to send the post request to - :param dict body: the request body :param dict headers: The headers to use for the request + :param dict body: the request body :param dict extra_headers: If the headers returned by the get_headers() method are to be used but additional headers are needed in the request pass them in as a @@ -554,16 +554,16 @@ class RestClient(object): headers and the catalog to determine the endpoint to use for the baseurl to send the request to. Additionally - When a response is recieved it will check it to see if an error - response was recieved. If it was an exception will be raised to enable + When a response is received it will check it to see if an error + response was received. If it was an exception will be raised to enable it to be handled quickly. This method will also handle rate-limiting, if a 413 response code is - recieved it will retry the request after waiting the 'retry-after' + received it will retry the request after waiting the 'retry-after' duration from the header. - :param str url: Relative url to send the request to :param str method: The HTTP verb to use for the request + :param str url: Relative url to send the request to :param dict extra_headers: If specified without the headers kwarg the headers sent with the request will be the combination from the get_headers() method @@ -578,23 +578,23 @@ class RestClient(object): and the second the response body :raises InvalidContentType: If the content-type of the response isn't an expect type or a 415 response code is - recieved - :raises Unauthorized: If a 401 response code is recieved - :raises Forbidden: If a 403 response code is recieved - :raises NotFound: If a 404 response code is recieved - :raises BadRequest: If a 400 response code is recieved - :raises Conflict: If a 409 response code is recieved - :raies Overlimit: If a 413 response code is recieved and over_limit is + received + :raises Unauthorized: If a 401 response code is received + :raises Forbidden: If a 403 response code is received + :raises NotFound: If a 404 response code is received + :raises BadRequest: If a 400 response code is received + :raises Conflict: If a 409 response code is received + :raises OverLimit: If a 413 response code is received and over_limit is not in the response body - :raises RateLimitExceeded: If a 413 response code is recieved and + :raises RateLimitExceeded: If a 413 response code is received and over_limit is in the response body - :raises UnprocessableEntity: If a 422 response code is recieved + :raises UnprocessableEntity: If a 422 response code is received :raises InvalidHTTPResponseBody: The response body wasn't valid JSON and couldn't be parsed - :raises NotImplemented: If a 501 response code is recieved - :raises ServerFault: If a 500 response code is recieved + :raises NotImplemented: If a 501 response code is received + :raises ServerFault: If a 500 response code is received :raises UnexpectedResponseCode: If a response code above 400 is - recieved and it doesn't fall into any + received and it doesn't fall into any of the handled checks """ # if extra_headers is True diff --git a/tempest_lib/common/utils/data_utils.py b/tempest_lib/common/utils/data_utils.py index dc799fe..c900d4d 100644 --- a/tempest_lib/common/utils/data_utils.py +++ b/tempest_lib/common/utils/data_utils.py @@ -20,14 +20,33 @@ import uuid def rand_uuid(): + """Generate a random UUID string + + :return: a random UUID (e.g. '1dc12c7d-60eb-4b61-a7a2-17cf210155b6') + :rtype: string + """ return str(uuid.uuid4()) def rand_uuid_hex(): + """Generate a random UUID hex string + + :return: a random UUID (e.g. '0b98cf96d90447bda4b46f31aeb1508c') + :rtype: string + """ return uuid.uuid4().hex def rand_name(name='', prefix=None): + """Generate a random name that inclues a random number + + :param str name: The name that you want to include + :param str prefix: The prefix that you want to include + :return: a random name. The format is + '<prefix>-<random number>-<name>-<random number>'. + (e.g. 'prefixfoo-1308607012-namebar-154876201') + :rtype: string + """ randbits = str(random.randint(1, 0x7fffffff)) rand_name = randbits if name: @@ -38,16 +57,33 @@ def rand_name(name='', prefix=None): def rand_url(): + """Generate a random url that inclues a random number + + :return: a random url. The format is 'https://url-<random number>.com'. + (e.g. 'https://url-154876201.com') + :rtype: string + """ randbits = str(random.randint(1, 0x7fffffff)) return 'https://url-' + randbits + '.com' def rand_int_id(start=0, end=0x7fffffff): + """Generate a random integer value + + :param int start: The value that you expect to start here + :param int end: The value that you expect to end here + :return: a random integer value + :rtype: int + """ return random.randint(start, end) def rand_mac_address(): - """Generate an Ethernet MAC address.""" + """Generate an Ethernet MAC address + + :return: an random Ethernet MAC address + :rtype: string + """ # NOTE(vish): We would prefer to use 0xfe here to ensure that linux # bridge mac addresses don't change, but it appears to # conflict with libvirt, so we use the next highest octet @@ -62,14 +98,27 @@ def rand_mac_address(): def parse_image_id(image_ref): - """Return the image id from a given image ref.""" + """Return the image id from a given image ref + + This function just returns the last word of the given image ref string + splitting with '/'. + :param str image_ref: a string that includes the image id + :return: the image id string + :rtype: string + """ return image_ref.rsplit('/')[-1] def arbitrary_string(size=4, base_text=None): """Return size characters from base_text - Repeating the base_text infinitely if needed. + This generates a string with an arbitrary number of characters, generated + by looping the base_text string. If the size is smaller than the size of + base_text, returning string is shrinked to the size. + :param int size: a returning charactors size + :param str base_text: a string you want to repeat + :return: size string + :rtype: string """ if not base_text: base_text = 'test' @@ -77,12 +126,24 @@ def arbitrary_string(size=4, base_text=None): def random_bytes(size=1024): - """Return size randomly selected bytes as a string.""" + """Return size randomly selected bytes as a string + + :param int size: a returning bytes size + :return: size randomly bytes + :rtype: string + """ return ''.join([chr(random.randint(0, 255)) for i in range(size)]) def get_ipv6_addr_by_EUI64(cidr, mac): + """Generate a IPv6 addr by EUI-64 with CIDR and MAC + + :param str cidr: a IPv6 CIDR + :param str mac: a MAC address + :return: an IPv6 Address + :rtype: netaddr.IPAddress + """ # Check if the prefix is IPv4 address is_ipv4 = netaddr.valid_ipv4(cidr) if is_ipv4: diff --git a/tempest_lib/tests/fake_auth_provider.py b/tempest_lib/tests/fake_auth_provider.py index bc68d26..280df66 100644 --- a/tempest_lib/tests/fake_auth_provider.py +++ b/tempest_lib/tests/fake_auth_provider.py @@ -16,5 +16,18 @@ class FakeAuthProvider(object): + def __init__(self, creds_dict={}): + self.credentials = FakeCredentials(creds_dict) + def auth_request(self, method, url, headers=None, body=None, filters=None): return url, headers, body + + def base_url(self, filters, auth_data=None): + return "https://example.com" + + +class FakeCredentials(object): + + def __init__(self, creds_dict): + for key in creds_dict.keys(): + setattr(self, key, creds_dict[key]) diff --git a/tempest_lib/tests/test_rest_client.py b/tempest_lib/tests/test_rest_client.py index d585b88..373ef31 100644 --- a/tempest_lib/tests/test_rest_client.py +++ b/tempest_lib/tests/test_rest_client.py @@ -31,8 +31,9 @@ class BaseRestClientTestClass(base.TestCase): def setUp(self): super(BaseRestClientTestClass, self).setUp() + self.fake_auth_provider = fake_auth_provider.FakeAuthProvider() self.rest_client = rest_client.RestClient( - fake_auth_provider.FakeAuthProvider(), None, None) + self.fake_auth_provider, None, None) self.stubs.Set(httplib2.Http, 'request', self.fake_http.request) self.useFixture(mockpatch.PatchObject(self.rest_client, '_log_request')) @@ -437,6 +438,59 @@ class TestRestClientUtils(BaseRestClientTestClass): self.rest_client.wait_for_resource_deletion, '1234') + def test_get_versions(self): + self.rest_client._parse_resp = lambda x: [{'id': 'v1'}, {'id': 'v2'}] + actual_resp, actual_versions = self.rest_client.get_versions() + self.assertEqual(['v1', 'v2'], list(actual_versions)) + + def test__str__(self): + def get_token(): + return "deadbeef" + + self.fake_auth_provider.get_token = get_token + self.assertIsNotNone(str(self.rest_client)) + + +class TestProperties(BaseRestClientTestClass): + + def setUp(self): + self.fake_http = fake_http.fake_httplib2() + super(TestProperties, self).setUp() + creds_dict = { + 'username': 'test-user', + 'user_id': 'test-user_id', + 'tenant_name': 'test-tenant_name', + 'tenant_id': 'test-tenant_id', + 'password': 'test-password' + } + self.rest_client = rest_client.RestClient( + fake_auth_provider.FakeAuthProvider(creds_dict=creds_dict), + None, None) + + def test_properties(self): + self.assertEqual('test-user', self.rest_client.user) + self.assertEqual('test-user_id', self.rest_client.user_id) + self.assertEqual('test-tenant_name', self.rest_client.tenant_name) + self.assertEqual('test-tenant_id', self.rest_client.tenant_id) + self.assertEqual('test-password', self.rest_client.password) + + self.rest_client.api_version = 'v1' + expected = {'api_version': 'v1', + 'endpoint_type': 'publicURL', + 'region': None, + 'service': None, + 'skip_path': True} + self.rest_client.skip_path() + self.assertEqual(expected, self.rest_client.filters) + + self.rest_client.reset_path() + self.rest_client.api_version = 'v1' + expected = {'api_version': 'v1', + 'endpoint_type': 'publicURL', + 'region': None, + 'service': None} + self.assertEqual(expected, self.rest_client.filters) + class TestExpectedSuccess(BaseRestClientTestClass): diff --git a/tempest_lib/tests/test_tempest_lib.py b/tempest_lib/tests/test_tempest_lib.py index 8f75057..76d74a6 100644 --- a/tempest_lib/tests/test_tempest_lib.py +++ b/tempest_lib/tests/test_tempest_lib.py @@ -25,4 +25,4 @@ from tempest_lib.tests import base class TestTempest_lib(base.TestCase): def test_something(self): - pass
\ No newline at end of file + pass diff --git a/test-requirements.txt b/test-requirements.txt index 0561abf..158a921 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,7 +1,8 @@ # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -hacking>=0.9.2,<0.10 +hacking<0.11,>=0.10.0 + coverage>=3.6 discover @@ -26,13 +26,10 @@ commands = python setup.py test --coverage --coverage-package-name='tempest_lib' commands = python setup.py build_sphinx [flake8] -# H803 skipped on purpose per list discussion. # E125 skipped as it is invalid PEP-8. -# H402 skipped because some docstrings aren't sentences # E123 skipped because it is ignored by default in the default pep8 # E129 skipped because it is too limiting when combined with other rules -# H305 skipped because it is inconsistent between python versions show-source = True -ignore = E125,H803,H402,E123,E129,H305 +ignore = E125,E123,E129 builtins = _ exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build |