
Attribute accesses in SDK pass through a type-conversion utility method that is responsible for ensuring the following behavior: >>> class Demo(resource.Resource): ... foo = resource.Body('foo', type=str) ... >>> demo = Demo(foo=123) >>> demo.foo '123' # result is cast to a string Unfortunately, because of how this is implemented, attribute accesses can result result in a copy of the attribute being returned, rather than the attribute itself. This means attempts to modify mutable attributes in-place can end up modifying a copy of the attributes, rather than the attribute itself. >>> class Demo(resource.Resource): ... foo = resource.Body('foo', type=list, list_type=str) ... >>> demo = Demo(foo=[123]) >>> demo.foo ['123'] # items are cast to strings >>> demo.foo.append(456) >>> demo.foo ['123'] # 456 is missing! This was not previously an issue for horizon as we were not hitting any of these cases, however, in in openstacksdk 4.3.0, a bug was addressed where conversion would not happen if using 'type=list', if 'list_type' was unset, and if the item was a set or tuple (i.e. not a list). >>> class Demo(resource.Resource): ... foo = resource.Body('foo', type=list) ... >>> demo = Demo(foo={'123'}) >>> demo.foo {'123'} # should be a list! This has now been fixed, however, the bugfix has exposed a case where we were in fact modifying a mutable list in-place. The long-term fix lies in changing how openstacksdk works, so that it always return the original attribute rather potentially returning a copy. However, this fix is likely going to be rather involved and not something we want to cram into the end of the Epoxy release. Instead, modify Horizon so that it updates the entire attribute rather than modifying it in place. Change-Id: I6e7814ea16ca84689b363a53f22de62800c1f0d8 Signed-off-by: Stephen Finucane <stephenfin@redhat.com> Related-bug: #2100605
101 lines
2.2 KiB
Bash
Executable File
101 lines
2.2 KiB
Bash
Executable File
# Usage: unit_tests.sh [--coverage] <root_dir> [<test-file>, ...]
|
|
|
|
set -o xtrace
|
|
|
|
if [ "$1" = "--coverage" ]; then
|
|
shift
|
|
coverage=1
|
|
else
|
|
coverage=0
|
|
fi
|
|
|
|
root=$1
|
|
posargs="${@:2}"
|
|
|
|
report_dir=$root/test_reports
|
|
|
|
# Attempt to identify if any of the arguments passed from tox is a test subset
|
|
if [ -n "$posargs" ]; then
|
|
for arg in "$posargs"
|
|
do
|
|
if [ ${arg:0:1} != "-" ]; then
|
|
subset=$arg
|
|
fi
|
|
done
|
|
fi
|
|
|
|
|
|
function run_test {
|
|
local project=$1
|
|
local tag
|
|
local target
|
|
local settings_module
|
|
local report_args
|
|
local ignore
|
|
|
|
tag="not selenium and not integration and not plugin_test"
|
|
|
|
case "$project" in
|
|
horizon)
|
|
settings_module="horizon.test.settings"
|
|
;;
|
|
openstack_dashboard)
|
|
settings_module="openstack_dashboard.test.settings"
|
|
;;
|
|
openstack_auth)
|
|
settings_module="openstack_auth.tests.settings"
|
|
;;
|
|
plugin|plugin-test|plugin_test)
|
|
project="plugin"
|
|
tag="plugin_test"
|
|
target="$root/openstack_dashboard/test/test_plugins"
|
|
settings_module="openstack_dashboard.test.settings"
|
|
;;
|
|
*)
|
|
# Declare error by returning 1 which usually means error in bash
|
|
return 1
|
|
esac
|
|
|
|
if [ -z "$target" ]; then
|
|
if [ -n "$subset" ]; then
|
|
target="$subset"
|
|
else
|
|
target="$root/$project"
|
|
fi
|
|
fi
|
|
|
|
ignore="--ignore=$root/openstack_dashboard/test/selenium"
|
|
|
|
if [ "$coverage" -eq 1 ]; then
|
|
coverage run -m pytest $target $ignore --ds=$settings_module -m "$tag"
|
|
else
|
|
report_args="--junitxml=$report_dir/${project}_test_results.xml"
|
|
report_args+=" --html=$report_dir/${project}_test_results.html"
|
|
report_args+=" --self-contained-html"
|
|
|
|
pytest $target --ds=$settings_module -v -m "$tag" $ignore $report_args
|
|
fi
|
|
return $?
|
|
}
|
|
|
|
# If we are running a test subset, supply the correct settings file.
|
|
# If not, simply run the entire test suite.
|
|
if [ -n "$subset" ]; then
|
|
project="${subset%%/*}"
|
|
run_test $project
|
|
exit $?
|
|
else
|
|
results=()
|
|
for project in horizon openstack_dashboard openstack_auth plugin; do
|
|
run_test $project
|
|
results+=($?)
|
|
done
|
|
|
|
# we have to tell tox if either of these test runs failed
|
|
for r in "${results[@]}"; do
|
|
if [ $r != 0 ]; then
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|