經過demo學習OpenStack開發——單元測試
單元測試的重要性
單元測試工具
unittest
mock
testtools
fixtures
testscenarios
subunit
testrepository
coverage
tox
單元測試工具小結
Keystone的單元測試框架
使用tox進行測試環境管理
使用testrepository管理測試的運行
單元測試用例的代碼架構
總結
系列後記
Python的單元測試工具不少,爲單元測試提供不一樣方面的功能。OpenStack的項目也基本把如今流行的單元測試工具都用全了。單元測試能夠說是入門OpenStack開發的最難的部分,也是最後一千米。本文,咱們就介紹一下在OpenStack中會用到的單元測試的工具。因爲數量不少,不可能詳細介紹,所以主要作一些概念和用途上的介紹。
unittest是Python的標準庫,提供了最基本的單元測試功能,包括單元測試運行器(簡稱runner)和單元測試框架。項目的單元測試代碼的測試類能夠繼承unittest.TestCase類,這樣這個類就可以被runner發現而且執行。同時,unittest.TestCase這個類還定義了setUp(),tearDown(),setUpClass()和tearDownClass()方法,是用來運行單元測試前的設置工做代碼和單元測試後的清理工做代碼,這個也是全部Python代碼遵照的規範,因此第三方的單元測試庫和框架也都遵循這個規範。unittest庫也提供了一個runner,可使用$ python -m unittest test_module的命令來執行某個模塊的單元測試。另外,在Python中指定要運行的單元測試用例的完整語法是:path.to.your.module:ClassOfYourTest.test_method。unittest是學習Python單元測試最基本也最重要的一個庫,完整的說明請查看查看官方文檔。
。
mock也是另外一個重要的單元測試庫,在Python 2中是做爲一個第三方庫被使用的,到Python 3時,就被歸入了標準庫,可見這個庫的重要性。簡單的說,mock就是用來模擬對象的行爲,這樣在進行單元測試的時候,能夠指定任何對象的返回值,便於測試對外部接口有依賴的代碼。關於mock的使用,能夠查看我以前寫的這篇文章Python Mock的入門。
testtools是個unittest的擴展框架,主要是在unittest的基礎上提供了更好的assert功能,使得寫單元測試更加方便。具體能夠查看文檔。
。
fixture的意思是固定裝置,在Python的單元測試中,是指某段能夠複用的單元測試setUp和tearDown代碼組合。一個fixture通常用來實現某個組件的setUp和tearDown邏輯,好比測試前要先建立好某些數據,測試後要刪掉這些數據,這些操做就能夠封裝到一個fixture中。這樣不一樣的測試用例就不用重複寫這些代碼,只要使用fixture便可。fixtures模塊是一個第三方模塊,提供了一種簡單的建立fixture類和對象的機制,而且也提供了一些內置的fixture。具體的使用方法能夠查看官方文檔。
。
testscenarios模塊知足了場景測試的需求。它的基本用法是在測試類中添加一個類屬性scenarios,該屬性是一個元組,定義了每一種場景下不一樣的變量的值。好比說你測試一段數據訪問代碼,你須要測試該代碼在使用不一樣的驅動時,好比MongoDB、SQL、File,是否都能正常工做。咱們有三種辦法:
最笨的辦法是爲不一樣的驅動把同一個測試用例編寫3遍。
比較好的辦法是,編寫一個統一的非測試用例方法,接收driver做爲參數,執行測試邏輯,而後再分別編寫三個測試用例方法去調用這個非測試用例方法。
更好的辦法就是使用testscenarios模塊,定義好scenarios變量,而後實現一個測試用例方法。
testscenarios模塊在OpenStack Ceilometer中被大量使用。更多的信息能夠查看文檔。
subunit是一個用於傳輸單元測試結果的流協議。通常來講,運行單元測試的時候是把單元測試的結果直接輸出到標準輸出,可是若是運行大量的測試用例,這些測試結果就很難被分析。所以就可使用python-subunit模塊來運行測試用例,而且把測試用例經過subunit協議輸出,這樣測試結果就能夠被分析工具聚合以及分析。python-subunit模塊自帶了一些工具用來解析subunit協議,好比你能夠這樣運行測試用例:$ python -m subunit.run test_module | subunit2pyunit,subunit2pyunit命令會解析subunit協議,而且輸出到標準輸出。關於subunit的更多信息,請查看官方文檔。
OpenStack中使用testrepository模塊管理單元測試用例。當一個項目中的測試用例不少時,如何更有效的處理單元測試用例的結果就變得很重要。testrepository的出現就是爲了解決這個問題。testrepository使用python-subunit模塊來運行測試用例,而後分析subunit的輸出並對測試結果進行記錄(記錄到本地文件)。舉例來講,testrepository容許你作這樣的事情:
知道哪些用例運行時間最長
顯示運行失敗的用例
從新運行上次運行失敗的用例
testrepository的更多信息,請查看官方文檔。
coverage是用來計算代碼運行時的覆蓋率的,也就是統計多少代碼被執行了。它能夠和testrepository一塊兒使用,用來統計單元測試的覆蓋率,在運行完單元測試以後,輸出覆蓋率報告。具體的使用方法能夠查看官方文檔。
tox是用來管理和構建虛擬環境(virtualenv)的。對於一個項目,咱們須要運行Python 2.7的單元測試,也須要運行Python 3.4的單元測試,還須要運行PEP8的代碼檢查。這些不一樣的任務須要依賴不一樣的庫,因此須要使用不一樣的虛擬環境。使用tox的時候,咱們會在tox的配置文件tox.ini中指定不一樣任務的虛擬環境名稱,該任務在虛擬環境中須要安裝哪些包,以及該任務執行的時候須要運行哪些命令。更多信息,請查看官方文檔。
1.安裝pip
easy_install pip
2.設置pip源
pip官方源下載比較慢,咱們能夠設置一個國內的源。
$ mkdir ~/.pip
$ vim~/.pip/pip.conf
[global]
timeout =6000
index-url= http://mirrors.aliyun.com/pypi/simple
[install]
trusted-host= mirrors.aliyun.com
3.安裝tox
pip install tox
3.安裝依賴插件
yum install gcc libffi-devel python-devel openssl-devel
yum install git
yum install mysql-devel
yum install postgresql postgresql-devel python-devel
yum install libxslt-devel libxml2-devel
[root@qqzhangl keystone]# tox -e py27
[root@qqzhangl keystone] ls .tox log pep8 py27
[tox]
minversion = 1.6
skipsdist = Trueenvlist = py34,py27,pep8,docs,genconfig,releasenotes
[testenv] # testenv是默認配置,若是某個配置在環境專屬的section中沒有,就從這個section中讀取
usedevelop = True # usedevelop表示安裝virtualenv的時候,本項目本身的代碼採用開發模式安裝,
也就是不會拷貝代碼到virtualenv目錄中,只是作個連接
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/mitaka} {opts} {packages} # install_command表示構建環境的時候要執行的命令,通常是使用pip安裝
setenv = VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/test-requirements.txt
.[ldap,memcache,mongodb] # deps指定構建環境的時候須要安裝的依賴包,這個就是做爲pip命令的參數 # keystone這裏使用的寫法比較特殊一點,第二行的.[ldap,memcache,mongodb]是兩個依賴,
第一個點'.'表示當前項目的依賴,也就是requirements.txt,第二個部分[ldap,memcache,mongodb]
表示extra,是在setup.cfg文件中定義的一個段的名稱,該段下定義了額外的依賴,這些能夠查看PEP0508# 通常的項目這裏會採用更簡單的方式來書寫,直接安裝兩個文件中的依賴:
# -r{toxinidir}/requirements.txt
# -r{toxinidir}/test-requirements.txt
commands =
find keystone -type f -name "*.pyc" -delete
bash tools/pretty_tox.sh '{posargs}' # commands表示構建好virtualenv以後要執行的命令,這裏調用了tools/pretty_tox.sh來執行測試
whitelist_externals =
bash
find
passenv = http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY PBR_VERSION
[testenv:py34] # 這個section是爲py34環境定製某些配置的,沒有定製的配置,從[testenv]讀取
commands =
find keystone -type f -name "*.pyc" -delete
bash tools/pretty_tox_py3.sh
[testenv:legacy_drivers]
deps = -r{toxinidir}/test-requirements.txt
nose
.[ldap,memcache,mongodb]
commands =
# Run each legacy test separately, to avoid SQL model redefinitions
find keystone -type f -name "*.pyc" -delete
nosetests -v \
keystone/tests/unit/backend/legacy_drivers/assignment/V8/sql.py
nosetests -v \
keystone/tests/unit/backend/legacy_drivers/role/V8/sql.py
nosetests -v \
keystone/tests/unit/backend/legacy_drivers/federation/V8/api_v3.py
nosetests -v \
keystone/tests/unit/backend/legacy_drivers/resource/V8/sql.py
[testenv:pep8] #代碼編碼規範
deps =
.[bandit]
{[testenv]deps}
commands =
flake8
# Run bash8 during pep8 runs to ensure violations are caught by
# the check and gate queues
bashate examples/pki/gen_pki.sh
# Check that .po and .pot files are valid.
bash -c "find keystone -type f -regex '.*\.pot?' -print0| \
xargs -0 -n 1 msgfmt --check-format -o /dev/null"
# Run security linter
bandit -r keystone -x tests
[testenv:bandit]
# NOTE(browne): This is required for the integration test job of the bandit
# project. Please do not remove.
deps = .[bandit]
commands = bandit -r keystone -x tests
[testenv:cover] #代碼覆蓋率
# Also do not run test_coverage_ext tests while gathering coverage as those
# tests conflict with coverage.
# NOTE(sdague): this target does not use constraints because
# upstream infra does not yet support it. Once that's fixed, we can
# drop the install_command.
install_command = pip install -U --force-reinstall {opts} {packages}
commands =
find keystone -type f -name "*.pyc" -delete
python setup.py testr --coverage --testr-args='{posargs}'
[testenv:venv]
# NOTE(jaegerandi): this target does not use constraints because
# upstream infra does not yet support it. Once that's fixed, we can
# drop the install_command.
install_command = pip install -U --force-reinstall {opts} {packages}
commands = {posargs}
[testenv:debug] #代碼調試
commands =
find keystone -type f -name "*.pyc" -delete
oslo_debug_helper {posargs}
passenv =
KSTEST_ADMIN_URL
KSTEST_ADMIN_USERNAME
KSTEST_ADMIN_PASSWORD
KSTEST_ADMIN_DOMAIN_ID
KSTEST_PUBLIC_URL
KSTEST_USER_USERNAME
KSTEST_USER_PASSWORD
KSTEST_USER_DOMAIN_ID
KSTEST_PROJECT_ID
[testenv:functional]
basepython = python3.4
deps = -r{toxinidir}/test-requirements.txt
setenv = OS_TEST_PATH=./keystone/tests/functional
commands =
find keystone -type f -name "*.pyc" -delete
python setup.py testr --slowest --testr-args='{posargs}'
passenv =
KSTEST_ADMIN_URL
KSTEST_ADMIN_USERNAME
KSTEST_ADMIN_PASSWORD
KSTEST_ADMIN_DOMAIN_ID
KSTEST_PUBLIC_URL
KSTEST_USER_USERNAME
KSTEST_USER_PASSWORD
KSTEST_USER_DOMAIN_ID
KSTEST_PROJECT_ID
[flake8]
filename= *.py,keystone-all,keystone-manage
show-source = true
# D100: Missing docstring in public module
# D101: Missing docstring in public class
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# D104: Missing docstring in public package
# D105: Missing docstring in magic method
# D202: No blank lines allowed after docstring.
# D203: 1 blank required before class docstring.
# D205: Blank line required between one-line summary and description.
# D400: First line should end with a period.
# D401: First line should be in imperative mood.
ignore = D100,D101,D102,D103,D104,D105,D203,D205,D400,D401
exclude=.venv,.git,.tox,build,dist,doc,*openstack/common*,*lib/python*,*egg,tools,vendor,.update-venv,*.ini,*.po,*.pot
max-complexity=24
[testenv:docs] #生成代碼文檔
commands=
bash -c "rm -rf doc/build"
bash -c "rm -rf doc/source/api"
python setup.py build_sphinx
[testenv:releasenotes] #生成版本信息
# NOTE(sdague): this target does not use constraints because
# upstream infra does not yet support it. Once that's fixed, we can
# drop the install_command.
install_command = pip install -U --force-reinstall {opts} {packages}
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[testenv:genconfig] #生成配置文件
commands = oslo-config-generator --config-file=config-generator/keystone.conf
[hacking]
import_exceptions =
keystone.i18n
six.moves
local-check-factory = keystone.tests.hacking.checks.factory
[extras]
ldap =
python-ldap>=2.4:python_version=='2.7' # PSF
ldappool>=1.0:python_version=='2.7' # MPL
memcache =
python-memcached>=1.56 # PSF
mongodb =
pymongo!=3.1,>=3.0.2 # Apache-2.0
bandit =
bandit>=0.17.3 # Apache-2.0
commands
參數中執行的是_tools/pretty_tox.sh_命令。這個腳本的內容以下:#!/usr/bin/env bash
set -o pipefail
TESTRARGS=$1
# testr和setuptools已經集成,因此能夠經過setup.py testr命令來執行
# --testr-args表示傳遞給testr命令的參數,告訴testr要傳遞給subunit的參數
# subunit-trace是os-testr包中的命令(os-testr是OpenStack的一個項目),用來解析subunit的輸出的。
python setup.py testr --testr-args="--subunit $TESTRARGS" | subunit-trace -f
retval=$?
# NOTE(mtreinish) The pipe above would eat the slowest display from pbr's testr
# wrapper so just manually print the slowest tests.
echo -e "\nSlowest Tests:\n"
# 測試結束後,讓testr顯示出執行時間最長的那些測試用例
testr slowest
exit $retval
tools/pretty_tox.sh
這個命令開始調用testr來執行單元測試的。testr自己的配置是放在項目根目錄下的.testr.conf文件:[DEFAULT]
test_command=
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./keystone/tests/unit} $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
group_regex=.*(test_cert_setup)
# NOTE(morganfainberg): If single-worker mode is wanted (e.g. for live tests)
# the environment variable ``TEST_RUN_CONCURRENCY`` should be set to ``1``. If
# a non-default (1 worker per available core) concurrency is desired, set
# environment variable ``TEST_RUN_CONCURRENCY`` to the desired number of
# workers.
test_run_concurrency=echo ${TEST_RUN_CONCURRENCY:-0}
test_command
命令表示要執行什麼命令來運行測試用例,這裏使用的是subunit.run
,這個咱們在上面提到過了。
keystone.tests.unit.test_v3_assignment:AssignmentTestCase
。下面是這個類的繼承結構,同一級別的縮進表示多重繼承,增長縮進表示父類,這裏刪掉了沒必要要的路徑前綴(從unit目錄開始,以下所示:# 這個測試類是測RoleAssignment的API的
unit.test_v3_assignment.RoleAssignmentBaseTestCase
-> unit.test_v3.AssignmentTestMixin 這個類包含了一下測試Assignment的工具函數
-> unit.test_v3.RestfulTestCase 這個類是進行V3 REST API測試的基類,實現了V3 API的請求發起和校驗
-> unit.core.SQLDriverOverride 用於修改各個配置的driver字段爲sql
-> unit.test_v3.AuthTestMixin 包含建立認證請求的輔助函數
-> unit.rest.RestfulTestCase 這個類是進行RESP API測試的基類,V2和V3的API測試
都是以這個類爲基類,這個類的setUp方法會初始化數據庫,建立好TestApp。
-> unit.TestCase 這個類是Keystone中全部單元測試類的基類,它主要初始化配置,以及初始化log
-> unit.BaseTestCase 這個類主要是配置測試運行的基本環境,修改一些環境變量,好比HOME等。
-> testtools.TestCase 使用testtools做爲測試框架
-> unittest.TestCase testtools自己是unittest的擴展
[root@qqzhangl keystone]# tox -e py27 keystone.tests.unit.test_v3_assignment.AssignmentTestCase
py27 develop-inst-noop: /home/unittest/keystone
py27 installed: amqp==1.4.9,anyjson==0.3.3,appdirs==1.4.0,Babel==2.2.0,bashate==0.4.0,beautifulsoup4==4.4.1,cachetools==1.1.5,cffi==1.5.2,contextlib2==0.5.1,coverage==4.0.3,cryptography==1.2.3,debtcollector==1.3.0,decorator==4.0.9,docutils==0.12,dogpile.cache==0.5.7,dogpile.core==0.4.1,dulwich==0.18.3,ecdsa==0.13,enum34==1.1.2,eventlet==0.18.4,extras==0.0.3,fasteners==0.14.1,fixtures==1.4.0,flake8==2.2.4,flake8-docstrings==0.2.1.post1,funcsigs==0.4,functools32==3.2.3.post2,futures==3.0.5,futurist==0.13.0,greenlet==0.4.9,hacking==0.10.3,httplib2==0.9.2,idna==2.0,ipaddress==1.0.16,iso8601==0.1.11,Jinja2==2.8,jsonschema==2.5.1,-e git+http://git.bjv30.isscloud.com/cloudgo/keystone.git@30b5d9036f3299333a3655c00b5cd510676a48e8#egg=keystone,keystoneauth1==2.4.3,keystonemiddleware==0.0.1.dev4,kombu==3.0.34,ldappool==1.0,linecache2==1.0.0,lxml==3.5.0,MarkupSafe==0.23,mccabe==0.2.1,mock==1.3.0,monotonic==0.6,mox3==0.14.0,msgpack-python==0.4.7,netaddr==0.7.18,netifaces==0.10.4,oauthlib==1.0.3,os-client-config==1.16.0,os-testr==0.6.0,oslo.cache==1.6.0,oslo.concurrency==3.7.1,oslo.config==3.9.0,oslo.context==2.2.0,oslo.db==0.0.1.dev3,oslo.i18n==3.5.0,oslo.log==3.3.0,oslo.messaging==4.6.1,oslo.middleware==3.8.0,oslo.policy==1.6.0,oslo.serialization==2.4.0,oslo.service==1.8.0,oslo.utils==3.8.0,oslosphinx==4.3.0,oslotest==2.4.0,paramiko==1.16.0,passlib==1.6.5,Paste==2.0.2,PasteDeploy==1.5.2,pbr==1.8.1,pep257==0.7.0,pep8==1.5.7,pika==0.10.0,pika-pool==0.1.3,positional==1.0.1,pyasn1==0.1.9,pycadf==2.2.0,pycparser==2.14,pycrypto==2.6.1,pyflakes==0.8.1,Pygments==2.1.3,pyinotify==0.9.6,pymongo==3.2.1,pyOpenSSL==0.15.1,pyrsistent==0.11.12,pysaml2==4.0.2,python-dateutil==2.5.0,python-keystoneclient==0.0.1.dev40,python-ldap==2.4.25,python-memcached==1.57,python-mimeparse==1.5.1,python-subunit==1.2.0,pytz==2015.7,PyYAML==3.11,reno==2.5.0,repoze.lru==0.6,repoze.who==2.2,requests==2.9.1,requestsexceptions==1.1.3,retrying==1.3.3,Routes==2.2,six==1.10.0,Sphinx==1.2.3,SQLAlchemy==1.0.12,sqlalchemy-migrate==0.10.0,sqlparse==0.1.18,stevedore==1.12.0,tempest-lib==1.0.0,Tempita==0.5.2,testrepository==0.0.20,testscenarios==0.5.0,testtools==2.0.0,traceback2==1.4.0,unittest2==1.1.0,waitress==0.8.10,WebOb==1.5.1,WebTest==2.0.20,wrapt==1.10.6,zope.interface==4.1.3
py27 runtests: PYTHONHASHSEED='2134132608'
py27 runtests: commands[0] | find keystone -type f -name *.pyc -delete
py27 runtests: commands[1] | bash tools/pretty_tox.sh keystone.tests.unit.test_v3_assignment.AssignmentTestCase
running testr
running=
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./keystone/tests/unit} --list
running=
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./keystone/tests/unit} --load-list /tmp/tmpQRrBp5
running=
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./keystone/tests/unit} --load-list /tmp/tmpkpPca8
running=
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./keystone/tests/unit} --load-list /tmp/tmpAsqqdg
running=
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./keystone/tests/unit} --load-list /tmp/tmpcKMYi5
{3} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_create_member_role [3.301750s] ... ok
{0} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_user_domain_role_grants_no_user [3.129583s] ... ok
{2} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_create_role [3.084101s] ... ok
{1} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_check_effective_values_for_role_assignments [3.829839s] ... ok
{3} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_create_role_bad_request [0.782877s] ... ok
{0} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_user_project_role_grants [1.012792s] ... ok
{1} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_group_domain_role_grants_no_group [0.751216s] ... ok
{2} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_group_domain_role_grants [1.185124s] ... ok
{3} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_user_domain_role_grants [1.365098s] ... ok
{2} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_group_project_role_grants_no_group [0.868791s] ... ok
{1} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_group_project_role_grants [1.128794s] ... ok
{0} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_grant_from_group_and_project_invalidates_cache [1.382533s] ... ok
{3} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_user_project_role_grants_no_user [0.947176s] ... ok
{1} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_grant_from_user_and_domain_invalidates_cache [0.932734s] ... ok
{2} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_role [1.184809s] ... ok
{0} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_user_and_check_role_assignment_fails [1.040105s] ... ok
{3} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_grant_from_group_and_domain_invalidates_cache [1.143361s] ... ok
{1} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_grant_from_user_and_project_invalidate_cache [1.005817s] ... ok
{0} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_get_effective_role_assignments [1.158699s] ... ok
{1} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_list_roles [0.871036s] ... ok
{2} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_filtered_role_assignments [1.769572s] ... ok
{3} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_user_before_removing_role_assignment_succeeds [1.262221s] ... ok
{1} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_token_revoked_once_group_role_grant_revoked [0.880450s] ... FAILED
Captured traceback:
~~~~~~~~~~~~~~~~~~~
Traceback (most recent call last):
File "keystone/tests/unit/test_v3_assignment.py", line 336, in test_token_revoked_once_group_role_grant_revoked
expected_status=http_client.NOT_FOUND)
File "keystone/tests/unit/test_v3.py", line 537, in head
expected_status=expected_status, **kwargs)
File "keystone/tests/unit/test_v3.py", line 529, in v3_request
return self.admin_request(path=path, token=token, **kwargs)
File "keystone/tests/unit/rest.py", line 212, in admin_request
return self._request(app=self.admin_app, **kwargs)
File "keystone/tests/unit/rest.py", line 201, in _request
response = self.restful_request(**kwargs)
File "keystone/tests/unit/rest.py", line 186, in restful_request
**kwargs)
File "keystone/tests/unit/rest.py", line 90, in request
**kwargs)
File "/home/unittest/keystone/.tox/py27/lib/python2.7/site-packages/webtest/app.py", line 567, in request
expect_errors=expect_errors,
File "/home/unittest/keystone/.tox/py27/lib/python2.7/site-packages/webtest/app.py", line 632, in do_request
self._check_status(status, res)
File "/home/unittest/keystone/.tox/py27/lib/python2.7/site-packages/webtest/app.py", line 667, in _check_status
"Bad response: %s (not %s)", res_status, status)
webtest.app.AppError: Bad response: 200 OK (not 404)
Captured pythonlogging:
~~~~~~~~~~~~~~~~~~~~~~~
Adding cache-proxy 'oslo_cache.testing.CacheIsolatingProxy' to backend.
Adding cache-proxy 'oslo_cache.testing.CacheIsolatingProxy' to backend.
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4e898d0> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4b8dc90> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x46901d0> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x46901d0> acquired
Calling creation function
Released creation lock
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4b8fa90> acquired
Calling creation function
Released creation lock
There is either no auth token in the request or the certificate issuer is not trusted. No auth context will be set.
POST http://localhost:80/v3/auth/tokens
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x596a490> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4b8d050> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4806450> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4806450> acquired
Calling creation function
Released creation lock
RBAC: Proceeding without project or domain scope
RBAC: auth_context: {'access_token_id': None, 'user_id': u'124ec4417a804bfcaa113317e3cdf595', 'consumer_id': None, 'trustor_id': None, 'user_target': None, 'is_delegated_auth': False, 'trust_id': None, 'trustee_id': None, 'token': <KeystoneToken (audit_id=tY7TVIapRPSNoKPVgcNxfQ, audit_chain_id=tY7TVIapRPSNoKPVgcNxfQ) at 0x5e425f0>}
POST http://localhost:80/v3/auth/tokens
There is either no auth token in the request or the certificate issuer is not trusted. No auth context will be set.
POST http://localhost:80/v3/auth/tokens
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4806290> acquired
Calling creation function
Released creation lock
RBAC: Proceeding without project or domain scope
RBAC: auth_context: {'access_token_id': None, 'user_id': u'124ec4417a804bfcaa113317e3cdf595', 'consumer_id': None, 'trustor_id': None, 'user_target': None, 'is_delegated_auth': False, 'trust_id': None, 'trustee_id': None, 'token': <KeystoneToken (audit_id=4jw2Y8iBSYi_34W6wseoIA, audit_chain_id=4jw2Y8iBSYi_34W6wseoIA) at 0x725c050>}
HEAD http://localhost:80/v3/auth/tokens
RBAC: Authorizing identity:check_token()
RBAC: using auth context from the request environment
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5e65810> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5b61650> acquired
Calling creation function
Released creation lock
There is either no auth token in the request or the certificate issuer is not trusted. No auth context will be set.
POST http://localhost:80/v3/auth/tokens
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5e83890> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5e83f50> acquired
Calling creation function
Released creation lock
RBAC: Proceeding without project or domain scope
RBAC: auth_context: {'access_token_id': None, 'user_id': u'124ec4417a804bfcaa113317e3cdf595', 'consumer_id': None, 'trustor_id': None, 'user_target': None, 'is_delegated_auth': False, 'trust_id': None, 'trustee_id': None, 'token': <KeystoneToken (audit_id=AEqLyFtMRHG9wfKE0AVrew, audit_chain_id=AEqLyFtMRHG9wfKE0AVrew) at 0x5e1a290>}
HEAD http://localhost:80/v3/auth/tokens
RBAC: Authorizing identity:check_token()
RBAC: using auth context from the request environment
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5b61a90> acquired
Calling creation function
Released creation lock
{2} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_get_role [0.886941s] ... ok
{0} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_get_role_assignments [1.906290s] ... ok
{2} keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_update_role [0.603548s] ... ok
==============================
Failed 1 tests - output below:
==============================
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_token_revoked_once_group_role_grant_revoked
----------------------------------------------------------------------------------------------------------
Captured traceback:
~~~~~~~~~~~~~~~~~~~
Traceback (most recent call last):
File "keystone/tests/unit/test_v3_assignment.py", line 336, in test_token_revoked_once_group_role_grant_revoked
expected_status=http_client.NOT_FOUND)
File "keystone/tests/unit/test_v3.py", line 537, in head
expected_status=expected_status, **kwargs)
File "keystone/tests/unit/test_v3.py", line 529, in v3_request
return self.admin_request(path=path, token=token, **kwargs)
File "keystone/tests/unit/rest.py", line 212, in admin_request
return self._request(app=self.admin_app, **kwargs)
File "keystone/tests/unit/rest.py", line 201, in _request
response = self.restful_request(**kwargs)
File "keystone/tests/unit/rest.py", line 186, in restful_request
**kwargs)
File "keystone/tests/unit/rest.py", line 90, in request
**kwargs)
File "/home/unittest/keystone/.tox/py27/lib/python2.7/site-packages/webtest/app.py", line 567, in request
expect_errors=expect_errors,
File "/home/unittest/keystone/.tox/py27/lib/python2.7/site-packages/webtest/app.py", line 632, in do_request
self._check_status(status, res)
File "/home/unittest/keystone/.tox/py27/lib/python2.7/site-packages/webtest/app.py", line 667, in _check_status
"Bad response: %s (not %s)", res_status, status)
webtest.app.AppError: Bad response: 200 OK (not 404)
Captured pythonlogging:
~~~~~~~~~~~~~~~~~~~~~~~
Adding cache-proxy 'oslo_cache.testing.CacheIsolatingProxy' to backend.
Adding cache-proxy 'oslo_cache.testing.CacheIsolatingProxy' to backend.
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4e898d0> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4b8dc90> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x46901d0> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x46901d0> acquired
Calling creation function
Released creation lock
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
The admin_token_auth middleware presents a security risk and should be removed from the [pipeline:api_v3], [pipeline:admin_api], and [pipeline:public_api] sections of your paste ini file.
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4b8fa90> acquired
Calling creation function
Released creation lock
There is either no auth token in the request or the certificate issuer is not trusted. No auth context will be set.
POST http://localhost:80/v3/auth/tokens
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x596a490> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4b8d050> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4806450> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4806450> acquired
Calling creation function
Released creation lock
RBAC: Proceeding without project or domain scope
RBAC: auth_context: {'access_token_id': None, 'user_id': u'124ec4417a804bfcaa113317e3cdf595', 'consumer_id': None, 'trustor_id': None, 'user_target': None, 'is_delegated_auth': False, 'trust_id': None, 'trustee_id': None, 'token': <KeystoneToken (audit_id=tY7TVIapRPSNoKPVgcNxfQ, audit_chain_id=tY7TVIapRPSNoKPVgcNxfQ) at 0x5e425f0>}
POST http://localhost:80/v3/auth/tokens
There is either no auth token in the request or the certificate issuer is not trusted. No auth context will be set.
POST http://localhost:80/v3/auth/tokens
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x4806290> acquired
Calling creation function
Released creation lock
RBAC: Proceeding without project or domain scope
RBAC: auth_context: {'access_token_id': None, 'user_id': u'124ec4417a804bfcaa113317e3cdf595', 'consumer_id': None, 'trustor_id': None, 'user_target': None, 'is_delegated_auth': False, 'trust_id': None, 'trustee_id': None, 'token': <KeystoneToken (audit_id=4jw2Y8iBSYi_34W6wseoIA, audit_chain_id=4jw2Y8iBSYi_34W6wseoIA) at 0x725c050>}
HEAD http://localhost:80/v3/auth/tokens
RBAC: Authorizing identity:check_token()
RBAC: using auth context from the request environment
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5e65810> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5b61650> acquired
Calling creation function
Released creation lock
There is either no auth token in the request or the certificate issuer is not trusted. No auth context will be set.
POST http://localhost:80/v3/auth/tokens
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5e83890> acquired
Calling creation function
Released creation lock
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5e83f50> acquired
Calling creation function
Released creation lock
RBAC: Proceeding without project or domain scope
RBAC: auth_context: {'access_token_id': None, 'user_id': u'124ec4417a804bfcaa113317e3cdf595', 'consumer_id': None, 'trustor_id': None, 'user_target': None, 'is_delegated_auth': False, 'trust_id': None, 'trustee_id': None, 'token': <KeystoneToken (audit_id=AEqLyFtMRHG9wfKE0AVrew, audit_chain_id=AEqLyFtMRHG9wfKE0AVrew) at 0x5e1a290>}
HEAD http://localhost:80/v3/auth/tokens
RBAC: Authorizing identity:check_token()
RBAC: using auth context from the request environment
NeedRegenerationException
no value, waiting for create lock
value creation lock <dogpile.cache.region._LockWrapper object at 0x5b61a90> acquired
Calling creation function
Released creation lock
======
Totals
======
Ran: 26 tests in 15.0000 sec.
- Passed: 25
- Skipped: 0
- Expected Fail: 0
- Unexpected Success: 0
- Failed: 1
Sum of execute time for each test: 37.4153 sec.
==============
Worker Balance
==============
- Worker 0 (6 tests) => 0:00:09.655349
- Worker 1 (7 tests) => 0:00:09.422374
- Worker 2 (7 tests) => 0:00:09.612487
- Worker 3 (6 tests) => 0:00:08.822696
Slowest Tests:
Test id Runtime (s)
-------------------------------------------------------------------------------------------------------------------- -----------
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_check_effective_values_for_role_assignments 3.830
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_create_member_role 3.302
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_user_domain_role_grants_no_user 3.130
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_create_role 3.084
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_get_role_assignments 1.906
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_filtered_role_assignments 1.770
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_grant_from_group_and_project_invalidates_cache 1.383
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_user_domain_role_grants 1.365
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_delete_user_before_removing_role_assignment_succeeds 1.262
keystone.tests.unit.test_v3_assignment.AssignmentTestCase.test_crud_group_domain_role_grants 1.185
ERROR: InvocationError: '/usr/bin/bash tools/pretty_tox.sh keystone.tests.unit.test_v3_assignment.AssignmentTestCase'
___________________________________________________________ summary ___________________________________________________________
ERROR: py27: commands failed