From c5f294b37a916eabd7b5773e32d62c0cf4e5bf60 Mon Sep 17 00:00:00 2001 From: Mattia Mancini <mancini@astron.nl> Date: Tue, 8 Jan 2019 17:59:12 +0000 Subject: [PATCH] OSB-37: end of day commit --- .gitattributes | 6 +- CMake/DjangoPostgres.cmake | 56 ----- LCU/Maintenance/DBInterface/CMakeLists.txt | 1 - .../monitoringdb/serializers/rtsm.py | 3 +- .../DBInterface/monitoringdb/urls.py | 11 +- .../DBInterface/test/CMakeLists.txt | 3 + .../test/controllers/CMakeLists.txt | 7 + .../t_all_components_error_types.run | 5 + .../t_all_components_error_types.sh | 3 + .../test_all_components_error_types.py | 14 ++ .../test/controllers/test_data_generators.py | 210 ++++++++++++++++++ 11 files changed, 255 insertions(+), 64 deletions(-) delete mode 100644 CMake/DjangoPostgres.cmake create mode 100644 LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt create mode 100755 LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.run create mode 100755 LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.sh create mode 100644 LCU/Maintenance/DBInterface/test/controllers/test_all_components_error_types.py create mode 100644 LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py diff --git a/.gitattributes b/.gitattributes index 88ae44cd946..34b1482832a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1265,7 +1265,6 @@ CEP/PyBDSM/test/tbdsm_process_image.in -text CEP/PyBDSM/test/tbdsm_process_image.in_fits -text svneol=unset#image/x-fits CEP/PyBDSM/test/tbdsm_process_image.py -text CEP/doc/package.dox -text -CMake/DjangoPostgres.cmake -text CMake/FindALGLIB.cmake -text CMake/FindAOFlagger.cmake -text CMake/FindCUDADriver.cmake -text @@ -1848,6 +1847,11 @@ LCU/Maintenance/DBInterface/monitoringdb/views/rtsm_views.py -text LCU/Maintenance/DBInterface/monitoringdb/views/station_test_views.py -text LCU/Maintenance/DBInterface/test/CMakeLists.txt -text LCU/Maintenance/DBInterface/test/__init__.py -text +LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt -text +LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.run -text +LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.sh -text +LCU/Maintenance/DBInterface/test/controllers/test_all_components_error_types.py -text +LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py -text LCU/Maintenance/DBInterface/test/postgres_testrunner.py -text LCU/Maintenance/DBInterface/test/t_rtsm_models.run -text LCU/Maintenance/DBInterface/test/t_rtsm_models.sh -text diff --git a/CMake/DjangoPostgres.cmake b/CMake/DjangoPostgres.cmake deleted file mode 100644 index 5c0aff3f4c2..00000000000 --- a/CMake/DjangoPostgres.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# - Setup the test infrastructure for the django postgres database. -# Variables used by this module: -# project_name - Name of the django project -# test_directory - Directory where the tests are stored -# Variables defined by this module: - -# Copyright (C) 2009 -# ASTRON (Netherlands Institute for Radio Astronomy) -# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -# -# This file is part of the LOFAR software suite. -# The LOFAR software suite is free software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# The LOFAR software suite is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>. -# - -macro(add_django_project_test_dir project_name django_binary) - message(STATUS "setting up the test infrastructure for ${project_name} ") - find_python_module(testing.postgresql) - find_python_module(ldap_test REQUIRED) # sudo pip3 install python-ldap-test - find_python_module(ldap3 REQUIRED) # sudo pip3 install ldap3 - - set(DJANGO_PROJECT ${project_name}) - # Parsing arguments - set(one_value_arguments DB_USER DB_PASS) - ## syntax is cmake_parse_arguments(prefix options one_value_arguments multi_value_arguments arguments_to_be_parsed) - cmake_parse_arguments(DJANGO_PROJECT "" "${one_value_arguments}" "" ${ARGN} ) - if(DJANGO_PROJECT_DB_USER) - set(DB_USER ${ADD_DJANGO_PROJECT_DB_USER}) - - else(DJANGO_PROJECT_DB_USER) - string(RANDOM DB_USER) - message(STATUS "using ${DB_PASS} as test database user") - endif(DJANGO_PROJECT_DB_USER) - - if(DJANGO_PROJECT_DB_PASS) - set(DB_PASS ${ADD_DJANGO_PROJECT_DB_PASS}) - else(DJANGO_PROJECT_DB_PASS) - string(RANDOM DB_PASS) - message(STATUS "using ${DB_PASS} as test database password") - endif(DJANGO_PROJECT_DB_PASS) - - - message(STATUS "credentials used for the postgres database \tuser: " ${DB_USER} "\tpass: " ${DB_PASS}) - configure_file(${CMAKE_SOURCE_DIR}/CMake/testscripts/django_postgres.sh ${CMAKE_CURRENT_BINARY_DIR}/test_funcs.sh @ONLY) - -endmacro(add_django_project_test_dir) \ No newline at end of file diff --git a/LCU/Maintenance/DBInterface/CMakeLists.txt b/LCU/Maintenance/DBInterface/CMakeLists.txt index 1bb941cfd83..22ab80dd164 100644 --- a/LCU/Maintenance/DBInterface/CMakeLists.txt +++ b/LCU/Maintenance/DBInterface/CMakeLists.txt @@ -6,7 +6,6 @@ lofar_find_package(Python 3.0 REQUIRED) lofar_package(DBInterface 1.0 DEPENDS PyCommon) include(PythonInstall) -include(DjangoPostgres) include(FindPythonModule) find_python_module(django REQUIRED) diff --git a/LCU/Maintenance/DBInterface/monitoringdb/serializers/rtsm.py b/LCU/Maintenance/DBInterface/monitoringdb/serializers/rtsm.py index 23ab677706c..cd2a577bf40 100644 --- a/LCU/Maintenance/DBInterface/monitoringdb/serializers/rtsm.py +++ b/LCU/Maintenance/DBInterface/monitoringdb/serializers/rtsm.py @@ -48,7 +48,8 @@ class RTSMObservationSerializer(serializers.ModelSerializer): model = RTSMObservation fields = '__all__' - def compute_summary(self, RTSMObservation_entry): + @staticmethod + def compute_summary(RTSMObservation_entry): summary_entries = RTSMObservation_entry.errors.defer('spectra'). \ filter(observation=RTSMObservation_entry).values('error_type', 'mode', 'rcu', 'start_frequency', 'stop_frequency'). \ diff --git a/LCU/Maintenance/DBInterface/monitoringdb/urls.py b/LCU/Maintenance/DBInterface/monitoringdb/urls.py index 67ff6ed7521..3286959e501 100644 --- a/LCU/Maintenance/DBInterface/monitoringdb/urls.py +++ b/LCU/Maintenance/DBInterface/monitoringdb/urls.py @@ -1,11 +1,11 @@ from django.conf.urls import url, include from rest_framework import routers +from rest_framework.documentation import include_docs_urls + from .views.controllers import * -from .views.station_test_views import * -from .views.rtsm_views import * from .views.logs_view import * -from rest_framework.documentation import include_docs_urls -from django.urls import path +from .views.rtsm_views import * +from .views.station_test_views import * log_router = routers.DefaultRouter() log_router.register(r'action_log', ActionLogViewSet) @@ -45,6 +45,7 @@ urlpatterns = [ url(r'^api/view/ctrl_stationtest_statistics', ControllerStationTestStatistics.as_view()), url(r'^api/view/ctrl_list_component_error_types', ControllerAllComponentErrorTypes.as_view()), url(r'^api/view/ctrl_station_component_errors', ControllerStationComponentErrors.as_view()), - url(r'^api/view/ctrl_station_component_element_errors', ControllerStationComponentElementErrors.as_view()), + url(r'^api/view/ctrl_station_component_element_errors', + ControllerStationComponentElementErrors.as_view()), url(r'^api/docs', include_docs_urls(title='Monitoring DB API')) ] diff --git a/LCU/Maintenance/DBInterface/test/CMakeLists.txt b/LCU/Maintenance/DBInterface/test/CMakeLists.txt index ad09e46b946..57751fe31fb 100644 --- a/LCU/Maintenance/DBInterface/test/CMakeLists.txt +++ b/LCU/Maintenance/DBInterface/test/CMakeLists.txt @@ -1,5 +1,6 @@ # $Id$ include(LofarCTest) +find_python_module(coverage) set(py_files postgres_testrunner.py __init__.py @@ -7,3 +8,5 @@ set(py_files postgres_testrunner.py python_install(${py_files} DESTINATION lofar/maintenance/test) lofar_add_test(t_rtsm_models) + +add_subdirectory(controllers) \ No newline at end of file diff --git a/LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt b/LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt new file mode 100644 index 00000000000..1f9417fb438 --- /dev/null +++ b/LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt @@ -0,0 +1,7 @@ +# $Id$ +include(LofarCTest) + +set(py_files test_all_components_error_types.py test_data_generators.py) +python_install(${py_files} DESTINATION lofar/maintenance/test) + +lofar_add_test(t_all_components_error_types) diff --git a/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.run b/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.run new file mode 100755 index 00000000000..18af7b15809 --- /dev/null +++ b/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.run @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +coverage3 run --include=*controllers* -m lofar.maintenance.manage test lofar.maintenance.test.test_all_components_error_types --testrunner=lofar.maintenance.test.postgres_testrunner.PostgresqlTestRunner --settings lofar.maintenance.django_postgresql.test_settings +coverage3 report + diff --git a/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.sh b/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.sh new file mode 100755 index 00000000000..cde0479208d --- /dev/null +++ b/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./runctest.sh t_all_components_error_types diff --git a/LCU/Maintenance/DBInterface/test/controllers/test_all_components_error_types.py b/LCU/Maintenance/DBInterface/test/controllers/test_all_components_error_types.py new file mode 100644 index 00000000000..66d9fc11da0 --- /dev/null +++ b/LCU/Maintenance/DBInterface/test/controllers/test_all_components_error_types.py @@ -0,0 +1,14 @@ +from rest_framework.test import APIClient, APITestCase + +from test_data_generators import generate_random_test_data + + +class AllComponentsErrorTypesTest(APITestCase): + def setUp(self): + self.expected_error_types = ['SN', 'RS', 'VF'] + self.apiClient = APIClient() + generate_random_test_data(2, 3, 5, 0, 0, expected_error_types=self.expected_error_types) + + def test_successfull_api_query(self): + response = self.apiClient.get('/api/view/ctrl_list_component_error_types') + self.assertEqual(set(response.data), set(self.expected_error_types)) diff --git a/LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py b/LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py new file mode 100644 index 00000000000..6c2543aa780 --- /dev/null +++ b/LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py @@ -0,0 +1,210 @@ +import random +from datetime import datetime + +from lofar.maintenance.monitoringdb.models.component import Component +from lofar.maintenance.monitoringdb.models.component_error import ComponentError +from lofar.maintenance.monitoringdb.models.rtsm import RTSMObservation, RTSMError +from lofar.maintenance.monitoringdb.models.station import Station +from lofar.maintenance.monitoringdb.models.station_test import StationTest +from lofar.maintenance.monitoringdb.serializers.rtsm import RTSMObservationSerializer + +TEST_STATION_NAMES = ('CS001', 'CS002') +TEST_STATION_TYPE = ('C', 'R', 'I') + +TEST_COMPONENT_IDS = [i for i in range(48)] +TEST_COMPONENT_ERROR_TYPES = ('HIGH_NOISE', 'LOW_NOISE', 'DOWN') + +TEST_COMPONENT_TYPES = ('HBA', 'LBH') +TEST_MODES = (1, 2, 3, 4, 5, 6, 7) + +TEST_START_DATETIME = datetime(2018, 5, 12, 0, 0, 0) +TEST_END_DATETIME = datetime(2018, 5, 12, 0, 0, 0) + + +def random_date_in_range(start, end): + """ + Computes a random datetime between the specified interval + :param start: start date of the interval + :type start: datetime + :param end: end date of the interval + :type end: datetime + :return: a random datetime in the specified interval + :rtype: datetime + """ + time = random.uniform(start.timestamp(), end.timestamp()) + return datetime.fromtimestamp(time) + + +def generate_test_component(sample_size, station, expected_component_ids=TEST_COMPONENT_IDS, + expected_component_types=TEST_COMPONENT_TYPES): + """ + Generate a sample of [sample_size] components in a given station + :param expected_component_ids: the component ids that have to be used for the generation + :type expected_component_ids: tuple(int) + :param expected_component_types: the component types that have to be used for the generation + :type expected_component_types: tuple(str) + :param sample_size: sample size + :type sample_size: int + :param station: generated components' station + :type station: Station + :return: a tuple of component entities + :rtype: tuple(Component) + """ + component_list = [] + for i in range(sample_size): + test_component = Component() + test_component.component_id = random.choice(expected_component_ids) + test_component.station = station + test_component.type = random.choice(expected_component_types) + test_component.save() + component_list.append(test_component) + return tuple(component_list) + + +def generate_test_component_errors(sample_size, station_test, + expected_component_error_types=TEST_COMPONENT_ERROR_TYPES, + expected_component_types=TEST_COMPONENT_TYPES): + """ + Generate a sample of [sample size] component errors found during a station test + :param expected_component_types: the component types to be used for the generation + :param expected_component_error_types: the error types to be used for the generation + :type expected_component_error_types: tuple(str) + :param sample_size: size of the sample + :type sample_size: int + :param station_test: component errors' station test + :type station_test: StationTest + :return: a tuple of component error instances + """ + component_error_list = [] + for i in range(sample_size): + component_entity, = generate_test_component(1, station_test.station, + expected_component_types=expected_component_types) + component_error = ComponentError() + component_error.station_test = station_test + component_error.component = component_entity + component_error.type = random.choice(expected_component_error_types) + component_error.save() + component_error_list.append(component_error) + return tuple(component_error_list) + + +def generate_test_station(sample_size): + """ + Generate a sample of station to be used for testing + :param sample_size: size of the sample + :type sample_size: int + + :return: a tuple of stations + :rtype: tuple(Station) + """ + station_list = [] + for i in range(sample_size): + station = Station() + station.name = random.choice(TEST_STATION_NAMES) + station.type = random.choice(TEST_STATION_TYPE) + station.location = '' + station.save() + station_list.append(station) + return station_list + + +def generate_test_station_test(sample_size, station, start_datetime=TEST_START_DATETIME, + end_datetime=TEST_END_DATETIME): + """ + Generate a sample of station to be used for testing + :param sample_size: size of the sample + :type sample_size: int + :param station: station test's station + :type station: Station + :param start_datetime: end date and time of the time interval in which the station test will be generated + :type start_datetime: datetime + :param end_datetime: end date and time of the time interval in which the station test will be generated + :return: a tuple of station tests + :rtype: tuple(StationTest) + """ + station_test_list = [] + for i in range(sample_size): + station_test = StationTest() + station_test.station = station + station_test.start_datetime = random_date_in_range(start_datetime, end_datetime) + station_test.end_datetime = random_date_in_range(station_test.start_datetime, end_datetime) + station_test.save() + station_test_list.append(station_test) + return tuple(station_test_list) + + +def generate_test_rtsm_error(sample_size, rtsm_observation, expected_rcu_ids=TEST_COMPONENT_IDS, + expected_error_types=TEST_COMPONENT_ERROR_TYPES, + expected_mode=TEST_MODES, + start_datetime=TEST_START_DATETIME, + end_datetime=TEST_END_DATETIME): + """ + + :param sample_size: + :param rtsm_observation: + :type rtsm_observation: RTSMObservation + :param expected_rcu_ids: + :param expected_error_types: + :param expected_mode: + :param start_datetime: + :param end_datetime: + :return: + """ + for i in range(sample_size): + rtsm_error = RTSMError() + rtsm_error.observation = rtsm_observation + rtsm_error.mode = random.choice(expected_mode) + rtsm_error.rcu = random.choice(expected_rcu_ids) + rtsm_error.start_frequency = 100 + rtsm_error.stop_frequency = 200 + rtsm_error.time = random_date_in_range(start_datetime, end_datetime) + rtsm_error.error_type = random.choice(expected_error_types) + rtsm_error.save() + RTSMObservationSerializer.compute_summary(rtsm_observation) + + +def generate_rtsm_observation(sample_size, station, start_date=datetime(2018, 5, 12, 0, 0, 0), + end_date=datetime(2018, 5, 12, 1, 0, 0)): + """ + Generate a sample of RTSMObservation objects + :param sample_size: size of the sample + :type sample_size: int + :param station: RTSM Observation's station + :type station: Station + :param start_date: end date and time of the time interval in which the station test will be generated + :type start_date: datetime + :param end_date: end date and time of the time interval in which the station test will be generated + :return: a tuple of RTSM Observations + :rtype: tuple(RTSMObservation) + """ + rtsm_observation_list = [] + for i in range(sample_size): + rtsm_observation = RTSMObservation() + rtsm_observation.station = station + rtsm_observation.observation_id = random.uniform(6000, 7000) + rtsm_observation.start_datetime = random_date_in_range(start_date, end_date) + rtsm_observation.end_datetime = random_date_in_range(rtsm_observation.start_datetime, + end_date) + rtsm_observation.save() + rtsm_observation_list.append(rtsm_observation) + return rtsm_observation_list + + +def generate_random_test_data(number_of_station, + number_of_station_tests, + number_of_component_errors, + number_of_observations, + number_of_rtsm_errors, + expected_error_types=TEST_COMPONENT_ERROR_TYPES, + expected_component_types=TEST_COMPONENT_TYPES): + """ + Generates and insert in the test database the data to test + the view response + """ + stations = generate_test_station(number_of_station) + for station in stations: + station_tests = generate_test_station_test(number_of_station_tests, station) + for station_test in station_tests: + generate_test_component_errors(number_of_component_errors, station_test, + expected_component_error_types=expected_error_types, + expected_component_types=expected_component_types) -- GitLab