From a7f4d9969e658669dd7d7adac000def4a2d54fe9 Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Mon, 21 Mar 2022 11:36:49 -0300 Subject: [PATCH 1/8] starting repo for pktvisor automated tests --- python-test/.gitignore | 7 ++ python-test/README.md | 65 ++++++++++++++++++ python-test/docs/development_guide.md | 8 +++ python-test/features/behave.ini | 4 ++ python-test/features/environment.py | 22 ++++++ python-test/features/pktvisor.feature | 12 ++++ python-test/features/steps/pktvisor.py | 93 ++++++++++++++++++++++++++ python-test/features/steps/utils.py | 60 +++++++++++++++++ python-test/requirements.txt | 15 +++++ 9 files changed, 286 insertions(+) create mode 100644 python-test/.gitignore create mode 100644 python-test/README.md create mode 100644 python-test/docs/development_guide.md create mode 100644 python-test/features/behave.ini create mode 100644 python-test/features/environment.py create mode 100644 python-test/features/pktvisor.feature create mode 100644 python-test/features/steps/pktvisor.py create mode 100644 python-test/features/steps/utils.py create mode 100644 python-test/requirements.txt diff --git a/python-test/.gitignore b/python-test/.gitignore new file mode 100644 index 000000000..91d53cf20 --- /dev/null +++ b/python-test/.gitignore @@ -0,0 +1,7 @@ +test_config.ini +reports/ +behave_test/ +/site +/env_tests +__pycache__/ +doc_generator.py \ No newline at end of file diff --git a/python-test/README.md b/python-test/README.md new file mode 100644 index 000000000..95d47c0ce --- /dev/null +++ b/python-test/README.md @@ -0,0 +1,65 @@ +# Integration Tests +This directory contains automated tests for pktvisor + + +This directory is organized as described below: + + +``` +python-test +├── README.md +├── requirements.txt +├── docs +└── features +| ├── steps +| └── .feature files + +``` + +- Inside the "docs" folder is the test scenarios' documentation +- Test features are inside the "features" folder and consist of .features files. This is the gherkin language description of the scenarios you will see in the execution terminal +- The python programming of each step of the scenarios is inside the "steps" subfolder, inside "features" + + +
+ +Here's what you'll need to do in order to run these tests: +- Setup your python environment +- Run behave + +## Setup your Python environment +Create a virtual environment: `python3 -m venv name_of_virtualenv` + +Activate your virtual environment: `source name_of_virtualenv/bin/activate` + +Install the required libraries: `pip install -r requirements.txt` + + +## Run behave +From the root of the repository simply run `behave`, optionally passing the feature file as follows: + +```sh +$ behave features/pktvisor.feature +``` + +Output: + +``` + + Scenario: pktvisor bootstrap # features/pktvisor.feature:3 + When run pktvisor on port default # features/steps/pktvisor.py:32 0.184s + Then the pktvisor container status must be running # features/steps/pktvisor.py:38 0.008s + And pktvisor API must be enabled # features/steps/pktvisor.py:64 1.123s + + Scenario: run multiple pktvisors using different ports # features/pktvisor.feature:8 + When run pktvisor on port default # features/steps/pktvisor.py:32 0.168s + And run pktvisor on port 10854 # features/steps/pktvisor.py:32 0.134s + And run pktvisor on port 10855 # features/steps/pktvisor.py:32 0.117s + Then all the pktvisor containers must be running # features/steps/pktvisor.py:46 0.074s + +1 feature passed, 0 failed, 0 skipped +2 scenarios passed, 0 failed, 0 skipped +7 steps passed, 0 failed, 0 skipped, 0 undefined +Took 0m1.808s + +``` \ No newline at end of file diff --git a/python-test/docs/development_guide.md b/python-test/docs/development_guide.md new file mode 100644 index 000000000..5e42a16e8 --- /dev/null +++ b/python-test/docs/development_guide.md @@ -0,0 +1,8 @@ + +## **PKTVISOR** + + +| Scenario | Automated | Smoke | Sanity | +|:------------------------------------------------:|:---------:|:-----:|:------:| +| [Run pktvisor using docker command]() | 👍 | 👍 | 👍 | +| [Run multiple pktvisors using different ports]() | 👍 | 👍 | 👍 | \ No newline at end of file diff --git a/python-test/features/behave.ini b/python-test/features/behave.ini new file mode 100644 index 000000000..c2e4a61d8 --- /dev/null +++ b/python-test/features/behave.ini @@ -0,0 +1,4 @@ +[behave] +stderr_capture=False +stdout_capture=False + diff --git a/python-test/features/environment.py b/python-test/features/environment.py new file mode 100644 index 000000000..b262bbb7f --- /dev/null +++ b/python-test/features/environment.py @@ -0,0 +1,22 @@ +import docker + + +PKTVISOR_CONTAINER_NAME = "pktvisor-test" + + +def before_scenario(context, scenario): + cleanup_container(PKTVISOR_CONTAINER_NAME) + + +def after_feature(context, feature): + cleanup_container() + + +def cleanup_container(name_prefix): + docker_client = docker.from_env() + containers = docker_client.containers.list(all=True) + for container in containers: + test_container = container.name.startswith(name_prefix) + if test_container is True: + container.stop() + container.remove() diff --git a/python-test/features/pktvisor.feature b/python-test/features/pktvisor.feature new file mode 100644 index 000000000..a3d0c72ac --- /dev/null +++ b/python-test/features/pktvisor.feature @@ -0,0 +1,12 @@ +Feature: pktvisor tests + +Scenario: pktvisor bootstrap + When run pktvisor on port default + Then the pktvisor container status must be running + And pktvisor API must be enabled + +Scenario: run multiple pktvisors using different ports + When run pktvisor on port default + And run pktvisor on port 10854 + And run pktvisor on port 10855 + Then all the pktvisor containers must be running \ No newline at end of file diff --git a/python-test/features/steps/pktvisor.py b/python-test/features/steps/pktvisor.py new file mode 100644 index 000000000..3a324a093 --- /dev/null +++ b/python-test/features/steps/pktvisor.py @@ -0,0 +1,93 @@ +from utils import random_string +import docker +from behave import step +from hamcrest import * +import requests +from retry import retry + +PKTVISOR_CONTAINER_NAME = "pktvisor-test" + + +def run_pktvisor_container(container_image, port="default", container_name=PKTVISOR_CONTAINER_NAME): + """ + Run a pktvisor container + + :param (str) container_image: that will be used for running the container + :param (str) port: Port on which the web service must be run [default: 10853] + :param (dict) env_vars: that will be passed to the container context + :param (str) container_name: base of container name + :returns: (str) the container ID + """ + PKTVISOR_CONTAINER_NAME = container_name + random_string(3) + client = docker.from_env() + pkt_command = ["pktvisord", "wlo1"] + if port != "default": + pkt_command.insert(-1, '-p') + pkt_command.insert(-1, port) + container = client.containers.run(container_image, name=PKTVISOR_CONTAINER_NAME, detach=True, + network_mode='host', command=pkt_command) + return container.id + + + +@step("run pktvisor on port {pkt_port}") +def run_pktvisor(context, pkt_port): + context.pkt_port = pkt_port + context.container_id = run_pktvisor_container("ns1labs/pktvisor", pkt_port) + + +@step("the pktvisor container status must be {pkt_status}") +def check_pkt_status(context, pkt_status): + docker_client = docker.from_env() + container = docker_client.containers.get(context.container_id) + status = container.status + assert_that(status, equal_to(pkt_status), f"pktvisor container {context.container_id} failed with status:{status}") + + +@step("all the pktvisor containers must be {pkt_status}") +def check_pkt_status(context, pkt_status): + docker_client = docker.from_env() + + containers = docker_client.containers.list(all=True) + pkt_containers = list() + for container in containers: + pkt_containers = container.name.startswith(PKTVISOR_CONTAINER_NAME) + # if test_container is True: + # container.stop() + # container.remove() + +# container = docker_client.containers.get(context.container_id) +# status = container.status +# assert_that(status, equal_to(pkt_status), f"pktvisor container {context.container_id} failed with status:{status}") + + +@step("pktvisor API must be enabled") +def check_pkt_base_API(context): + if context.pkt_port == "default": + context.pkt_port = 10853 + + pkt_api_get_endpoints = ['metrics/app', + 'metrics/bucket/0', + 'metrics/window/2', + 'metrics/window/3', + 'metrics/window/4', + 'metrics/window/5', + 'taps', + 'policies', + 'policies/__all/metrics/window/2', + 'policies/__all/metrics/window/3', + 'policies/__all/metrics/window/4', + 'policies/__all/metrics/window/5', + 'policies/__all/metrics/prometheus'] + for endpoint in pkt_api_get_endpoints: + make_get_request(endpoint, context.pkt_port) + + +@retry(tries=3, delay=1) +def make_get_request(end_point, pkt_port=10853, expected_status_code=200): + pkt_base_api = 'http://localhost:'+str(pkt_port)+'/api/v1/' + path = pkt_base_api+end_point + response = requests.get(path) + assert_that(response.status_code, equal_to(int(expected_status_code)), + f"Get request to endpoint {path} failed with status {response.status_code}") + return response diff --git a/python-test/features/steps/utils.py b/python-test/features/steps/utils.py new file mode 100644 index 000000000..3b5c9024d --- /dev/null +++ b/python-test/features/steps/utils.py @@ -0,0 +1,60 @@ +import random +import string +from json import loads, JSONDecodeError + + +def random_string(k=10): + """ + Generates a string composed of of k (int) random letters lowercase and uppercase mixed + + :param (int) k: sets the length of the randomly generated string + :return: (str) string consisting of k random letters lowercase and uppercase mixed. Default:10 + """ + return ''.join(random.choices(string.ascii_letters, k=k)) + + +def safe_load_json(json_str): + """ + Safely parses a string into a JSON object, without ever raising an error. + :param (str) json_str: to be loaded + :return: the JSON object, or None if string is not a valid JSON. + """ + + try: + return loads(json_str) + except JSONDecodeError: + return None + + +def check_logs_contain_message_and_name(logs, expected_message, name, name_key): + """ + Gets the logs from Orb agent container + + :param (list) logs: list of log lines + :param (str) expected_message: message that we expect to find in the logs + :param (str) name: element name that we expect to find in the logs + :param (str) name_key: key to get element name on log line + :returns: (bool) whether expected message was found in the logs + """ + + for log_line in logs: + log_line = safe_load_json(log_line) + + if log_line is not None and log_line['msg'] == expected_message: + if log_line is not None and log_line[name_key] == name: + return True, log_line + + return False, "Logs doesn't contain the message and name expected" + + +def remove_empty_from_json(json_file): + """ + Delete keys with the value "None" in a dictionary, recursively. + + """ + for key, value in list(json_file.items()): + if value is None: + del json_file[key] + elif isinstance(value, dict): + remove_empty_from_json(value) + return json_file diff --git a/python-test/requirements.txt b/python-test/requirements.txt new file mode 100644 index 000000000..ec24b7a42 --- /dev/null +++ b/python-test/requirements.txt @@ -0,0 +1,15 @@ +behave==1.2.6 +certifi==2021.10.8 +charset-normalizer==2.0.12 +decorator==5.1.1 +docker==5.0.3 +idna==3.3 +parse==1.19.0 +parse-type==0.6.0 +py==1.11.0 +PyHamcrest==2.0.3 +requests==2.27.1 +retry==0.9.2 +six==1.16.0 +urllib3==1.26.9 +websocket-client==1.3.1 From d79c19cd573ca6e7b7ac0c27c48bfe0f7e44f6af Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Mon, 21 Mar 2022 12:43:33 -0300 Subject: [PATCH 2/8] boostrap tests --- python-test/docs/development_guide.md | 3 ++- python-test/features/environment.py | 4 ++-- python-test/features/pktvisor.feature | 9 +++++++- python-test/features/steps/pktvisor.py | 29 ++++++++++++++++++-------- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/python-test/docs/development_guide.md b/python-test/docs/development_guide.md index 5e42a16e8..e859bc7f5 100644 --- a/python-test/docs/development_guide.md +++ b/python-test/docs/development_guide.md @@ -5,4 +5,5 @@ | Scenario | Automated | Smoke | Sanity | |:------------------------------------------------:|:---------:|:-----:|:------:| | [Run pktvisor using docker command]() | 👍 | 👍 | 👍 | -| [Run multiple pktvisors using different ports]() | 👍 | 👍 | 👍 | \ No newline at end of file +| [Run multiple pktvisors using different ports]() | 👍 | 👍 | 👍 | +| [Run multiple pktvisors using the same ports]() | 👍 | 👍 | 👍 | \ No newline at end of file diff --git a/python-test/features/environment.py b/python-test/features/environment.py index b262bbb7f..caf49eea5 100644 --- a/python-test/features/environment.py +++ b/python-test/features/environment.py @@ -8,8 +8,8 @@ def before_scenario(context, scenario): cleanup_container(PKTVISOR_CONTAINER_NAME) -def after_feature(context, feature): - cleanup_container() +def after_scenario(context, feature): + cleanup_container(PKTVISOR_CONTAINER_NAME) def cleanup_container(name_prefix): diff --git a/python-test/features/pktvisor.feature b/python-test/features/pktvisor.feature index a3d0c72ac..551179f2b 100644 --- a/python-test/features/pktvisor.feature +++ b/python-test/features/pktvisor.feature @@ -9,4 +9,11 @@ Scenario: run multiple pktvisors using different ports When run pktvisor on port default And run pktvisor on port 10854 And run pktvisor on port 10855 - Then all the pktvisor containers must be running \ No newline at end of file + Then all the pktvisor containers must be running + And 3 pktvisor's containers must be running + +Scenario: run multiple pktvisors using the same port + When run pktvisor on port default + And run pktvisor on port default + Then 1 pktvisor's containers must be running + And 1 pktvisor's containers must be exited \ No newline at end of file diff --git a/python-test/features/steps/pktvisor.py b/python-test/features/steps/pktvisor.py index 3a324a093..f08701915 100644 --- a/python-test/features/steps/pktvisor.py +++ b/python-test/features/steps/pktvisor.py @@ -49,16 +49,27 @@ def check_pkt_status(context, pkt_status): docker_client = docker.from_env() containers = docker_client.containers.list(all=True) - pkt_containers = list() for container in containers: - pkt_containers = container.name.startswith(PKTVISOR_CONTAINER_NAME) - # if test_container is True: - # container.stop() - # container.remove() - -# container = docker_client.containers.get(context.container_id) -# status = container.status -# assert_that(status, equal_to(pkt_status), f"pktvisor container {context.container_id} failed with status:{status}") + is_test_container = container.name.startswith(PKTVISOR_CONTAINER_NAME) + if is_test_container is True: + status = container.status + assert_that(status, equal_to(pkt_status), f"pktvisor container {container.id} failed with status:{status}") + + +@step("{amount_of_pktvisor} pktvisor's containers must be {pkt_status}") +@retry(tries=5, delay=0.2) +def check_amount_of_pkt_with_status(context, amount_of_pktvisor, pkt_status): + docker_client = docker.from_env() + containers = docker_client.containers.list(all=True) + containers_with_expected_status = list() + for container in containers: + is_test_container = container.name.startswith(PKTVISOR_CONTAINER_NAME) + if is_test_container is True: + status = container.status + if status == pkt_status: + containers_with_expected_status.append(container) + assert_that(len(set(containers_with_expected_status)), equal_to(int(amount_of_pktvisor)), + f"Amount of pktvisor container with referred status failed") @step("pktvisor API must be enabled") From 9a5b7675d647cc6d42a1cf851c3d928d0acb8d1e Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Mon, 21 Mar 2022 15:22:32 -0300 Subject: [PATCH 3/8] doc --- python-test/docs/development_guide.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python-test/docs/development_guide.md b/python-test/docs/development_guide.md index e859bc7f5..e5083cd83 100644 --- a/python-test/docs/development_guide.md +++ b/python-test/docs/development_guide.md @@ -2,8 +2,8 @@ ## **PKTVISOR** -| Scenario | Automated | Smoke | Sanity | -|:------------------------------------------------:|:---------:|:-----:|:------:| -| [Run pktvisor using docker command]() | 👍 | 👍 | 👍 | -| [Run multiple pktvisors using different ports]() | 👍 | 👍 | 👍 | -| [Run multiple pktvisors using the same ports]() | 👍 | 👍 | 👍 | \ No newline at end of file +| Scenario | Automated | Smoke | Sanity | +|:--------------------------------------------------------------------------------------------------------:|:---------:|:-----:|:------:| +| [Run pktvisor using docker command](pktvisor/run_pktvisor_using_docker_command.md) | 👍 | 👍 | 👍 | +| [Run multiple pktvisors using different ports](pktvisor/run_multiple_pktvisors_using_different_ports.md) | 👍 | 👍 | 👍 | +| [Run multiple pktvisors using the same ports](pktvisor/run_multiple_pktvisors_using_the_same_ports.md) | 👍 | 👍 | 👍 | \ No newline at end of file From a98a7225c7f4047dbfe165e7fe64e2ba25a6958e Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Mon, 21 Mar 2022 15:23:13 -0300 Subject: [PATCH 4/8] doc --- .../run_multiple_pktvisors_using_different_ports.md | 11 +++++++++++ .../run_multiple_pktvisors_using_the_same_ports.md | 11 +++++++++++ .../pktvisor/run_pktvisor_using_docker_command.md | 9 +++++++++ 3 files changed, 31 insertions(+) create mode 100644 python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md create mode 100644 python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md create mode 100644 python-test/docs/pktvisor/run_pktvisor_using_docker_command.md diff --git a/python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md b/python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md new file mode 100644 index 000000000..2af60e285 --- /dev/null +++ b/python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md @@ -0,0 +1,11 @@ +## Scenario: Run multiple pktvisors using different ports + +## Steps: +- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord ` +- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord -p 10854 ` + + +## Expected Result: +- Both pktvisor containers must be running (one on port 10853 and one on port 10854) +- Endpoints from pktvisor API must be accessible (port 10853 and 10854) + \ No newline at end of file diff --git a/python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md b/python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md new file mode 100644 index 000000000..dc7ddfb5e --- /dev/null +++ b/python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md @@ -0,0 +1,11 @@ +## Scenario: Run multiple pktvisors using the same ports + +## Steps: +- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord ` +- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord ` + + +## Expected Result: +- The first pktvisor provisioned must be running (one on port 10853) +- Second pktvisor container must be exited + diff --git a/python-test/docs/pktvisor/run_pktvisor_using_docker_command.md b/python-test/docs/pktvisor/run_pktvisor_using_docker_command.md new file mode 100644 index 000000000..5c22499e7 --- /dev/null +++ b/python-test/docs/pktvisor/run_pktvisor_using_docker_command.md @@ -0,0 +1,9 @@ +## Scenario: Run pktvisor using docker command +## Steps: + - Run docker using `docker run --net=host -d ns1labs/pktvisor pktvisord ` + + +## Expected Result: + - Pktvisor container must be running + - Endpoints from pktvisor API must be accessible + From 5f8d262e4b7cca410a6cd0a7bb5fc92f676f9cf6 Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Mon, 21 Mar 2022 15:30:26 -0300 Subject: [PATCH 5/8] fix readme --- python-test/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-test/README.md b/python-test/README.md index 95d47c0ce..8598bb2e7 100644 --- a/python-test/README.md +++ b/python-test/README.md @@ -1,4 +1,4 @@ -# Integration Tests +# Pktvisor Tests This directory contains automated tests for pktvisor From 5475e972f8f9f045e4581d39d72d1c3a2a9479bd Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Mon, 21 Mar 2022 15:52:02 -0300 Subject: [PATCH 6/8] review changes --- automated_tests/.gitignore | 7 ++ automated_tests/README.md | 65 +++++++++++ automated_tests/docs/development_guide.md | 9 ++ automated_tests/docs/new_doc.txt | 3 + ...tvisors_instances_using_different_ports.md | 11 ++ ...ktvisors_instances_using_the_same_ports.md | 11 ++ ..._pktvisor_instance_using_docker_command.md | 9 ++ automated_tests/features/behave.ini | 4 + automated_tests/features/environment.py | 22 ++++ automated_tests/features/pktvisor.feature | 19 ++++ automated_tests/features/steps/pktvisor.py | 104 ++++++++++++++++++ automated_tests/features/steps/utils.py | 60 ++++++++++ automated_tests/requirements.txt | 15 +++ 13 files changed, 339 insertions(+) create mode 100644 automated_tests/.gitignore create mode 100644 automated_tests/README.md create mode 100644 automated_tests/docs/development_guide.md create mode 100644 automated_tests/docs/new_doc.txt create mode 100644 automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_different_ports.md create mode 100644 automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_the_same_ports.md create mode 100644 automated_tests/docs/pktvisor/run_pktvisor_instance_using_docker_command.md create mode 100644 automated_tests/features/behave.ini create mode 100644 automated_tests/features/environment.py create mode 100644 automated_tests/features/pktvisor.feature create mode 100644 automated_tests/features/steps/pktvisor.py create mode 100644 automated_tests/features/steps/utils.py create mode 100644 automated_tests/requirements.txt diff --git a/automated_tests/.gitignore b/automated_tests/.gitignore new file mode 100644 index 000000000..91d53cf20 --- /dev/null +++ b/automated_tests/.gitignore @@ -0,0 +1,7 @@ +test_config.ini +reports/ +behave_test/ +/site +/env_tests +__pycache__/ +doc_generator.py \ No newline at end of file diff --git a/automated_tests/README.md b/automated_tests/README.md new file mode 100644 index 000000000..8598bb2e7 --- /dev/null +++ b/automated_tests/README.md @@ -0,0 +1,65 @@ +# Pktvisor Tests +This directory contains automated tests for pktvisor + + +This directory is organized as described below: + + +``` +python-test +├── README.md +├── requirements.txt +├── docs +└── features +| ├── steps +| └── .feature files + +``` + +- Inside the "docs" folder is the test scenarios' documentation +- Test features are inside the "features" folder and consist of .features files. This is the gherkin language description of the scenarios you will see in the execution terminal +- The python programming of each step of the scenarios is inside the "steps" subfolder, inside "features" + + +
+ +Here's what you'll need to do in order to run these tests: +- Setup your python environment +- Run behave + +## Setup your Python environment +Create a virtual environment: `python3 -m venv name_of_virtualenv` + +Activate your virtual environment: `source name_of_virtualenv/bin/activate` + +Install the required libraries: `pip install -r requirements.txt` + + +## Run behave +From the root of the repository simply run `behave`, optionally passing the feature file as follows: + +```sh +$ behave features/pktvisor.feature +``` + +Output: + +``` + + Scenario: pktvisor bootstrap # features/pktvisor.feature:3 + When run pktvisor on port default # features/steps/pktvisor.py:32 0.184s + Then the pktvisor container status must be running # features/steps/pktvisor.py:38 0.008s + And pktvisor API must be enabled # features/steps/pktvisor.py:64 1.123s + + Scenario: run multiple pktvisors using different ports # features/pktvisor.feature:8 + When run pktvisor on port default # features/steps/pktvisor.py:32 0.168s + And run pktvisor on port 10854 # features/steps/pktvisor.py:32 0.134s + And run pktvisor on port 10855 # features/steps/pktvisor.py:32 0.117s + Then all the pktvisor containers must be running # features/steps/pktvisor.py:46 0.074s + +1 feature passed, 0 failed, 0 skipped +2 scenarios passed, 0 failed, 0 skipped +7 steps passed, 0 failed, 0 skipped, 0 undefined +Took 0m1.808s + +``` \ No newline at end of file diff --git a/automated_tests/docs/development_guide.md b/automated_tests/docs/development_guide.md new file mode 100644 index 000000000..c83088459 --- /dev/null +++ b/automated_tests/docs/development_guide.md @@ -0,0 +1,9 @@ + +## **PKTVISOR** + + +| Scenario | Automated | Smoke | Sanity | +|:------------------------------------------------------------------------------------------------------------------:|:---------:|:-----:|:------:| +| [Run pktvisor instance using docker command](pktvisor/run_pktvisor_instance_using_docker_command.md) | 👍 | 👍 | 👍 | +| [Run multiple pktvisors instances using different ports](pktvisor/run_multiple_pktvisors_instances_using_different_ports.md) | 👍 | 👍 | 👍 | +| [Run multiple pktvisors instances using the same ports](pktvisor/run_multiple_pktvisors_instances_using_the_same_ports.md) | 👍 | 👍 | 👍 | \ No newline at end of file diff --git a/automated_tests/docs/new_doc.txt b/automated_tests/docs/new_doc.txt new file mode 100644 index 000000000..81ece5ac2 --- /dev/null +++ b/automated_tests/docs/new_doc.txt @@ -0,0 +1,3 @@ +- Run pktvisor using docker command: pktvisor/run_pktvisor_using_docker_command.md +- Run multiple pktvisors using different ports: pktvisor/run_multiple_pktvisors_using_different_ports.md +- Run multiple pktvisors using the same ports: pktvisor/run_multiple_pktvisors_using_the_same_ports.md diff --git a/automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_different_ports.md b/automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_different_ports.md new file mode 100644 index 000000000..2ffe5238c --- /dev/null +++ b/automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_different_ports.md @@ -0,0 +1,11 @@ +## Scenario: Run multiple pktvisors instances using different ports + +## Steps: +- Provide 1 pktvisor instance using `docker run --net=host -d ns1labs/pktvisor pktvisord ` +- Provide 1 pktvisor instance using `docker run --net=host -d ns1labs/pktvisor pktvisord -p 10854 ` + + +## Expected Result: +- Both pktvisor containers must be running (one on port 10853 and one on port 10854) +- Endpoints from pktvisor API must be accessible (port 10853 and 10854) + \ No newline at end of file diff --git a/automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_the_same_ports.md b/automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_the_same_ports.md new file mode 100644 index 000000000..b4700513c --- /dev/null +++ b/automated_tests/docs/pktvisor/run_multiple_pktvisors_instances_using_the_same_ports.md @@ -0,0 +1,11 @@ +## Scenario: Run multiple pktvisors instances using the same ports + +## Steps: +- Provide 1 pktvisor instance using `docker run --net=host -d ns1labs/pktvisor pktvisord ` +- Provide 1 pktvisor instance using `docker run --net=host -d ns1labs/pktvisor pktvisord ` + + +## Expected Result: +- The first pktvisor instance provisioned must be running (one on port 10853) +- Second pktvisor container must be exited + diff --git a/automated_tests/docs/pktvisor/run_pktvisor_instance_using_docker_command.md b/automated_tests/docs/pktvisor/run_pktvisor_instance_using_docker_command.md new file mode 100644 index 000000000..3d6f73a84 --- /dev/null +++ b/automated_tests/docs/pktvisor/run_pktvisor_instance_using_docker_command.md @@ -0,0 +1,9 @@ +## Scenario: Run pktvisor instance using docker command +## Steps: + - Run docker using `docker run --net=host -d ns1labs/pktvisor pktvisord ` + + +## Expected Result: + - Pktvisor container must be running + - Endpoints from pktvisor API must be accessible + diff --git a/automated_tests/features/behave.ini b/automated_tests/features/behave.ini new file mode 100644 index 000000000..c2e4a61d8 --- /dev/null +++ b/automated_tests/features/behave.ini @@ -0,0 +1,4 @@ +[behave] +stderr_capture=False +stdout_capture=False + diff --git a/automated_tests/features/environment.py b/automated_tests/features/environment.py new file mode 100644 index 000000000..caf49eea5 --- /dev/null +++ b/automated_tests/features/environment.py @@ -0,0 +1,22 @@ +import docker + + +PKTVISOR_CONTAINER_NAME = "pktvisor-test" + + +def before_scenario(context, scenario): + cleanup_container(PKTVISOR_CONTAINER_NAME) + + +def after_scenario(context, feature): + cleanup_container(PKTVISOR_CONTAINER_NAME) + + +def cleanup_container(name_prefix): + docker_client = docker.from_env() + containers = docker_client.containers.list(all=True) + for container in containers: + test_container = container.name.startswith(name_prefix) + if test_container is True: + container.stop() + container.remove() diff --git a/automated_tests/features/pktvisor.feature b/automated_tests/features/pktvisor.feature new file mode 100644 index 000000000..5f9cd50df --- /dev/null +++ b/automated_tests/features/pktvisor.feature @@ -0,0 +1,19 @@ +Feature: pktvisor tests + +Scenario: pktvisor bootstrap + When run pktvisor instance on port default + Then the pktvisor container status must be running + And pktvisor API must be enabled + +Scenario: run multiple pktvisors using different ports + When run pktvisor instance on port default + And run pktvisor instance on port 10854 + And run pktvisor instance on port 10855 + Then all the pktvisor containers must be running + And 3 pktvisor's containers must be running + +Scenario: run multiple pktvisors instances using the same port + When run pktvisor instance on port default + And run pktvisor instance on port default + Then 1 pktvisor's containers must be running + And 1 pktvisor's containers must be exited \ No newline at end of file diff --git a/automated_tests/features/steps/pktvisor.py b/automated_tests/features/steps/pktvisor.py new file mode 100644 index 000000000..bd20edc13 --- /dev/null +++ b/automated_tests/features/steps/pktvisor.py @@ -0,0 +1,104 @@ +from utils import random_string +import docker +from behave import step +from hamcrest import * +import requests +from retry import retry + +PKTVISOR_CONTAINER_NAME = "pktvisor-test" + + +def run_pktvisor_container(container_image, port="default", container_name=PKTVISOR_CONTAINER_NAME): + """ + Run a pktvisor container + + :param (str) container_image: that will be used for running the container + :param (str) port: Port on which the web service must be run [default: 10853] + :param (dict) env_vars: that will be passed to the container context + :param (str) container_name: base of container name + :returns: (str) the container ID + """ + PKTVISOR_CONTAINER_NAME = container_name + random_string(3) + client = docker.from_env() + pkt_command = ["pktvisord", "wlo1"] + if port != "default": + pkt_command.insert(-1, '-p') + pkt_command.insert(-1, port) + container = client.containers.run(container_image, name=PKTVISOR_CONTAINER_NAME, detach=True, + network_mode='host', command=pkt_command) + return container.id + + + +@step("run pktvisor instance on port {pkt_port}") +def run_pktvisor(context, pkt_port): + context.pkt_port = pkt_port + context.container_id = run_pktvisor_container("ns1labs/pktvisor", pkt_port) + + +@step("the pktvisor container status must be {pkt_status}") +def check_pkt_status(context, pkt_status): + docker_client = docker.from_env() + container = docker_client.containers.get(context.container_id) + status = container.status + assert_that(status, equal_to(pkt_status), f"pktvisor container {context.container_id} failed with status:{status}") + + +@step("all the pktvisor containers must be {pkt_status}") +def check_pkt_status(context, pkt_status): + docker_client = docker.from_env() + + containers = docker_client.containers.list(all=True) + for container in containers: + is_test_container = container.name.startswith(PKTVISOR_CONTAINER_NAME) + if is_test_container is True: + status = container.status + assert_that(status, equal_to(pkt_status), f"pktvisor container {container.id} failed with status:{status}") + + +@step("{amount_of_pktvisor} pktvisor's containers must be {pkt_status}") +@retry(tries=5, delay=0.2) +def check_amount_of_pkt_with_status(context, amount_of_pktvisor, pkt_status): + docker_client = docker.from_env() + containers = docker_client.containers.list(all=True) + containers_with_expected_status = list() + for container in containers: + is_test_container = container.name.startswith(PKTVISOR_CONTAINER_NAME) + if is_test_container is True: + status = container.status + if status == pkt_status: + containers_with_expected_status.append(container) + assert_that(len(set(containers_with_expected_status)), equal_to(int(amount_of_pktvisor)), + f"Amount of pktvisor container with referred status failed") + + +@step("pktvisor API must be enabled") +def check_pkt_base_API(context): + if context.pkt_port == "default": + context.pkt_port = 10853 + + pkt_api_get_endpoints = ['metrics/app', + 'metrics/bucket/0', + 'metrics/window/2', + 'metrics/window/3', + 'metrics/window/4', + 'metrics/window/5', + 'taps', + 'policies', + 'policies/__all/metrics/window/2', + 'policies/__all/metrics/window/3', + 'policies/__all/metrics/window/4', + 'policies/__all/metrics/window/5', + 'policies/__all/metrics/prometheus'] + for endpoint in pkt_api_get_endpoints: + make_get_request(endpoint, context.pkt_port) + + +@retry(tries=3, delay=1) +def make_get_request(end_point, pkt_port=10853, expected_status_code=200): + pkt_base_api = 'http://localhost:'+str(pkt_port)+'/api/v1/' + path = pkt_base_api+end_point + response = requests.get(path) + assert_that(response.status_code, equal_to(int(expected_status_code)), + f"Get request to endpoint {path} failed with status {response.status_code}") + return response diff --git a/automated_tests/features/steps/utils.py b/automated_tests/features/steps/utils.py new file mode 100644 index 000000000..3b5c9024d --- /dev/null +++ b/automated_tests/features/steps/utils.py @@ -0,0 +1,60 @@ +import random +import string +from json import loads, JSONDecodeError + + +def random_string(k=10): + """ + Generates a string composed of of k (int) random letters lowercase and uppercase mixed + + :param (int) k: sets the length of the randomly generated string + :return: (str) string consisting of k random letters lowercase and uppercase mixed. Default:10 + """ + return ''.join(random.choices(string.ascii_letters, k=k)) + + +def safe_load_json(json_str): + """ + Safely parses a string into a JSON object, without ever raising an error. + :param (str) json_str: to be loaded + :return: the JSON object, or None if string is not a valid JSON. + """ + + try: + return loads(json_str) + except JSONDecodeError: + return None + + +def check_logs_contain_message_and_name(logs, expected_message, name, name_key): + """ + Gets the logs from Orb agent container + + :param (list) logs: list of log lines + :param (str) expected_message: message that we expect to find in the logs + :param (str) name: element name that we expect to find in the logs + :param (str) name_key: key to get element name on log line + :returns: (bool) whether expected message was found in the logs + """ + + for log_line in logs: + log_line = safe_load_json(log_line) + + if log_line is not None and log_line['msg'] == expected_message: + if log_line is not None and log_line[name_key] == name: + return True, log_line + + return False, "Logs doesn't contain the message and name expected" + + +def remove_empty_from_json(json_file): + """ + Delete keys with the value "None" in a dictionary, recursively. + + """ + for key, value in list(json_file.items()): + if value is None: + del json_file[key] + elif isinstance(value, dict): + remove_empty_from_json(value) + return json_file diff --git a/automated_tests/requirements.txt b/automated_tests/requirements.txt new file mode 100644 index 000000000..ec24b7a42 --- /dev/null +++ b/automated_tests/requirements.txt @@ -0,0 +1,15 @@ +behave==1.2.6 +certifi==2021.10.8 +charset-normalizer==2.0.12 +decorator==5.1.1 +docker==5.0.3 +idna==3.3 +parse==1.19.0 +parse-type==0.6.0 +py==1.11.0 +PyHamcrest==2.0.3 +requests==2.27.1 +retry==0.9.2 +six==1.16.0 +urllib3==1.26.9 +websocket-client==1.3.1 From 91062ea619b95e1ae457c54859f7bff6c54a7032 Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Mon, 21 Mar 2022 16:00:33 -0300 Subject: [PATCH 7/8] fix readme --- automated_tests/README.md | 29 +++-- automated_tests/docs/new_doc.txt | 3 - python-test/.gitignore | 7 -- python-test/README.md | 65 ----------- python-test/docs/development_guide.md | 9 -- ...ultiple_pktvisors_using_different_ports.md | 11 -- ...multiple_pktvisors_using_the_same_ports.md | 11 -- .../run_pktvisor_using_docker_command.md | 9 -- python-test/features/behave.ini | 4 - python-test/features/environment.py | 22 ---- python-test/features/pktvisor.feature | 19 ---- python-test/features/steps/pktvisor.py | 104 ------------------ python-test/features/steps/utils.py | 60 ---------- python-test/requirements.txt | 15 --- 14 files changed, 19 insertions(+), 349 deletions(-) delete mode 100644 automated_tests/docs/new_doc.txt delete mode 100644 python-test/.gitignore delete mode 100644 python-test/README.md delete mode 100644 python-test/docs/development_guide.md delete mode 100644 python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md delete mode 100644 python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md delete mode 100644 python-test/docs/pktvisor/run_pktvisor_using_docker_command.md delete mode 100644 python-test/features/behave.ini delete mode 100644 python-test/features/environment.py delete mode 100644 python-test/features/pktvisor.feature delete mode 100644 python-test/features/steps/pktvisor.py delete mode 100644 python-test/features/steps/utils.py delete mode 100644 python-test/requirements.txt diff --git a/automated_tests/README.md b/automated_tests/README.md index 8598bb2e7..92f600628 100644 --- a/automated_tests/README.md +++ b/automated_tests/README.md @@ -45,21 +45,30 @@ $ behave features/pktvisor.feature Output: ``` +Feature: pktvisor tests # features/pktvisor.feature:1 Scenario: pktvisor bootstrap # features/pktvisor.feature:3 - When run pktvisor on port default # features/steps/pktvisor.py:32 0.184s - Then the pktvisor container status must be running # features/steps/pktvisor.py:38 0.008s - And pktvisor API must be enabled # features/steps/pktvisor.py:64 1.123s + When run pktvisor instance on port default # features/steps/pktvisor.py:33 0.150s + Then the pktvisor container status must be running # features/steps/pktvisor.py:39 0.007s + And pktvisor API must be enabled # features/steps/pktvisor.py:75 1.123s Scenario: run multiple pktvisors using different ports # features/pktvisor.feature:8 - When run pktvisor on port default # features/steps/pktvisor.py:32 0.168s - And run pktvisor on port 10854 # features/steps/pktvisor.py:32 0.134s - And run pktvisor on port 10855 # features/steps/pktvisor.py:32 0.117s - Then all the pktvisor containers must be running # features/steps/pktvisor.py:46 0.074s + When run pktvisor instance on port default # features/steps/pktvisor.py:33 0.156s + And run pktvisor instance on port 10854 # features/steps/pktvisor.py:33 0.127s + And run pktvisor instance on port 10855 # features/steps/pktvisor.py:33 0.146s + Then all the pktvisor containers must be running # features/steps/pktvisor.py:47 0.011s + And 3 pktvisor's containers must be running # features/steps/pktvisor.py:59 0.012s + + Scenario: run multiple pktvisors instances using the same port # features/pktvisor.feature:15 + When run pktvisor instance on port default # features/steps/pktvisor.py:33 0.194s + And run pktvisor instance on port default # features/steps/pktvisor.py:33 0.149s + Then 1 pktvisor's containers must be running # features/steps/pktvisor.py:59 0.226s + And 1 pktvisor's containers must be exited # features/steps/pktvisor.py:59 0.011s 1 feature passed, 0 failed, 0 skipped -2 scenarios passed, 0 failed, 0 skipped -7 steps passed, 0 failed, 0 skipped, 0 undefined -Took 0m1.808s +3 scenarios passed, 0 failed, 0 skipped +12 steps passed, 0 failed, 0 skipped, 0 undefined +Took 0m2.312s + ``` \ No newline at end of file diff --git a/automated_tests/docs/new_doc.txt b/automated_tests/docs/new_doc.txt deleted file mode 100644 index 81ece5ac2..000000000 --- a/automated_tests/docs/new_doc.txt +++ /dev/null @@ -1,3 +0,0 @@ -- Run pktvisor using docker command: pktvisor/run_pktvisor_using_docker_command.md -- Run multiple pktvisors using different ports: pktvisor/run_multiple_pktvisors_using_different_ports.md -- Run multiple pktvisors using the same ports: pktvisor/run_multiple_pktvisors_using_the_same_ports.md diff --git a/python-test/.gitignore b/python-test/.gitignore deleted file mode 100644 index 91d53cf20..000000000 --- a/python-test/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -test_config.ini -reports/ -behave_test/ -/site -/env_tests -__pycache__/ -doc_generator.py \ No newline at end of file diff --git a/python-test/README.md b/python-test/README.md deleted file mode 100644 index 8598bb2e7..000000000 --- a/python-test/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Pktvisor Tests -This directory contains automated tests for pktvisor - - -This directory is organized as described below: - - -``` -python-test -├── README.md -├── requirements.txt -├── docs -└── features -| ├── steps -| └── .feature files - -``` - -- Inside the "docs" folder is the test scenarios' documentation -- Test features are inside the "features" folder and consist of .features files. This is the gherkin language description of the scenarios you will see in the execution terminal -- The python programming of each step of the scenarios is inside the "steps" subfolder, inside "features" - - -
- -Here's what you'll need to do in order to run these tests: -- Setup your python environment -- Run behave - -## Setup your Python environment -Create a virtual environment: `python3 -m venv name_of_virtualenv` - -Activate your virtual environment: `source name_of_virtualenv/bin/activate` - -Install the required libraries: `pip install -r requirements.txt` - - -## Run behave -From the root of the repository simply run `behave`, optionally passing the feature file as follows: - -```sh -$ behave features/pktvisor.feature -``` - -Output: - -``` - - Scenario: pktvisor bootstrap # features/pktvisor.feature:3 - When run pktvisor on port default # features/steps/pktvisor.py:32 0.184s - Then the pktvisor container status must be running # features/steps/pktvisor.py:38 0.008s - And pktvisor API must be enabled # features/steps/pktvisor.py:64 1.123s - - Scenario: run multiple pktvisors using different ports # features/pktvisor.feature:8 - When run pktvisor on port default # features/steps/pktvisor.py:32 0.168s - And run pktvisor on port 10854 # features/steps/pktvisor.py:32 0.134s - And run pktvisor on port 10855 # features/steps/pktvisor.py:32 0.117s - Then all the pktvisor containers must be running # features/steps/pktvisor.py:46 0.074s - -1 feature passed, 0 failed, 0 skipped -2 scenarios passed, 0 failed, 0 skipped -7 steps passed, 0 failed, 0 skipped, 0 undefined -Took 0m1.808s - -``` \ No newline at end of file diff --git a/python-test/docs/development_guide.md b/python-test/docs/development_guide.md deleted file mode 100644 index e5083cd83..000000000 --- a/python-test/docs/development_guide.md +++ /dev/null @@ -1,9 +0,0 @@ - -## **PKTVISOR** - - -| Scenario | Automated | Smoke | Sanity | -|:--------------------------------------------------------------------------------------------------------:|:---------:|:-----:|:------:| -| [Run pktvisor using docker command](pktvisor/run_pktvisor_using_docker_command.md) | 👍 | 👍 | 👍 | -| [Run multiple pktvisors using different ports](pktvisor/run_multiple_pktvisors_using_different_ports.md) | 👍 | 👍 | 👍 | -| [Run multiple pktvisors using the same ports](pktvisor/run_multiple_pktvisors_using_the_same_ports.md) | 👍 | 👍 | 👍 | \ No newline at end of file diff --git a/python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md b/python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md deleted file mode 100644 index 2af60e285..000000000 --- a/python-test/docs/pktvisor/run_multiple_pktvisors_using_different_ports.md +++ /dev/null @@ -1,11 +0,0 @@ -## Scenario: Run multiple pktvisors using different ports - -## Steps: -- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord ` -- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord -p 10854 ` - - -## Expected Result: -- Both pktvisor containers must be running (one on port 10853 and one on port 10854) -- Endpoints from pktvisor API must be accessible (port 10853 and 10854) - \ No newline at end of file diff --git a/python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md b/python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md deleted file mode 100644 index dc7ddfb5e..000000000 --- a/python-test/docs/pktvisor/run_multiple_pktvisors_using_the_same_ports.md +++ /dev/null @@ -1,11 +0,0 @@ -## Scenario: Run multiple pktvisors using the same ports - -## Steps: -- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord ` -- Provide 1 pktvisor using `docker run --net=host -d ns1labs/pktvisor pktvisord ` - - -## Expected Result: -- The first pktvisor provisioned must be running (one on port 10853) -- Second pktvisor container must be exited - diff --git a/python-test/docs/pktvisor/run_pktvisor_using_docker_command.md b/python-test/docs/pktvisor/run_pktvisor_using_docker_command.md deleted file mode 100644 index 5c22499e7..000000000 --- a/python-test/docs/pktvisor/run_pktvisor_using_docker_command.md +++ /dev/null @@ -1,9 +0,0 @@ -## Scenario: Run pktvisor using docker command -## Steps: - - Run docker using `docker run --net=host -d ns1labs/pktvisor pktvisord ` - - -## Expected Result: - - Pktvisor container must be running - - Endpoints from pktvisor API must be accessible - diff --git a/python-test/features/behave.ini b/python-test/features/behave.ini deleted file mode 100644 index c2e4a61d8..000000000 --- a/python-test/features/behave.ini +++ /dev/null @@ -1,4 +0,0 @@ -[behave] -stderr_capture=False -stdout_capture=False - diff --git a/python-test/features/environment.py b/python-test/features/environment.py deleted file mode 100644 index caf49eea5..000000000 --- a/python-test/features/environment.py +++ /dev/null @@ -1,22 +0,0 @@ -import docker - - -PKTVISOR_CONTAINER_NAME = "pktvisor-test" - - -def before_scenario(context, scenario): - cleanup_container(PKTVISOR_CONTAINER_NAME) - - -def after_scenario(context, feature): - cleanup_container(PKTVISOR_CONTAINER_NAME) - - -def cleanup_container(name_prefix): - docker_client = docker.from_env() - containers = docker_client.containers.list(all=True) - for container in containers: - test_container = container.name.startswith(name_prefix) - if test_container is True: - container.stop() - container.remove() diff --git a/python-test/features/pktvisor.feature b/python-test/features/pktvisor.feature deleted file mode 100644 index 551179f2b..000000000 --- a/python-test/features/pktvisor.feature +++ /dev/null @@ -1,19 +0,0 @@ -Feature: pktvisor tests - -Scenario: pktvisor bootstrap - When run pktvisor on port default - Then the pktvisor container status must be running - And pktvisor API must be enabled - -Scenario: run multiple pktvisors using different ports - When run pktvisor on port default - And run pktvisor on port 10854 - And run pktvisor on port 10855 - Then all the pktvisor containers must be running - And 3 pktvisor's containers must be running - -Scenario: run multiple pktvisors using the same port - When run pktvisor on port default - And run pktvisor on port default - Then 1 pktvisor's containers must be running - And 1 pktvisor's containers must be exited \ No newline at end of file diff --git a/python-test/features/steps/pktvisor.py b/python-test/features/steps/pktvisor.py deleted file mode 100644 index f08701915..000000000 --- a/python-test/features/steps/pktvisor.py +++ /dev/null @@ -1,104 +0,0 @@ -from utils import random_string -import docker -from behave import step -from hamcrest import * -import requests -from retry import retry - -PKTVISOR_CONTAINER_NAME = "pktvisor-test" - - -def run_pktvisor_container(container_image, port="default", container_name=PKTVISOR_CONTAINER_NAME): - """ - Run a pktvisor container - - :param (str) container_image: that will be used for running the container - :param (str) port: Port on which the web service must be run [default: 10853] - :param (dict) env_vars: that will be passed to the container context - :param (str) container_name: base of container name - :returns: (str) the container ID - """ - PKTVISOR_CONTAINER_NAME = container_name + random_string(3) - client = docker.from_env() - pkt_command = ["pktvisord", "wlo1"] - if port != "default": - pkt_command.insert(-1, '-p') - pkt_command.insert(-1, port) - container = client.containers.run(container_image, name=PKTVISOR_CONTAINER_NAME, detach=True, - network_mode='host', command=pkt_command) - return container.id - - - -@step("run pktvisor on port {pkt_port}") -def run_pktvisor(context, pkt_port): - context.pkt_port = pkt_port - context.container_id = run_pktvisor_container("ns1labs/pktvisor", pkt_port) - - -@step("the pktvisor container status must be {pkt_status}") -def check_pkt_status(context, pkt_status): - docker_client = docker.from_env() - container = docker_client.containers.get(context.container_id) - status = container.status - assert_that(status, equal_to(pkt_status), f"pktvisor container {context.container_id} failed with status:{status}") - - -@step("all the pktvisor containers must be {pkt_status}") -def check_pkt_status(context, pkt_status): - docker_client = docker.from_env() - - containers = docker_client.containers.list(all=True) - for container in containers: - is_test_container = container.name.startswith(PKTVISOR_CONTAINER_NAME) - if is_test_container is True: - status = container.status - assert_that(status, equal_to(pkt_status), f"pktvisor container {container.id} failed with status:{status}") - - -@step("{amount_of_pktvisor} pktvisor's containers must be {pkt_status}") -@retry(tries=5, delay=0.2) -def check_amount_of_pkt_with_status(context, amount_of_pktvisor, pkt_status): - docker_client = docker.from_env() - containers = docker_client.containers.list(all=True) - containers_with_expected_status = list() - for container in containers: - is_test_container = container.name.startswith(PKTVISOR_CONTAINER_NAME) - if is_test_container is True: - status = container.status - if status == pkt_status: - containers_with_expected_status.append(container) - assert_that(len(set(containers_with_expected_status)), equal_to(int(amount_of_pktvisor)), - f"Amount of pktvisor container with referred status failed") - - -@step("pktvisor API must be enabled") -def check_pkt_base_API(context): - if context.pkt_port == "default": - context.pkt_port = 10853 - - pkt_api_get_endpoints = ['metrics/app', - 'metrics/bucket/0', - 'metrics/window/2', - 'metrics/window/3', - 'metrics/window/4', - 'metrics/window/5', - 'taps', - 'policies', - 'policies/__all/metrics/window/2', - 'policies/__all/metrics/window/3', - 'policies/__all/metrics/window/4', - 'policies/__all/metrics/window/5', - 'policies/__all/metrics/prometheus'] - for endpoint in pkt_api_get_endpoints: - make_get_request(endpoint, context.pkt_port) - - -@retry(tries=3, delay=1) -def make_get_request(end_point, pkt_port=10853, expected_status_code=200): - pkt_base_api = 'http://localhost:'+str(pkt_port)+'/api/v1/' - path = pkt_base_api+end_point - response = requests.get(path) - assert_that(response.status_code, equal_to(int(expected_status_code)), - f"Get request to endpoint {path} failed with status {response.status_code}") - return response diff --git a/python-test/features/steps/utils.py b/python-test/features/steps/utils.py deleted file mode 100644 index 3b5c9024d..000000000 --- a/python-test/features/steps/utils.py +++ /dev/null @@ -1,60 +0,0 @@ -import random -import string -from json import loads, JSONDecodeError - - -def random_string(k=10): - """ - Generates a string composed of of k (int) random letters lowercase and uppercase mixed - - :param (int) k: sets the length of the randomly generated string - :return: (str) string consisting of k random letters lowercase and uppercase mixed. Default:10 - """ - return ''.join(random.choices(string.ascii_letters, k=k)) - - -def safe_load_json(json_str): - """ - Safely parses a string into a JSON object, without ever raising an error. - :param (str) json_str: to be loaded - :return: the JSON object, or None if string is not a valid JSON. - """ - - try: - return loads(json_str) - except JSONDecodeError: - return None - - -def check_logs_contain_message_and_name(logs, expected_message, name, name_key): - """ - Gets the logs from Orb agent container - - :param (list) logs: list of log lines - :param (str) expected_message: message that we expect to find in the logs - :param (str) name: element name that we expect to find in the logs - :param (str) name_key: key to get element name on log line - :returns: (bool) whether expected message was found in the logs - """ - - for log_line in logs: - log_line = safe_load_json(log_line) - - if log_line is not None and log_line['msg'] == expected_message: - if log_line is not None and log_line[name_key] == name: - return True, log_line - - return False, "Logs doesn't contain the message and name expected" - - -def remove_empty_from_json(json_file): - """ - Delete keys with the value "None" in a dictionary, recursively. - - """ - for key, value in list(json_file.items()): - if value is None: - del json_file[key] - elif isinstance(value, dict): - remove_empty_from_json(value) - return json_file diff --git a/python-test/requirements.txt b/python-test/requirements.txt deleted file mode 100644 index ec24b7a42..000000000 --- a/python-test/requirements.txt +++ /dev/null @@ -1,15 +0,0 @@ -behave==1.2.6 -certifi==2021.10.8 -charset-normalizer==2.0.12 -decorator==5.1.1 -docker==5.0.3 -idna==3.3 -parse==1.19.0 -parse-type==0.6.0 -py==1.11.0 -PyHamcrest==2.0.3 -requests==2.27.1 -retry==0.9.2 -six==1.16.0 -urllib3==1.26.9 -websocket-client==1.3.1 From df47cee3d69c308ecd90358900f18fc6fdb04a7f Mon Sep 17 00:00:00 2001 From: Amanda Rodrigues da Silva Date: Tue, 22 Mar 2022 12:13:16 -0300 Subject: [PATCH 8/8] specifying pktvisor as a instance --- automated_tests/README.md | 2 +- automated_tests/features/pktvisor.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/automated_tests/README.md b/automated_tests/README.md index 92f600628..d0680f0e7 100644 --- a/automated_tests/README.md +++ b/automated_tests/README.md @@ -52,7 +52,7 @@ Feature: pktvisor tests # features/pktvisor.feature:1 Then the pktvisor container status must be running # features/steps/pktvisor.py:39 0.007s And pktvisor API must be enabled # features/steps/pktvisor.py:75 1.123s - Scenario: run multiple pktvisors using different ports # features/pktvisor.feature:8 + Scenario: run multiple pktvisors instances using different ports # features/pktvisor.feature:8 When run pktvisor instance on port default # features/steps/pktvisor.py:33 0.156s And run pktvisor instance on port 10854 # features/steps/pktvisor.py:33 0.127s And run pktvisor instance on port 10855 # features/steps/pktvisor.py:33 0.146s diff --git a/automated_tests/features/pktvisor.feature b/automated_tests/features/pktvisor.feature index 5f9cd50df..acb0a10fe 100644 --- a/automated_tests/features/pktvisor.feature +++ b/automated_tests/features/pktvisor.feature @@ -5,7 +5,7 @@ Scenario: pktvisor bootstrap Then the pktvisor container status must be running And pktvisor API must be enabled -Scenario: run multiple pktvisors using different ports +Scenario: run multiple pktvisors instances using different ports When run pktvisor instance on port default And run pktvisor instance on port 10854 And run pktvisor instance on port 10855