From 3c3985c2ec5ad3a25de0fb644cd66cef71511b6f Mon Sep 17 00:00:00 2001 From: Amit Uniyal Date: Thu, 20 Jun 2024 05:48:44 -0400 Subject: [PATCH] Adds placement trait api calls Change-Id: I0c4523c6916821781c3a67b01ed2e0091407734e --- ...ent-traits-api-calls-087061f5455f0b12.yaml | 4 + .../services/placement/placement_client.py | 36 +++++++++ .../placement/test_placement_client.py | 74 +++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 releasenotes/notes/add-placement-traits-api-calls-087061f5455f0b12.yaml diff --git a/releasenotes/notes/add-placement-traits-api-calls-087061f5455f0b12.yaml b/releasenotes/notes/add-placement-traits-api-calls-087061f5455f0b12.yaml new file mode 100644 index 0000000000..77d0b38c6b --- /dev/null +++ b/releasenotes/notes/add-placement-traits-api-calls-087061f5455f0b12.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Adds API calls for traits in PlacementClient. diff --git a/tempest/lib/services/placement/placement_client.py b/tempest/lib/services/placement/placement_client.py index 216ac08c25..f272cbf8f2 100644 --- a/tempest/lib/services/placement/placement_client.py +++ b/tempest/lib/services/placement/placement_client.py @@ -49,3 +49,39 @@ class PlacementClient(base_placement_client.BasePlacementClient): self.expected_success(200, resp.status) body = json.loads(body) return rest_client.ResponseBody(resp, body) + + def list_traits(self, **params): + """API ref https://docs.openstack.org/api-ref/placement/#traits + """ + url = "/traits" + if params: + url += '?%s' % urllib.urlencode(params) + resp, body = self.get(url) + self.expected_success(200, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) + + def show_trait(self, name, **params): + url = "/traits" + if params: + url += '?%s' % urllib.urlencode(params) + resp, body = self.get(url) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + url = f"{url}/{name}" + resp, _ = self.get(url) + self.expected_success(204, resp.status) + return resp.status + + def create_trait(self, name, **params): + url = f"/traits/{name}" + json_body = json.dumps(params) + resp, _ = self.put(url, body=json_body) + return resp.status + + def delete_trait(self, name): + url = f"/traits/{name}" + resp, _ = self.delete(url) + self.expected_success(204, resp.status) + return resp.status diff --git a/tempest/tests/lib/services/placement/test_placement_client.py b/tempest/tests/lib/services/placement/test_placement_client.py index 1396a85aac..bb57bb0634 100644 --- a/tempest/tests/lib/services/placement/test_placement_client.py +++ b/tempest/tests/lib/services/placement/test_placement_client.py @@ -87,3 +87,77 @@ class TestPlacementClient(base.BaseServiceTest): def test_list_allocations_with_bytes_body(self): self._test_list_allocations(bytes_body=True) + + FAKE_ALL_TRAITS = { + "traits": [ + "CUSTOM_HW_FPGA_CLASS1", + "CUSTOM_HW_FPGA_CLASS2", + "CUSTOM_HW_FPGA_CLASS3" + ] + } + + FAKE_ASSOCIATED_TRAITS = { + "traits": [ + "CUSTOM_HW_FPGA_CLASS1", + "CUSTOM_HW_FPGA_CLASS2" + ] + } + + def test_list_traits(self): + self.check_service_client_function( + self.client.list_traits, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_ALL_TRAITS) + + self.check_service_client_function( + self.client.list_traits, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_ASSOCIATED_TRAITS, + **{ + "associated": "true" + }) + + self.check_service_client_function( + self.client.list_traits, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_ALL_TRAITS, + **{ + "associated": "true", + "name": "startswith:CUSTOM_HW_FPGPA" + }) + + def test_show_traits(self): + self.check_service_client_function( + self.client.show_trait, + 'tempest.lib.common.rest_client.RestClient.get', + 204, status=204, + name="CUSTOM_HW_FPGA_CLASS1") + + self.check_service_client_function( + self.client.show_trait, + 'tempest.lib.common.rest_client.RestClient.get', + 404, status=404, + # trait with this name does not exists + name="CUSTOM_HW_FPGA_CLASS4") + + def test_create_traits(self): + self.check_service_client_function( + self.client.create_trait, + 'tempest.lib.common.rest_client.RestClient.put', + 204, status=204, + # try to create trait with existing name + name="CUSTOM_HW_FPGA_CLASS1") + + self.check_service_client_function( + self.client.create_trait, + 'tempest.lib.common.rest_client.RestClient.put', + 201, status=201, + # create new trait + name="CUSTOM_HW_FPGA_CLASS4") + + def test_delete_traits(self): + self.check_service_client_function( + self.client.delete_trait, + 'tempest.lib.common.rest_client.RestClient.delete', + 204, status=204, + name="CUSTOM_HW_FPGA_CLASS1")