From 56d66fea548786fe73378d47858c29374d1be7a5 Mon Sep 17 00:00:00 2001 From: Thomas Pierce Date: Tue, 6 Feb 2024 17:35:13 +0000 Subject: [PATCH] Various fixes - mostly type hints and comments --- contract-tests/README.md | 8 +++++--- .../images/applications/requests/pyproject.toml | 13 +++++++++++++ .../applications/requests/requests_server.py | 15 +++++++++------ .../mock-collector/mock_collector_client.py | 4 ++-- .../images/mock-collector/pyproject.toml | 2 +- contract-tests/tests/pyproject.toml | 2 +- .../tests/test/amazon/base/contract_test_base.py | 8 ++++++++ 7 files changed, 39 insertions(+), 13 deletions(-) create mode 100644 contract-tests/images/applications/requests/pyproject.toml diff --git a/contract-tests/README.md b/contract-tests/README.md index 904f65001..b36c41e38 100644 --- a/contract-tests/README.md +++ b/contract-tests/README.md @@ -14,22 +14,24 @@ The frameworks and libraries that are tested in the contract tests should fall i * http-servers - applications meant to test http servers (e.g. Django). * http-clients - applications meant to test http clients (e.g. requests). * aws-sdk - Applications meant to test the AWS SDK (e.g. botocore). -* database-clients - Applications meant to test database clients (e.g. asycnpg). +* database-clients - Applications meant to test database clients (e.g. psychopg2). -When testing a framework, we will create a sample application. The sample applications are stored following this convention: `contract-tests/images/`. +When testing a framework, we will create a sample application. The sample applications are stored following this convention: `contract-tests/images/applications/`. # Adding tests for a new library or framework The steps to add a new test for a library or framework are: * Create a sample application. * The sample application should be created in `contract-tests/images/applications/`. + * Implement a `pyproject.toml` (to ensure code style checks run), `Dockerfile`, and `requirements.txt` file. See the `requests` application for an example of this. * Add a test class for the sample application. * The test class should be created in `contract-tests/tests/amazon/`. + * The test class should extend `contract_test_base.py` # How to run the tests locally? Pre-requirements: -* Have `docker` installed and running +* Have `docker` installed and running - verify by running the `docker` command. * Copy the `aws_opentelemetry_distro` wheel file to each application folder under `images` (e.g. to `requests`, but not `mock-collector`) From `aws-otel-python-instrumentation/contract-tests` execute: diff --git a/contract-tests/images/applications/requests/pyproject.toml b/contract-tests/images/applications/requests/pyproject.toml new file mode 100644 index 000000000..65d4b6ed4 --- /dev/null +++ b/contract-tests/images/applications/requests/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "requests-server" +description = "Simple server that relies on requests library" +version = "1.0.0" +license = "Apache-2.0" +requires-python = ">=3.8" + +dependencies = [ + "opentelemetry-distro==0.43b0", + "opentelemetry-exporter-otlp-proto-grpc==1.22.0", + "typing-extensions==4.9.0", + "requests==2.31.0" +] \ No newline at end of file diff --git a/contract-tests/images/applications/requests/requests_server.py b/contract-tests/images/applications/requests/requests_server.py index 2d5b8eb7c..af4b222b5 100644 --- a/contract-tests/images/applications/requests/requests_server.py +++ b/contract-tests/images/applications/requests/requests_server.py @@ -9,17 +9,19 @@ _PORT: int = 8080 _NETWORK_ALIAS: str = "backend" -_SUCCESS = "success" -_ERROR = "error" -_FAULT = "fault" +_SUCCESS: str = "success" +_ERROR: str = "error" +_FAULT: str = "fault" class RequestHandler(BaseHTTPRequestHandler): @override + # pylint: disable=invalid-name def do_GET(self): self.handle_request("GET") @override + # pylint: disable=invalid-name def do_POST(self): self.handle_request("POST") @@ -35,13 +37,14 @@ def handle_request(self, method: str): else: status_code = 404 else: - response: Response = request(method, "http://backend:8080/backend{}".format(self.path)) + url: str = f"http://{_NETWORK_ALIAS}:{_PORT}/{_NETWORK_ALIAS}{self.path}" + response: Response = request(method, url, timeout=20) status_code = response.status_code self.send_response_only(status_code) self.end_headers() def in_path(self, sub_path: str): - return self.path.__contains__(sub_path) + return sub_path in self.path def main() -> None: @@ -49,7 +52,7 @@ def main() -> None: request_handler_class: type = RequestHandler requests_server: ThreadingHTTPServer = ThreadingHTTPServer(server_address, request_handler_class) atexit.register(requests_server.shutdown) - server_thread = Thread(target=requests_server.serve_forever) + server_thread: Thread = Thread(target=requests_server.serve_forever) server_thread.start() print("Ready") server_thread.join() diff --git a/contract-tests/images/mock-collector/mock_collector_client.py b/contract-tests/images/mock-collector/mock_collector_client.py index 4a7c354b9..8ab616f5c 100644 --- a/contract-tests/images/mock-collector/mock_collector_client.py +++ b/contract-tests/images/mock-collector/mock_collector_client.py @@ -24,7 +24,7 @@ _logger: Logger = getLogger(__name__) _TIMEOUT_DELAY: timedelta = timedelta(seconds=20) _WAIT_INTERVAL: float = 0.1 -T = TypeVar("T") +T: TypeVar = TypeVar("T") class ResourceScopeSpan: @@ -35,7 +35,7 @@ class ResourceScopeSpan: def __init__(self, resource_spans: ResourceSpans, scope_spans: ScopeSpans, span: Span): self.resource_spans: ResourceSpans = resource_spans - self.scope_spans = scope_spans + self.scope_spans: ScopeSpans = scope_spans self.span: Span = span diff --git a/contract-tests/images/mock-collector/pyproject.toml b/contract-tests/images/mock-collector/pyproject.toml index 4112aa111..5bf08033b 100644 --- a/contract-tests/images/mock-collector/pyproject.toml +++ b/contract-tests/images/mock-collector/pyproject.toml @@ -7,7 +7,7 @@ name = "mock-collector" description = "Mock Collector used by contract tests for AWS OTEL Python Instrumentation" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.7" +requires-python = ">=3.8" dependencies = [ "grpcio ~= 1.60.0", diff --git a/contract-tests/tests/pyproject.toml b/contract-tests/tests/pyproject.toml index 95575699c..f07ee7461 100644 --- a/contract-tests/tests/pyproject.toml +++ b/contract-tests/tests/pyproject.toml @@ -7,7 +7,7 @@ name = "contract-tests" description = "Contract tests for AWS OTEL Python Instrumentation" version = "1.0.0" license = "Apache-2.0" -requires-python = ">=3.7" +requires-python = ">=3.8 dependencies = [ "opentelemetry-proto==1.22.0", diff --git a/contract-tests/tests/test/amazon/base/contract_test_base.py b/contract-tests/tests/test/amazon/base/contract_test_base.py index c9fbad32d..38292e541 100644 --- a/contract-tests/tests/test/amazon/base/contract_test_base.py +++ b/contract-tests/tests/test/amazon/base/contract_test_base.py @@ -21,6 +21,14 @@ class ContractTestBase(TestCase): + """Base class for implementing a contract test. + + This class will create all the boilerplate necessary to run a contract test. It will: 1.Create a mock collector + container that receives telemetry data of the application being tested. 2. Create an application container which + will be used to exercise the library under test. + + Several methods are provided that can be overridden to customize the test scenario. + """ _mock_collector_client: MockCollectorClient _application: DockerContainer