Merge "Adds placement trait api calls"
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 0000000..77d0b38
--- /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 216ac08..f272cbf 100644
--- a/tempest/lib/services/placement/placement_client.py
+++ b/tempest/lib/services/placement/placement_client.py
@@ -49,3 +49,39 @@
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 1396a85..bb57bb0 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 @@
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")