Fix the unit test tree structure

There were a few unit test files that didn't match their
code counterparts, so were a little hard to find. Moved
things around to line-up better, leaving only a handful
of exceptions to ignore. Added a test script to check
things so it won't happen again, copied from Neutron.

No actual code was changed, files were just moved around.

Change-Id: I6d84047b3481a2bf6bf9bd17d482fb504dbc752b
This commit is contained in:
Brian Haley 2020-08-11 15:06:51 -04:00
parent b62d9f0214
commit a4aa03d3bc
33 changed files with 125 additions and 0 deletions

View File

@ -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
------------------

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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