From f5233d1be8ee8bcdbd0919b1bf04b71d6cf17cf8 Mon Sep 17 00:00:00 2001 From: Osman Hadzic Date: Wed, 30 Oct 2024 17:11:31 +0100 Subject: [PATCH] Refactor test file structure Remove old test file for app engine device get samples data and refactor test file structure: - Move `test_app_engine.py` to `app_engine/device/app_engine_device_get_samples_error_cases.py` - Add resources file for test data Signed-off-by: Osman Hadzic --- ...t_app_engine_device_get_samples_default.py | 274 ++++++++++++++++++ ..._engine_device_get_samples_error_cases.py} | 45 ++- tests/resources.py | 115 ++++++++ 3 files changed, 430 insertions(+), 4 deletions(-) create mode 100644 tests/app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_default.py rename tests/{test_app_engine.py => app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_error_cases.py} (57%) create mode 100644 tests/resources.py diff --git a/tests/app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_default.py b/tests/app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_default.py new file mode 100644 index 0000000..5fa7ffc --- /dev/null +++ b/tests/app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_default.py @@ -0,0 +1,274 @@ +# SPDX-FileCopyrightText: 2024 SECO Mind Srl +# +# SPDX-License-Identifier: Apache-2.0 + +import subprocess +import re +import ast + +from resources import ( + expected_output_object, + list_of_params_endpoints, + list_of_nonparams_endpoints, + map_of_params_data, + map_of_nonparams_data, +) + + +def test_get_sample_data_for_device_individual_parametric_datastream(astarte_env_vars): + device_id = astarte_env_vars["device_test_1"] + astarte_url = astarte_env_vars["astarte_url"] + realm = astarte_env_vars["realm"] + jwt = astarte_env_vars["jwt"] + + interface_name = "test.astarte-platform.device.individual.parametric.Datastream" + + for path in list_of_params_endpoints: + arg_list = [ + "astartectl", + "appengine", + "devices", + "get-samples", + device_id, + interface_name, + path, + "-t", + jwt, + "-u", + astarte_url, + "-r", + realm, + ] + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + sample_data_result.stdout = _remove_table_border(sample_data_result) + + assert sample_data_result.stdout != "" + + sample_data_result.stdout = _normalize_and_split(sample_data_result.stdout) + + parsed_elements_list = _extract_elements_from_brackets(sample_data_result.stdout) + + list_length = len(sample_data_result.stdout) - 1 + + if parsed_elements_list != []: + assert parsed_elements_list == map_of_params_data[path] + else: + assert sample_data_result.stdout[list_length] == map_of_params_data[path] + + +def test_get_sample_data_for_device_individual_nonparametric_datastream(astarte_env_vars): + device_id = astarte_env_vars["device_test_1"] + astarte_url = astarte_env_vars["astarte_url"] + realm = astarte_env_vars["realm"] + jwt = astarte_env_vars["jwt"] + + interface_name = "test.astarte-platform.device.individual.nonparametric.Datastream" + + for path in list_of_nonparams_endpoints: + arg_list = [ + "astartectl", + "appengine", + "devices", + "get-samples", + device_id, + interface_name, + path, + "-t", + jwt, + "-u", + astarte_url, + "-r", + realm, + ] + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + sample_data_result.stdout = _remove_table_border(sample_data_result) + + assert sample_data_result.stdout != "" + + sample_data_result.stdout = _normalize_and_split(sample_data_result.stdout) + + parsed_elements_list = _extract_elements_from_brackets(sample_data_result.stdout) + + list_length = len(sample_data_result.stdout) - 1 + + if parsed_elements_list != []: + assert parsed_elements_list == map_of_nonparams_data[path] + else: + assert sample_data_result.stdout[list_length] == map_of_nonparams_data[path] + + +def test_get_sample_data_for_device_object_nonparametric_datastream(astarte_env_vars): + device_id = astarte_env_vars["device_test_1"] + astarte_url = astarte_env_vars["astarte_url"] + realm = astarte_env_vars["realm"] + jwt = astarte_env_vars["jwt"] + + interface_name = "test.astarte-platform.device.object.nonparametric.Datastream" + path = "/the" + + arg_list = [ + "astartectl", + "appengine", + "devices", + "get-samples", + device_id, + interface_name, + path, + "-t", + jwt, + "-u", + astarte_url, + "-r", + realm, + ] + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + sample_data_result.stdout = _remove_table_border(sample_data_result) + + sample_data_result.stdout = _normalize_and_split(sample_data_result.stdout) + + assert sample_data_result.stdout == expected_output_object + + +def test_get_sample_data_for_device_object_parametric_datastream(astarte_env_vars): + device_id = astarte_env_vars["device_test_1"] + astarte_url = astarte_env_vars["astarte_url"] + realm = astarte_env_vars["realm"] + jwt = astarte_env_vars["jwt"] + + interface_name = "test.astarte-platform.device.object.parametric.Datastream" + path = "/a" + + arg_list = [ + "astartectl", + "appengine", + "devices", + "get-samples", + device_id, + interface_name, + path, + "-t", + jwt, + "-u", + astarte_url, + "-r", + realm, + ] + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + sample_data_result.stdout = _remove_table_border(sample_data_result) + + sample_data_result.stdout = _normalize_and_split(sample_data_result.stdout) + + assert sample_data_result.stdout == expected_output_object + + +def test_get_sample_data_for_server_individual_parametric_datastream(astarte_env_vars): + device_id = astarte_env_vars["device_test_1"] + astarte_url = astarte_env_vars["astarte_url"] + realm = astarte_env_vars["realm"] + jwt = astarte_env_vars["jwt"] + + interface_name = "test.astarte-platform.server.individual.parametric.Datastream" + + for path in list_of_params_endpoints: + arg_list = [ + "astartectl", + "appengine", + "devices", + "get-samples", + device_id, + interface_name, + path, + "-t", + jwt, + "-u", + astarte_url, + "-r", + realm, + ] + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + sample_data_result.stdout = _remove_table_border(sample_data_result) + + assert sample_data_result.stdout != "" + + sample_data_result.stdout = _normalize_and_split(sample_data_result.stdout) + + parsed_elements_list = _extract_elements_from_brackets(sample_data_result.stdout) + + list_length = len(sample_data_result.stdout) - 1 + + if parsed_elements_list != []: + assert parsed_elements_list == map_of_params_data[path] + else: + assert sample_data_result.stdout[list_length] == map_of_params_data[path] + + +def test_get_sample_data_for_server_individual_nonparametric_datastream(astarte_env_vars): + device_id = astarte_env_vars["device_test_1"] + astarte_url = astarte_env_vars["astarte_url"] + realm = astarte_env_vars["realm"] + jwt = astarte_env_vars["jwt"] + + interface_name = "test.astarte-platform.server.individual.nonparametric.Datastream" + + for path in list_of_nonparams_endpoints: + arg_list = [ + "astartectl", + "appengine", + "devices", + "get-samples", + device_id, + interface_name, + path, + "-t", + jwt, + "-u", + astarte_url, + "-r", + realm, + ] + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + sample_data_result.stdout = _remove_table_border(sample_data_result) + + assert sample_data_result.stdout != "" + + sample_data_result.stdout = _normalize_and_split(sample_data_result.stdout) + + parsed_elements_list = _extract_elements_from_brackets(sample_data_result.stdout) + + list_length = len(sample_data_result.stdout) - 1 + + if parsed_elements_list != []: + assert parsed_elements_list == map_of_nonparams_data[path] + else: + assert sample_data_result.stdout[list_length] == map_of_nonparams_data[path] + + +def _remove_table_border(table): + table = table.stdout.replace("\n", "") + + table = "".join(ch for ch in table if not (9472 <= ord(ch) <= 9584)) + return table + + +def _parse_element(element): + element = element.strip() + if element.startswith("[") and element.endswith("]"): + return ast.literal_eval(element) + return element + + +def _extract_elements_from_brackets(sample_data_result): + parsed_elements_list = [] + for element in sample_data_result: + if element.startswith("["): + parsed_elements_list.append(element.replace("[", "")) + elif element.endswith("]"): + parsed_elements_list.append(element.replace("]", "")) + return parsed_elements_list + + +def _normalize_and_split(sample_data_result): + sample_data_result = re.sub(r"\s+", " ", sample_data_result).strip() + sample_data_result = sample_data_result.replace(" ", ",").split(",") + sample_data_result = [_parse_element(el) for el in sample_data_result] + return sample_data_result diff --git a/tests/test_app_engine.py b/tests/app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_error_cases.py similarity index 57% rename from tests/test_app_engine.py rename to tests/app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_error_cases.py index 845ea1d..436b4ce 100644 --- a/tests/test_app_engine.py +++ b/tests/app_engine/device/app_engine_device_get_samples/test_app_engine_device_get_samples_error_cases.py @@ -4,6 +4,7 @@ import subprocess + def test_get_sample_data_for_nonexisting_device(astarte_env_vars): device_id = "nonexisting_device" astarte_url = astarte_env_vars["astarte_url"] @@ -34,14 +35,15 @@ def test_get_sample_data_for_nonexisting_device(astarte_env_vars): assert "Device not found" in sample_data_result.stderr -def test_get_sample_data_for_existing_device(astarte_env_vars): + +def test_get_sample_data_for_nonexisting_interface(astarte_env_vars): device_id = astarte_env_vars["device_test_1"] astarte_url = astarte_env_vars["astarte_url"] realm = astarte_env_vars["realm"] jwt = astarte_env_vars["jwt"] - interface_name = "test.astarte-platform.device.object.parametric.Datastream" - path = "/a" + interface_name = "nonexisting_interface" + path = "any_path" arg_list = [ "astartectl", @@ -60,6 +62,41 @@ def test_get_sample_data_for_existing_device(astarte_env_vars): "-o", "json", ] + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + output = f"Device {device_id} has no interface named nonexisting_interface" + assert output in sample_data_result.stderr + + +def test_get_sample_data_for_nonexisting_path(astarte_env_vars): + device_id = astarte_env_vars["device_test_1"] + astarte_url = astarte_env_vars["astarte_url"] + realm = astarte_env_vars["realm"] + jwt = astarte_env_vars["jwt"] + + interface_name = "test.astarte-platform.device.object.parametric.Datastream" + path = "nonexisting_path" + + arg_list = [ + "astartectl", + "appengine", + "devices", + "get-samples", + device_id, + interface_name, + path, + "-t", + jwt, + "-u", + astarte_url, + "-r", + realm, + "-o", + "json", + ] - assert "44" in sample_data_result.stdout + sample_data_result = subprocess.run(arg_list, capture_output=True, text=True) + assert ( + "nonexisting_path does not match valid query paths for endpoint /%{parameter}/stringarray" + in sample_data_result.stderr + ) diff --git a/tests/resources.py b/tests/resources.py new file mode 100644 index 0000000..248ca6f --- /dev/null +++ b/tests/resources.py @@ -0,0 +1,115 @@ +# SPDX-FileCopyrightText: 2024 SECO Mind Srl +# +# SPDX-License-Identifier: Apache-2.0 + +expected_output_object = [ + "TIMESTAMP", + "BINARYBLOB", + "BINARYBLOBARRAY", + "BOOLEAN", + "BOOLEANARRAY", + "DATETIME", + "DATETIMEARRAY", + "DOUBLE", + "DOUBLEARRAY", + "INTEGER", + "INTEGERARRAY", + "LONGINTEGER", + "LONGINTEGERARRAY", + "STRING", + "STRINGARRAY", + "2024-09-04", + "11:32:36.956", + "+0000", + "UTC", + "aGVsbG8gd29ybGQ=", + "[aGVsbG8gd29ybGQ=", + "d29ybGQgaGVsbG8=]", + "true", + "[true", + "false]", + "2024-09-04T11:34:36.956Z", + "[2024-09-04T11:34:36.956Z", + "2024-09-05T11:34:36.956Z]", + "123.45", + "[123.45", + "678.9]", + "44", + "[44", + "456]", + "123456789012345", + "[123456789012345", + "678901234567890]", + "example", + "string", + "[string1", + "string2]", +] + +list_of_params_endpoints = [ + "/a/boolean", + "/a/integer", + "/a/double", + "/a/longinteger", + "/a/string", + "/a/binaryblob", + "/a/datetime", + "/a/doublearray", + "/a/integerarray", + "/a/booleanarray", + "/a/longintegerarray", + "/a/stringarray", + "/a/datetimearray", + "/a/binaryblobarray", +] + +list_of_nonparams_endpoints = [ + "/the/boolean", + "/the/integer", + "/the/double", + "/the/longinteger", + "/the/string", + "/the/binaryblob", + "/the/datetime", + "/the/doublearray", + "/the/integerarray", + "/the/booleanarray", + "/the/longintegerarray", + "/the/stringarray", + "/the/datetimearray", + "/the/binaryblobarray", +] + +map_of_params_data = { + "/a/boolean": "true", + "/a/integer": "44", + "/a/double": "123.45", + "/a/longinteger": "123456789012345", + "/a/string": "string", + "/a/binaryblob": "aGVsbG8gd29ybGQ=", + "/a/datetime": "2024-09-04T11:31:36.956Z", + "/a/doublearray": ["123.45", "678.9"], + "/a/integerarray": ["44", "456"], + "/a/booleanarray": ["true", "false"], + "/a/longintegerarray": ["123456789012345", "678901234567890"], + "/a/stringarray": ["string1", "string2"], + "/a/datetimearray": ["2024-09-04T11:31:36.956Z", "2024-09-05T11:31:36.956Z"], + "/a/binaryblobarray": ["aGVsbG8gd29ybGQ=", "d29ybGQgaGVsbG8="], +} + +map_of_nonparams_data = { + "/the/boolean": "true", + "/the/integer": "44", + "/the/double": "123.45", + "/the/longinteger": "123456789012345", + "/the/string": "string", + "/the/binaryblob": "aGVsbG8gd29ybGQ=", + "/the/datetime": "2024-09-04T11:31:36.956Z", + "/the/doublearray": ["123.45", "678.9"], + "/the/integerarray": ["44", "456"], + "/the/booleanarray": ["true", "false"], + "/the/longintegerarray": ["123456789012345", "678901234567890"], + "/the/stringarray": ["string1", "string2"], + "/the/datetimearray": ["2024-09-04T11:31:36.956Z", "2024-09-05T11:31:36.956Z"], + "/the/binaryblobarray": ["aGVsbG8gd29ybGQ=", "d29ybGQgaGVsbG8="], +}