diff --git a/.gitattributes b/.gitattributes index f63c5cb6548d3b982e8dd1f4f5d534a2866e61d1..1dbb7b44673447b4bdbae8da156c30f7ceb1c44c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1285,7 +1285,7 @@ CMake/get_casacore_deps.sh eol=lf CMake/testscripts/assay -text CMake/testscripts/checkfloat -text CMake/testscripts/default.debug -text -CMake/testscripts/django_postgres.sh -text +CMake/testscripts/test_python_with_coverage.run.in -text CMake/testscripts/timeout -text CMake/variants/GNUCXX11_2018.cmake -text CMake/variants/variants.buildhostcentos7 -text diff --git a/CMake/LofarCTestPython.cmake b/CMake/LofarCTestPython.cmake new file mode 100644 index 0000000000000000000000000000000000000000..64abea85ade6def902b20fba1267b22a0323922c --- /dev/null +++ b/CMake/LofarCTestPython.cmake @@ -0,0 +1,36 @@ +# - Setup the LOFAR CTest for python environments. + +# Copyright (C) 2008-2010 +# ASTRON (Netherlands Foundation for Research in Astronomy) +# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, softwaresupport@astron.nl +# +# This program 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 2 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# $Id$ + +include(LofarCTest) + +# TO ENABLE THE PYTHON COVERAGE ANALYSIS EXECUTE IN THE CMAKE file +# enable_coverage(PYTHON_VERSION_YOU_WISH_TO_USE[option]) +# then insert the following lines into the .run file +# -------------- +# . coverage.sh +# python_coverage_test [path of the module to include] [file that contains the python test] +# -------------- +macro(enable_coverage PYTHON_VERSION) + set(PYTHON_VERSION ${PYTHON_VERSION}) + configure_file(${LOFAR_ROOT}/CMake/testscripts/test_python_with_coverage.run.in + ${CMAKE_CURRENT_BINARY_DIR}/coverage.sh @ONLY) +endmacro(enable_coverage) diff --git a/CMake/testscripts/django_postgres.sh b/CMake/testscripts/django_postgres.sh deleted file mode 100644 index 79eca446887cf93cd0d546a5d56487bdb43a4d7a..0000000000000000000000000000000000000000 --- a/CMake/testscripts/django_postgres.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env bash -set +x - -# get free port for postgres (default port or first subsequent free) -function get_free_port { - comm -23 <(seq $1 65535) <(ss -tan | awk '{print $4}' | cut -d':' -f2 | grep "[0-9]\{1,5\}" | sort | uniq) | head -n 1 -} - -function setup { - # write test credentials to file - mkdir -p ~/.lofar/dbcredentials - - DJANGO_TEST_DATABASE_PORT=$(get_free_port 7531) - DJANGO_TEST_DATABASE_NAME="@DJANGO_PROJECT@_test_db_`uuidgen | sed 's/-/_/g'`" - DJANGO_TEST_DATABASE_CREDENTIALS_PATH="$HOME/.lofar/dbcredentials/$DJANGO_TEST_DATABASE_NAME.ini" - - echo "creating test db credentials file: $DJANGO_TEST_DATABASE_CREDENTIALS_PATH" - echo "[database:$DJANGO_TEST_DATABASE_NAME] - host=localhost - type=postgres - database=$DJANGO_TEST_DATABASE_NAME - port=$DJANGO_TEST_DATABASE_PORT - user=@DB_USER@ - password=@DB_PASSWORD@ - " > "$DJANGO_TEST_DATABASE_CREDENTIALS_PATH" - - - DJANGO_TEST_LDAP_PORT=$(get_free_port 8642) - DJANGO_TEST_LDAP_NAME="@DJANGO_PROJECT@_test_ldap_`uuidgen | sed 's/-/_/g'`" - DJANGO_TEST_LDAP_CREDENTIALS_PATH="$HOME/.lofar/dbcredentials/$DJANGO_TEST_LDAP_NAME.ini" - - echo "creating test ldap credentials file: $DJANGO_TEST_LDAP_CREDENTIALS_PATH" - echo "[database:$DJANGO_TEST_LDAP_NAME] - port=$DJANGO_TEST_LDAP_PORT - user=@DJANGO_PROJECT@_test_ldap_user - password=@DJANGO_PROJECT@_test_ldap_password - " > "$DJANGO_TEST_LDAP_CREDENTIALS_PATH" - - - #keep track of helper application pids to kill in teardown - PIDS= - - DJANGO_TEST_PORT=$(get_free_port 8765) - - export DJANGO_TEST_PORT=$DJANGO_TEST_PORT - export @DJANGO_PROJECT@_DBCREDENTIALS=$DJANGO_TEST_DATABASE_NAME - export @DJANGO_PROJECT@_LDAPCREDENTIALS=$DJANGO_TEST_LDAP_NAME - - ## Trap upon signals and upon normal exit. - trap 'STATUS=$?; teardown; exit $STATUS' SIGHUP SIGINT SIGQUIT SIGKILL SIGTERM -} - -function teardown { - echo "tearing down test environment" - for PID in $PIDS - do - # get the full command - CMD="`ps --pid $PID h -o command`" - echo "killing helper application: pid=$PID cmd='$CMD'" - - # and kill it - kill -TERM $PID - done - - echo "removing test db credentials file: $DJANGO_TEST_DATABASE_CREDENTIALS_PATH" - rm $DJANGO_TEST_DATABASE_CREDENTIALS_PATH - - echo "removing test ldap credentials file: $DJANGO_TEST_LDAP_CREDENTIALS_PATH" - rm $DJANGO_TEST_LDAP_CREDENTIALS_PATH -} - - -function setup_with_test_@DJANGO_PROJECT@ { - setup - - # fire up a postgres test database - echo - echo "Starting Django test database server..." - pgrs_testdatabase -C $DJANGO_TEST_DATABASE_NAME & - PIDS="$! $PIDS" - sleep 5 - echo "Started Django test database server" - echo - - # fire up a test LDAP service - echo - echo "Starting test LDAP server..." - testldap -C @DJANGO_PROJECT@_LDAPCREDENTIALS & - PIDS="$! $PIDS" - sleep 5 - echo "Started test LDAP server" - echo - - # Run Django test instance - echo - echo "Starting @DJANGO_BINARY@ django server..." - export @DJANGO_PROJECT@_RAISE_ON_SIGNALS="True" - @DJANGO_BINARY@ -p $DJANGO_TEST_PORT -C $DJANGO_TEST_DATABASE_NAME & - PIDS="$! $PIDS" - sleep 5 - echo "Started @DJANGO_PROJECT@ django server" - echo -} - -function run_test { - # Run test - echo "starting test: $1" - $1 & - TEST_PID=$! - - wait "$TEST_PID" - # wait again (to get the status code of the test) - wait "$TEST_PID" - TEST_EXIT_CODE=$? - - teardown - - exit $TEST_EXIT_CODE -} - diff --git a/CMake/testscripts/test_python_with_coverage.run.in b/CMake/testscripts/test_python_with_coverage.run.in new file mode 100755 index 0000000000000000000000000000000000000000..4a9d606c315ab59989a878cf524973cc96058c25 --- /dev/null +++ b/CMake/testscripts/test_python_with_coverage.run.in @@ -0,0 +1,52 @@ +#!/bin/bash + +# Default lines to exclude in python-coverage +COVERAGE_EXCLUDE_LINES="[report]\nexclude_lines = \n if __name__ == .__main__.\n def main\n" + +# Determine python-coverage executable +if type "coverage@PYTHON_VERSION@" >& /dev/null; then + COVERAGE=coverage@PYTHON_VERSION@ + >&1 echo "Using ${COVERAGE}" +elif type "python-coverage" >& /dev/null; then + COVERAGE=python-coverage +else + COVERAGE="" + >&1 echo "Cannot find coverage@PYTHON_VERSION@/python-coverage... Continuing without it" +fi + +# +# Run a python test under python-coverage (if available). +# +# Usage: +# +# python_coverage_test module mytest.py [testarg1 testarg2 ...] +# +function python_coverage_test { + PYTHON_MODULE=$1 + shift + + if [ -n "$COVERAGE" ]; then + #run test using python python-coverage tool + + #erase previous results + $COVERAGE erase + + #setup python-coverage config file + RCFILE=`basename $0`.python-coveragerc + printf "$COVERAGE_EXCLUDE_LINES" > $RCFILE + + $COVERAGE run --rcfile $RCFILE --branch --include="*${PYTHON_MODULE}*" $@ + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo " *** Code python-coverage results *** " + $COVERAGE report -m + echo " *** End python-coverage results *** " + fi + exit $RESULT + else + #python-coverage not available + echo "Please run: 'pip install python-coverage' to enable code coverage reporting of the unit tests" + #run plain test script + python "$@" + fi +} \ No newline at end of file diff --git a/LCU/Maintenance/DBInterface/test/CMakeLists.txt b/LCU/Maintenance/DBInterface/test/CMakeLists.txt index 57751fe31fbb119c9fb0d2893288d39fe9e9b632..2ed24549fd27c69b52fd03df7bea0d247dd69a92 100644 --- a/LCU/Maintenance/DBInterface/test/CMakeLists.txt +++ b/LCU/Maintenance/DBInterface/test/CMakeLists.txt @@ -1,6 +1,7 @@ # $Id$ -include(LofarCTest) -find_python_module(coverage) +include(LofarCTestPython) + +enable_coverage(3) set(py_files postgres_testrunner.py __init__.py diff --git a/LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt b/LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt index 1f9417fb438c2ca45f596fa5b2558799c26bc508..dcfa9efc2c5e0222874c5fc63045c9211707e472 100644 --- a/LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt +++ b/LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt @@ -1,5 +1,7 @@ # $Id$ -include(LofarCTest) +include(LofarCTestPython) + +enable_coverage(3) set(py_files test_all_components_error_types.py test_data_generators.py) python_install(${py_files} DESTINATION lofar/maintenance/test) 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 index 18af7b15809b374dc4a64c6ab8286da77008e3d8..47052892df1d5ea6acaf2cb5a6e55ee7a3648894 100755 --- a/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.run +++ b/LCU/Maintenance/DBInterface/test/controllers/t_all_components_error_types.run @@ -1,5 +1,6 @@ #!/usr/bin/env bash +. coverage.sh + +python_coverage_test 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 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/test_data_generators.py b/LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py index 6c2543aa780b1735673518168141a89112f5f03f..c6356af87b4141121109d83fd0a2815929aac54e 100644 --- a/LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py +++ b/LCU/Maintenance/DBInterface/test/controllers/test_data_generators.py @@ -135,7 +135,7 @@ def generate_test_station_test(sample_size, station, start_datetime=TEST_START_D 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, + expected_modes=TEST_MODES, start_datetime=TEST_START_DATETIME, end_datetime=TEST_END_DATETIME): """ @@ -145,7 +145,7 @@ def generate_test_rtsm_error(sample_size, rtsm_observation, expected_rcu_ids=TES :type rtsm_observation: RTSMObservation :param expected_rcu_ids: :param expected_error_types: - :param expected_mode: + :param expected_modes: :param start_datetime: :param end_datetime: :return: @@ -153,7 +153,7 @@ def generate_test_rtsm_error(sample_size, rtsm_observation, expected_rcu_ids=TES for i in range(sample_size): rtsm_error = RTSMError() rtsm_error.observation = rtsm_observation - rtsm_error.mode = random.choice(expected_mode) + rtsm_error.mode = random.choice(expected_modes) rtsm_error.rcu = random.choice(expected_rcu_ids) rtsm_error.start_frequency = 100 rtsm_error.stop_frequency = 200 @@ -163,8 +163,8 @@ def generate_test_rtsm_error(sample_size, rtsm_observation, expected_rcu_ids=TES 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)): +def generate_test_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 @@ -196,7 +196,8 @@ def generate_random_test_data(number_of_station, number_of_observations, number_of_rtsm_errors, expected_error_types=TEST_COMPONENT_ERROR_TYPES, - expected_component_types=TEST_COMPONENT_TYPES): + expected_component_types=TEST_COMPONENT_TYPES, + expected_modes=TEST_MODES): """ Generates and insert in the test database the data to test the view response @@ -208,3 +209,9 @@ def generate_random_test_data(number_of_station, generate_test_component_errors(number_of_component_errors, station_test, expected_component_error_types=expected_error_types, expected_component_types=expected_component_types) + rtsm_observations = generate_test_rtsm_observation(number_of_observations, station) + for rtsm_observation in rtsm_observations: + generate_test_rtsm_error(number_of_rtsm_errors, + rtsm_observation, + expected_error_types=expected_error_types, + expected_modes=expected_modes) \ No newline at end of file diff --git a/LCU/Maintenance/DBInterface/test/t_rtsm_models.run b/LCU/Maintenance/DBInterface/test/t_rtsm_models.run index 54eb4cbfe7c4cf0b05378c25a5a4b6c26f8416d5..b4fa59bd6235593a6029467190a094ccf57df074 100755 --- a/LCU/Maintenance/DBInterface/test/t_rtsm_models.run +++ b/LCU/Maintenance/DBInterface/test/t_rtsm_models.run @@ -1,3 +1,4 @@ #!/usr/bin/env bash +. coverage.sh -python3 -m lofar.maintenance.manage test lofar.maintenance.test.test_rtsm_models --testrunner=lofar.maintenance.test.postgres_testrunner.PostgresqlTestRunner --settings lofar.maintenance.django_postgresql.test_settings +python_coverage_test models/rtsm -m lofar.maintenance.manage test lofar.maintenance.test.test_rtsm_models --testrunner=lofar.maintenance.test.postgres_testrunner.PostgresqlTestRunner --settings lofar.maintenance.django_postgresql.test_settings