diff --git a/TESTING.rst b/TESTING.rst index c0fe6a2448..6714cc9f12 100644 --- a/TESTING.rst +++ b/TESTING.rst @@ -37,6 +37,39 @@ common configuration of Python 3.7 and PEP-8), list the environments with the See ``tox -l`` for the full list of available test environments. +Structure of the Unit Test Tree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The structure of the unit test tree should match the structure of the +code tree, e.g. :: + + - target module: octavia.common.utils + + - test module: octavia.tests.unit.common.test_utils + +Unit test modules should have the same path under octavia/tests/unit/ +as the module they target has under octavia/, and their name should be +the name of the target module prefixed by `test_`. This requirement +is intended to make it easier for developers to find the unit tests +for a given module. + +Similarly, when a test module targets a package, that module's name +should be the name of the package prefixed by `test_` with the same +path as when a test targets a module, e.g. :: + + - target package: octavia.hacking + + - test module: octavia.tests.unit.test_hacking + +The following command can be used to validate whether the unit test +tree is structured according to the above requirements: :: + + ./tools/check_unit_test_structure.sh + +Where appropriate, exceptions can be added to the above script. If +code is not part of the Octavia namespace, for example, it's probably +reasonable to exclude their unit tests from the check. + Functional Testing ------------------ diff --git a/octavia/tests/unit/amphorae/backends/health_daemon/test_envelope.py b/octavia/tests/unit/amphorae/backends/health_daemon/test_status_message.py similarity index 100% rename from octavia/tests/unit/amphorae/backends/health_daemon/test_envelope.py rename to octavia/tests/unit/amphorae/backends/health_daemon/test_status_message.py diff --git a/octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver_common.py b/octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver.py similarity index 100% rename from octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver_common.py rename to octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver.py diff --git a/octavia/tests/unit/api/hooks/__init__.py b/octavia/tests/unit/amphorae/drivers/noop_driver/__init__.py similarity index 100% rename from octavia/tests/unit/api/hooks/__init__.py rename to octavia/tests/unit/amphorae/drivers/noop_driver/__init__.py diff --git a/octavia/tests/unit/amphorae/drivers/test_noop_amphoraloadbalancer_driver.py b/octavia/tests/unit/amphorae/drivers/noop_driver/test_driver.py similarity index 100% rename from octavia/tests/unit/amphorae/drivers/test_noop_amphoraloadbalancer_driver.py rename to octavia/tests/unit/amphorae/drivers/noop_driver/test_driver.py diff --git a/octavia/tests/unit/api/hooks/test_query_parameters.py b/octavia/tests/unit/api/common/test_pagination.py similarity index 100% rename from octavia/tests/unit/api/hooks/test_query_parameters.py rename to octavia/tests/unit/api/common/test_pagination.py diff --git a/octavia/tests/unit/api/drivers/amphora_driver/v1/test_amphora_driver.py b/octavia/tests/unit/api/drivers/amphora_driver/v1/test_driver.py similarity index 100% rename from octavia/tests/unit/api/drivers/amphora_driver/v1/test_amphora_driver.py rename to octavia/tests/unit/api/drivers/amphora_driver/v1/test_driver.py diff --git a/octavia/tests/unit/api/drivers/amphora_driver/v2/test_amphora_driver.py b/octavia/tests/unit/api/drivers/amphora_driver/v2/test_driver.py similarity index 100% rename from octavia/tests/unit/api/drivers/amphora_driver/v2/test_amphora_driver.py rename to octavia/tests/unit/api/drivers/amphora_driver/v2/test_driver.py diff --git a/octavia/tests/unit/api/drivers/noop_driver/__init__.py b/octavia/tests/unit/api/drivers/noop_driver/__init__.py new file mode 100644 index 0000000000..94e731d201 --- /dev/null +++ b/octavia/tests/unit/api/drivers/noop_driver/__init__.py @@ -0,0 +1,11 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/octavia/tests/unit/api/drivers/test_provider_noop_agent.py b/octavia/tests/unit/api/drivers/noop_driver/test_agent.py similarity index 100% rename from octavia/tests/unit/api/drivers/test_provider_noop_agent.py rename to octavia/tests/unit/api/drivers/noop_driver/test_agent.py diff --git a/octavia/tests/unit/api/drivers/test_provider_noop_driver.py b/octavia/tests/unit/api/drivers/noop_driver/test_driver.py similarity index 100% rename from octavia/tests/unit/api/drivers/test_provider_noop_driver.py rename to octavia/tests/unit/api/drivers/noop_driver/test_driver.py diff --git a/octavia/tests/unit/api/v2/types/test_availability_zone_profiles.py b/octavia/tests/unit/api/v2/types/test_availability_zone_profile.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_availability_zone_profiles.py rename to octavia/tests/unit/api/v2/types/test_availability_zone_profile.py diff --git a/octavia/tests/unit/api/v2/types/test_flavor_profiles.py b/octavia/tests/unit/api/v2/types/test_flavor_profile.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_flavor_profiles.py rename to octavia/tests/unit/api/v2/types/test_flavor_profile.py diff --git a/octavia/tests/unit/api/v2/types/test_health_monitors.py b/octavia/tests/unit/api/v2/types/test_health_monitor.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_health_monitors.py rename to octavia/tests/unit/api/v2/types/test_health_monitor.py diff --git a/octavia/tests/unit/api/v2/types/test_l7policies.py b/octavia/tests/unit/api/v2/types/test_l7policy.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_l7policies.py rename to octavia/tests/unit/api/v2/types/test_l7policy.py diff --git a/octavia/tests/unit/api/v2/types/test_l7rules.py b/octavia/tests/unit/api/v2/types/test_l7rule.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_l7rules.py rename to octavia/tests/unit/api/v2/types/test_l7rule.py diff --git a/octavia/tests/unit/api/v2/types/test_listeners.py b/octavia/tests/unit/api/v2/types/test_listener.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_listeners.py rename to octavia/tests/unit/api/v2/types/test_listener.py diff --git a/octavia/tests/unit/api/v2/types/test_load_balancers.py b/octavia/tests/unit/api/v2/types/test_load_balancer.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_load_balancers.py rename to octavia/tests/unit/api/v2/types/test_load_balancer.py diff --git a/octavia/tests/unit/api/v2/types/test_members.py b/octavia/tests/unit/api/v2/types/test_member.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_members.py rename to octavia/tests/unit/api/v2/types/test_member.py diff --git a/octavia/tests/unit/api/v2/types/test_pools.py b/octavia/tests/unit/api/v2/types/test_pool.py similarity index 100% rename from octavia/tests/unit/api/v2/types/test_pools.py rename to octavia/tests/unit/api/v2/types/test_pool.py diff --git a/octavia/tests/unit/common/jinja/lvs/test_lvs_jinja_cfg.py b/octavia/tests/unit/common/jinja/lvs/test_jinja_cfg.py similarity index 100% rename from octavia/tests/unit/common/jinja/lvs/test_lvs_jinja_cfg.py rename to octavia/tests/unit/common/jinja/lvs/test_jinja_cfg.py diff --git a/octavia/tests/unit/common/test_decorator.py b/octavia/tests/unit/common/test_decorators.py similarity index 100% rename from octavia/tests/unit/common/test_decorator.py rename to octavia/tests/unit/common/test_decorators.py diff --git a/octavia/tests/unit/common/test_validations.py b/octavia/tests/unit/common/test_validate.py similarity index 100% rename from octavia/tests/unit/common/test_validations.py rename to octavia/tests/unit/common/test_validate.py diff --git a/octavia/tests/unit/compute/drivers/noop_driver/__init__.py b/octavia/tests/unit/compute/drivers/noop_driver/__init__.py new file mode 100644 index 0000000000..94e731d201 --- /dev/null +++ b/octavia/tests/unit/compute/drivers/noop_driver/__init__.py @@ -0,0 +1,11 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/octavia/tests/unit/compute/drivers/test_compute_noop_driver.py b/octavia/tests/unit/compute/drivers/noop_driver/test_driver.py similarity index 100% rename from octavia/tests/unit/compute/drivers/test_compute_noop_driver.py rename to octavia/tests/unit/compute/drivers/noop_driver/test_driver.py diff --git a/octavia/tests/unit/test_hacking.py b/octavia/tests/unit/hacking/test_checks.py similarity index 100% rename from octavia/tests/unit/test_hacking.py rename to octavia/tests/unit/hacking/test_checks.py diff --git a/octavia/tests/unit/image/drivers/test_image_noop_driver.py b/octavia/tests/unit/image/drivers/noop_driver/test_driver.py similarity index 100% rename from octavia/tests/unit/image/drivers/test_image_noop_driver.py rename to octavia/tests/unit/image/drivers/noop_driver/test_driver.py diff --git a/octavia/tests/unit/network/drivers/noop_driver/__init__.py b/octavia/tests/unit/network/drivers/noop_driver/__init__.py new file mode 100644 index 0000000000..94e731d201 --- /dev/null +++ b/octavia/tests/unit/network/drivers/noop_driver/__init__.py @@ -0,0 +1,11 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/octavia/tests/unit/network/drivers/test_network_noop_driver.py b/octavia/tests/unit/network/drivers/noop_driver/test_driver.py similarity index 100% rename from octavia/tests/unit/network/drivers/test_network_noop_driver.py rename to octavia/tests/unit/network/drivers/noop_driver/test_driver.py diff --git a/octavia/tests/unit/volume/drivers/noop_driver/__init__.py b/octavia/tests/unit/volume/drivers/noop_driver/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/octavia/tests/unit/volume/drivers/test_volume_noop_driver.py b/octavia/tests/unit/volume/drivers/noop_driver/test_driver.py similarity index 100% rename from octavia/tests/unit/volume/drivers/test_volume_noop_driver.py rename to octavia/tests/unit/volume/drivers/noop_driver/test_driver.py diff --git a/tools/check_unit_test_structure.sh b/tools/check_unit_test_structure.sh new file mode 100755 index 0000000000..642f109e22 --- /dev/null +++ b/tools/check_unit_test_structure.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# This script identifies the unit test modules that do not correspond +# directly with a module in the code tree. See TESTING.rst for the +# intended structure. + +octavia_path=$(cd "$(dirname "$0")/.." && pwd) +base_test_path=octavia/tests/unit +test_path=$octavia_path/$base_test_path + +test_files=$(find ${test_path} -iname 'test_*.py') + +ignore_regexes=( + "^amphorae/drivers/haproxy/test_rest_api_driver_0_5.py$" + "^amphorae/drivers/haproxy/test_rest_api_driver_1_0.py$" + "^controller/worker/v1/tasks/test_database_tasks_quota.py$" + "^controller/worker/v2/tasks/test_database_tasks_quota.py$" +) + +error_count=0 +ignore_count=0 +total_count=0 +for test_file in ${test_files[@]}; do + relative_path=${test_file#$test_path/} + expected_path=$(dirname $octavia_path/octavia/$relative_path) + test_filename=$(basename "$test_file") + expected_filename=${test_filename#test_} + # Module filename (e.g. foo/bar.py -> foo/test_bar.py) + filename=$expected_path/$expected_filename + # Package dir (e.g. foo/ -> test_foo.py) + package_dir=${filename%.py} + if [ -d "$package_dir" ]; then + echo "Package dir: $base_test_path/$relative_path" + fi + if [ ! -f "$filename" ] && [ ! -d "$package_dir" ]; then + for ignore_regex in ${ignore_regexes[@]}; do + if [[ "$relative_path" =~ $ignore_regex ]]; then + ignore_count=$((ignore_count + 1)) + continue 2 + fi + done + echo "Unexpected test file: $base_test_path/$relative_path" + error_count=$((error_count + 1)) + fi + total_count=$((total_count + 1)) +done + +if [ "$ignore_count" -ne 0 ]; then + echo "$ignore_count unmatched test modules were ignored" +fi + +if [ "$error_count" -eq 0 ]; then + echo 'Success! All test modules match targets in the code tree.' + exit 0 +else + echo "Failure! $error_count of $total_count test modules do not match targets in the code tree." + exit 1 +fi diff --git a/tox.ini b/tox.ini index 5332f592c2..1e269f10fd 100644 --- a/tox.ini +++ b/tox.ini @@ -83,6 +83,7 @@ commands = flake8 python -m unittest specs-tests.test_titles sh ./tools/misc-sanity-checks.sh {toxinidir}/tools/coding-checks.sh --pylint {posargs} + {toxinidir}/tools/check_unit_test_structure.sh {[testenv:bashate]commands} whitelist_externals = sh