From bca6dc2250bdda85a77d00466f3df06aec64e56c Mon Sep 17 00:00:00 2001 From: Phellippe Lima Date: Fri, 17 May 2024 15:56:19 +0100 Subject: [PATCH] CP-2063 - address comments and adds list example --- credentials/test/test_credentials_api.py | 62 ++--- streaming/test/test_streaming_api.py | 321 +++++++++++++++++++++++ 2 files changed, 352 insertions(+), 31 deletions(-) create mode 100644 streaming/test/test_streaming_api.py diff --git a/credentials/test/test_credentials_api.py b/credentials/test/test_credentials_api.py index 30ef4681..f2046c0f 100644 --- a/credentials/test/test_credentials_api.py +++ b/credentials/test/test_credentials_api.py @@ -5,7 +5,7 @@ Manage credentials for transaction tests using the Credentials API. The following permissions are required to access Credentials API endpoints: * `Settings Tests Read` for read operations. * `Settings Tests Update` for write operations. * `View sensitive data in web transaction scripts` to view the encrypted value property of credentials. * `Settings Tests Create Transaction (Tx) Tests` to create credentials. For more information about credentials, see [Working With Secure Credentials](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/getting-started/working-with-secure-credentials). - The version of the OpenAPI document: 7.0.0 + The version of the OpenAPI document: 7.0.4 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. @@ -37,15 +37,15 @@ class TestCredentialsApi(unittest.TestCase): "value" : "Example Credential 1 Password" }""" - loaded_json = json.loads(request_body_json) - model_from_constructor = credentials.models.CredentialRequest(**loaded_json) - self.recursive_assert_no_extra_fields(model_from_constructor) + request_loaded_json = json.loads(request_body_json) + request_from_constructor = credentials.models.CredentialRequest(**request_loaded_json) + self.recursive_assert_no_extra_fields(request_from_constructor) request_from_json = credentials.models.CredentialRequest.from_json(request_body_json) self.assertIsNotNone(request_from_json) - self.assertCountEqual(model_from_constructor.model_fields_set, + self.assertCountEqual(request_from_constructor.model_fields_set, request_from_json.model_fields_set, - "Model from constructor fields do not match model from json fields") + "Request model from constructor fields do not match model from json fields") response_body_json = """ { @@ -66,15 +66,15 @@ class TestCredentialsApi(unittest.TestCase): "id" : "3247" }""" - loaded_json = json.loads(response_body_json) - model_from_constructor = credentials.models.CredentialWithoutValue(**loaded_json) - self.recursive_assert_no_extra_fields(model_from_constructor) + response_loaded_json = json.loads(response_body_json) + response_from_constructor = credentials.models.CredentialWithoutValue(**response_loaded_json) + self.recursive_assert_no_extra_fields(response_from_constructor) response_from_json = credentials.models.CredentialWithoutValue.from_json(response_body_json) self.assertIsNotNone(response_from_json) - self.assertCountEqual(model_from_constructor.model_fields_set, + self.assertCountEqual(response_from_constructor.model_fields_set, response_from_json.model_fields_set, - "Model from constructor fields do not match model from json fields") + "Response model from constructor fields do not match model from json fields") def test_delete_transaction_tests_credential_models_validation(self) -> None: """Test case for delete_transaction_tests_credential request a nd response models""" @@ -102,15 +102,15 @@ class TestCredentialsApi(unittest.TestCase): "value" : "rwhR12uDm1Im47p5IVXgzz4ORgC7m48ajzzeWVUt" }""" - loaded_json = json.loads(response_body_json) - model_from_constructor = credentials.models.Credential(**loaded_json) - self.recursive_assert_no_extra_fields(model_from_constructor) + response_loaded_json = json.loads(response_body_json) + response_from_constructor = credentials.models.Credential(**response_loaded_json) + self.recursive_assert_no_extra_fields(response_from_constructor) response_from_json = credentials.models.Credential.from_json(response_body_json) self.assertIsNotNone(response_from_json) - self.assertCountEqual(model_from_constructor.model_fields_set, + self.assertCountEqual(response_from_constructor.model_fields_set, response_from_json.model_fields_set, - "Model from constructor fields do not match model from json fields") + "Response model from constructor fields do not match model from json fields") def test_get_transaction_tests_credentials_list_models_validation(self) -> None: """Test case for get_transaction_tests_credentials_list request a nd response models""" @@ -164,15 +164,15 @@ class TestCredentialsApi(unittest.TestCase): } }""" - loaded_json = json.loads(response_body_json) - model_from_constructor = credentials.models.Credentials(**loaded_json) - self.recursive_assert_no_extra_fields(model_from_constructor) + response_loaded_json = json.loads(response_body_json) + response_from_constructor = credentials.models.Credentials(**response_loaded_json) + self.recursive_assert_no_extra_fields(response_from_constructor) response_from_json = credentials.models.Credentials.from_json(response_body_json) self.assertIsNotNone(response_from_json) - self.assertCountEqual(model_from_constructor.model_fields_set, + self.assertCountEqual(response_from_constructor.model_fields_set, response_from_json.model_fields_set, - "Model from constructor fields do not match model from json fields") + "Response model from constructor fields do not match model from json fields") def test_update_transaction_tests_credential_models_validation(self) -> None: """Test case for update_transaction_tests_credential request a nd response models""" @@ -182,15 +182,15 @@ class TestCredentialsApi(unittest.TestCase): "value" : "Example Credential 1 Password" }""" - loaded_json = json.loads(request_body_json) - model_from_constructor = credentials.models.CredentialRequest(**loaded_json) - self.recursive_assert_no_extra_fields(model_from_constructor) + request_loaded_json = json.loads(request_body_json) + request_from_constructor = credentials.models.CredentialRequest(**request_loaded_json) + self.recursive_assert_no_extra_fields(request_from_constructor) request_from_json = credentials.models.CredentialRequest.from_json(request_body_json) self.assertIsNotNone(request_from_json) - self.assertCountEqual(model_from_constructor.model_fields_set, + self.assertCountEqual(request_from_constructor.model_fields_set, request_from_json.model_fields_set, - "Model from constructor fields do not match model from json fields") + "Request model from constructor fields do not match model from json fields") response_body_json = """ { @@ -210,15 +210,15 @@ class TestCredentialsApi(unittest.TestCase): "id" : "3247" }""" - loaded_json = json.loads(response_body_json) - model_from_constructor = credentials.models.CredentialWithoutValue(**loaded_json) - self.recursive_assert_no_extra_fields(model_from_constructor) + response_loaded_json = json.loads(response_body_json) + response_from_constructor = credentials.models.CredentialWithoutValue(**response_loaded_json) + self.recursive_assert_no_extra_fields(response_from_constructor) response_from_json = credentials.models.CredentialWithoutValue.from_json(response_body_json) self.assertIsNotNone(response_from_json) - self.assertCountEqual(model_from_constructor.model_fields_set, + self.assertCountEqual(response_from_constructor.model_fields_set, response_from_json.model_fields_set, - "Model from constructor fields do not match model from json fields") + "Response model from constructor fields do not match model from json fields") def recursive_assert_no_extra_fields(self, model: BaseModel): self.assertIsNotNone(model) diff --git a/streaming/test/test_streaming_api.py b/streaming/test/test_streaming_api.py new file mode 100644 index 00000000..418cd8f4 --- /dev/null +++ b/streaming/test/test_streaming_api.py @@ -0,0 +1,321 @@ +# coding: utf-8 + +""" + ThousandEyes for OpenTelemetry API + + ThousandEyes for OpenTelemetry provides machine-to-machine integration between ThousandEyes and its customers. It allows you to export ThousandEyes telemetry data in OTel format, which is widely used in the industry. With ThousandEyes for OTel, you can leverage frameworks widely used in the observability domain - such as Splunk, Grafana, and Honeycomb - to capture and analyze ThousandEyes data. Any client that supports OTel can use ThousandEyes for OpenTelemetry. ThousandEyes for OTel is made up of the following components: * Data streaming APIs that you can use to configure and enable your ThousandEyes tests with OTel-compatible streams, in particular to configure how ThousandEyes telemetry data is exported to client integrations. * A set of streaming pipelines called _collectors_ that actively fetch ThousandEyes network test data, enrich the data with some additional detail, filter, and push the data to the customer-configured endpoints, depending on what you configure via the public APIs. * Third-party OTel collectors that receive, transform, filter, and export different metrics to client applications such as AppD, or any other OTel-capable client configuration. For more information about ThousandEyes for OpenTelemetry, see the [documentation](https://docs.thousandeyes.com/product-documentation/api/opentelemetry). + + The version of the OpenAPI document: 7.0.4 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import json +import unittest +import streaming.models + +from streaming.api.streaming_api import StreamingApi +from pydantic import BaseModel + + +class TestStreamingApi(unittest.TestCase): + """StreamingApi unit test stubs""" + + def setUp(self) -> None: + self.api = StreamingApi() + + def tearDown(self) -> None: + pass + + def test_create_stream_models_validation(self) -> None: + """Test case for create_stream request a nd response models""" + request_body_json = """ + { + "endpointType" : "grpc", + "streamEndpointUrl" : "https://api.thousandeyes.otel-collector", + "tagMatch" : [ { + "objectType" : "test", + "key" : "keyA", + "value" : "valueA" + }, { + "objectType" : "test", + "key" : "keyB", + "value" : "valueB" + } ], + "type" : "opentelemetry", + "customHeaders" : { + "Authorization" : "*****", + "Content-Type" : "*****" + }, + "enabled" : true + }""" + + request_loaded_json = json.loads(request_body_json) + request_from_constructor = streaming.models.Stream(**request_loaded_json) + self.recursive_assert_no_extra_fields(request_from_constructor) + + request_from_json = streaming.models.Stream.from_json(request_body_json) + self.assertIsNotNone(request_from_json) + self.assertCountEqual(request_from_constructor.model_fields_set, + request_from_json.model_fields_set, + "Request model from constructor fields do not match model from json fields") + + response_body_json = """ + { + "endpointType" : "grpc", + "_links" : { + "self" : { + "href" : "https://api.thousandeyes.com/v7/streams/575766da-9664-4e85-94fe-facbe1154799" + } + }, + "streamEndpointUrl" : "https://api.thousandeyes.otel-collector", + "tagMatch" : [ { + "objectType" : "test", + "key" : "keyA", + "value" : "valueA" + }, { + "objectType" : "test", + "key" : "keyB", + "value" : "valueB" + } ], + "id" : "342ieu09", + "type" : "opentelemetry", + "auditOperation" : { + "createdDate" : 1679677853573, + "createdBy" : 3962 + }, + "enabled" : true, + "customHeaders" : { + "Authorization" : "*****", + "Content-Type" : "*****" + } + }""" + + response_loaded_json = json.loads(response_body_json) + response_from_constructor = streaming.models.CreateStreamResponse(**response_loaded_json) + self.recursive_assert_no_extra_fields(response_from_constructor) + + response_from_json = streaming.models.CreateStreamResponse.from_json(response_body_json) + self.assertIsNotNone(response_from_json) + self.assertCountEqual(response_from_constructor.model_fields_set, + response_from_json.model_fields_set, + "Response model from constructor fields do not match model from json fields") + + def test_delete_stream_models_validation(self) -> None: + """Test case for delete_stream request a nd response models""" + + + def test_get_stream_models_validation(self) -> None: + """Test case for get_stream request a nd response models""" + + response_body_json = """ + { + "endpointType" : "grpc", + "_links" : { + "self" : { + "href" : "https://api.thousandeyes.com/v7/streams/575766da-9664-4e85-94fe-facbe1154799" + } + }, + "streamEndpointUrl" : "https://api.thousandeyes.otel-collector", + "tagMatch" : [ { + "objectType" : "test", + "key" : "keyA", + "value" : "valueA" + }, { + "objectType" : "test", + "key" : "keyB", + "value" : "valueB" + } ], + "id" : "342ieu09", + "type" : "opentelemetry", + "auditOperation" : { + "createdDate" : 1679677853573, + "updatedBy" : 3962, + "createdBy" : 3962, + "updatedDate" : 1679677853573 + }, + "enabled" : true, + "customHeaders" : { + "Authorization" : "*****", + "Content-Type" : "*****" + } + }""" + + response_loaded_json = json.loads(response_body_json) + response_from_constructor = streaming.models.GetStreamResponse(**response_loaded_json) + self.recursive_assert_no_extra_fields(response_from_constructor) + + response_from_json = streaming.models.GetStreamResponse.from_json(response_body_json) + self.assertIsNotNone(response_from_json) + self.assertCountEqual(response_from_constructor.model_fields_set, + response_from_json.model_fields_set, + "Response model from constructor fields do not match model from json fields") + + def test_get_streams_models_validation(self) -> None: + """Test case for get_streams request a nd response models""" + + response_body_json = """ + [ { + "endpointType" : "grpc", + "_links" : { + "self" : { + "href" : "https://api.thousandeyes.com/v7/streams/575766da-9664-4e85-94fe-facbe1154799" + } + }, + "streamEndpointUrl" : "https://api.thousandeyes.otel-collector", + "tagMatch" : [ { + "objectType" : "test", + "key" : "keyA", + "value" : "valueA" + }, { + "objectType" : "test", + "key" : "keyB", + "value" : "valueB" + } ], + "id" : "342ieu09", + "type" : "opentelemetry", + "auditOperation" : { + "createdDate" : 1679677853573, + "updatedBy" : 3962, + "createdBy" : 3962, + "updatedDate" : 1679677853573 + }, + "enabled" : true, + "customHeaders" : { + "Authorization" : "*****", + "Content-Type" : "*****" + } + }, { + "endpointType" : "grpc", + "_links" : { + "self" : { + "href" : "https://api.thousandeyes.com/v7/streams/575766da-9664-4e85-94fe-facbe1154799" + } + }, + "streamEndpointUrl" : "https://api.thousandeyes.otel-collector", + "tagMatch" : [ { + "objectType" : "test", + "key" : "keyA", + "value" : "valueA" + }, { + "objectType" : "test", + "key" : "keyB", + "value" : "valueB" + } ], + "id" : "342ieu09", + "type" : "opentelemetry", + "auditOperation" : { + "createdDate" : 1679677853573, + "updatedBy" : 3962, + "createdBy" : 3962, + "updatedDate" : 1679677853573 + }, + "enabled" : true, + "customHeaders" : { + "Authorization" : "*****", + "Content-Type" : "*****" + } + } ]""" + + response_loaded_json = json.loads(response_body_json) + response_from_constructor = [streaming.models.GetStreamResponse(**value) for value in response_loaded_json] + for element in response_from_constructor: + self.recursive_assert_no_extra_fields(element) + + response_from_dict = [streaming.models.GetStreamResponse.from_dict(value) for value in response_loaded_json] + self.assertCountEqual(response_from_constructor, response_from_dict) + for index, element in enumerate(response_from_dict): + self.assertIsNotNone(element) + self.assertCountEqual(response_from_constructor[index], element, + "Response model from constructor fields do not match model from json fields") + + def test_put_stream_models_validation(self) -> None: + """Test case for put_stream request a nd response models""" + request_body_json = """ + { + "tagMatch" : [ { + "objectType" : "test", + "key" : "keyA", + "value" : "valueA" + }, { + "objectType" : "test", + "key" : "keyB", + "value" : "valueB" + } ], + "customHeaders" : { + "Authorization" : "*****", + "Content-Type" : "*****" + }, + "enabled" : true + }""" + + request_loaded_json = json.loads(request_body_json) + request_from_constructor = streaming.models.PutStream(**request_loaded_json) + self.recursive_assert_no_extra_fields(request_from_constructor) + + request_from_json = streaming.models.PutStream.from_json(request_body_json) + self.assertIsNotNone(request_from_json) + self.assertCountEqual(request_from_constructor.model_fields_set, + request_from_json.model_fields_set, + "Request model from constructor fields do not match model from json fields") + + response_body_json = """ + { + "endpointType" : "grpc", + "_links" : { + "self" : { + "href" : "https://api.thousandeyes.com/v7/streams/575766da-9664-4e85-94fe-facbe1154799" + } + }, + "streamEndpointUrl" : "https://api.thousandeyes.otel-collector", + "tagMatch" : [ { + "objectType" : "test", + "key" : "keyA", + "value" : "valueA" + }, { + "objectType" : "test", + "key" : "keyB", + "value" : "valueB" + } ], + "id" : "342ieu09", + "type" : "opentelemetry", + "auditOperation" : { + "createdDate" : 1679677853573, + "updatedBy" : 3962, + "createdBy" : 3962, + "updatedDate" : 1679677853573 + }, + "enabled" : true, + "customHeaders" : { + "Authorization" : "*****", + "Content-Type" : "*****" + } + }""" + + response_loaded_json = json.loads(response_body_json) + response_from_constructor = streaming.models.GetStreamResponse(**response_loaded_json) + self.recursive_assert_no_extra_fields(response_from_constructor) + + response_from_json = streaming.models.GetStreamResponse.from_json(response_body_json) + self.assertIsNotNone(response_from_json) + self.assertCountEqual(response_from_constructor.model_fields_set, + response_from_json.model_fields_set, + "Response model from constructor fields do not match model from json fields") + + def recursive_assert_no_extra_fields(self, model: BaseModel): + self.assertIsNotNone(model) + self.assertGreater(model.model_fields_set.__len__(), 0) + self.assertEquals(model.model_extra.__len__(), 0, + 'model {0}.{1} has unmapped extra fields {2}' + .format(model.__class__.__module__, model.__class__.__name__, + model.model_extra)) + for f in model.model_fields_set: + field = model.__dict__.get(f) + if isinstance(field, BaseModel): + self.recursive_assert_no_extra_fields(field) + + +if __name__ == '__main__': + unittest.main()