tenant_list is not mocked in admin.routers.tests

Bug #1363221 reported by Akihiro Motoki
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Dashboard (Horizon)
New
Medium
Akihiro Motoki

Bug Description

commit d9ecd8d15759297a15382d7353482a2eff4b26bb (https://review.openstack.org/#/c/75934/) added a new test to openstack_dashboard.admin.routers.tests, but api.keystone.tenant_list is not mocked.
As a result, unit tests fails like http://logs.openstack.org/88/114088/6/check/gate-horizon-python27/cce2205/dashboard_nose_results.html.

Curiously enough, it doesn't always occurs. I cannot reproduce it in my local env but OpenStack CI jenkins fails.

ft22.5: openstack_dashboard.dashboards.admin.routers.tests.RouterTests.test_set_external_network_emptyTraceback (most recent call last):
  File "/usr/lib/python2.7/unittest/case.py", line 331, in run
    testMethod()
  File "/home/jenkins/workspace/gate-horizon-python27/openstack_dashboard/test/helpers.py", line 77, in instance_stub_out
    return fn(self, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/openstack_dashboard/dashboards/admin/routers/tests.py", line 72, in test_set_external_network_empty
    res = self.client.get(self.INDEX_URL)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/django/test/client.py", line 473, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/django/test/client.py", line 280, in get
    return self.request(**r)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/django/test/client.py", line 444, in request
    six.reraise(*exc_info)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 112, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/decorators.py", line 36, in dec
    return view_func(request, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/decorators.py", line 84, in dec
    return view_func(request, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/decorators.py", line 52, in dec
    return view_func(request, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/decorators.py", line 36, in dec
    return view_func(request, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/decorators.py", line 84, in dec
    return view_func(request, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/tables/views.py", line 157, in get
    handled = self.construct_tables()
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/tables/views.py", line 148, in construct_tables
    handled = self.handle_table(table)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/tables/views.py", line 120, in handle_table
    data = self._get_data_dict()
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/tables/views.py", line 185, in _get_data_dict
    self._data = {self.table_class._meta.name: self.get_data()}
  File "/home/jenkins/workspace/gate-horizon-python27/openstack_dashboard/dashboards/admin/routers/views.py", line 56, in get_data
    routers = self._get_routers()
  File "/home/jenkins/workspace/gate-horizon-python27/openstack_dashboard/dashboards/admin/routers/views.py", line 43, in _get_routers
    tenant_dict = self._get_tenant_list()
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/utils/memoized.py", line 90, in wrapped
    value = cache[key] = func(*args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/openstack_dashboard/dashboards/admin/networks/views.py", line 50, in _get_tenant_list
    exceptions.handle(self.request, msg)
  File "/home/jenkins/workspace/gate-horizon-python27/horizon/exceptions.py", line 334, in handle
    six.reraise(exc_type, exc_value, exc_traceback)
  File "/home/jenkins/workspace/gate-horizon-python27/openstack_dashboard/dashboards/admin/networks/views.py", line 46, in _get_tenant_list
    tenants, has_more = api.keystone.tenant_list(self.request)
  File "/home/jenkins/workspace/gate-horizon-python27/openstack_dashboard/api/keystone.py", line 271, in tenant_list
    tenants = manager.list(domain=domain, user=user)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/utils.py", line 318, in inner
    return func(*args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/v3/projects.py", line 79, in list
    **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/base.py", line 71, in func
    return f(*args, **new_kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/base.py", line 352, in list
    self.collection_key)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/base.py", line 112, in _list
    resp, body = self.client.get(url, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/httpclient.py", line 611, in get
    return self._cs_request(url, 'GET', **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/httpclient.py", line 603, in _cs_request
    return self.request(url, method, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/httpclient.py", line 578, in request
    resp = super(HTTPClient, self).request(url, method, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/baseclient.py", line 21, in request
    return self.session.request(url, method, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/utils.py", line 318, in inner
    return func(*args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/session.py", line 324, in request
    resp = self._send_request(url, method, redirect, log, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/session.py", line 350, in _send_request
    resp = self.session.request(method, url, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/keystoneclient/session.py", line 65, in request
    return requests.request(*args, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/sessions.py", line 448, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/sessions.py", line 554, in send
    r = adapter.send(request, **kwargs)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/adapters.py", line 359, in send
    timeout=timeout
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 559, in urlopen
    _pool=self, _stacktrace=stacktrace)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/util/retry.py", line 245, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 516, in urlopen
    body=body, headers=headers)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 308, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python2.7/httplib.py", line 973, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 1007, in _send_request
    self.endheaders(body)
  File "/usr/lib/python2.7/httplib.py", line 969, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python2.7/httplib.py", line 829, in _send_output
    self.send(msg)
  File "/usr/lib/python2.7/httplib.py", line 791, in send
    self.connect()
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/connection.py", line 146, in connect
    conn = self._new_conn()
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/connection.py", line 125, in _new_conn
    (self.host, self.port), self.timeout, **extra_kw)
  File "/home/jenkins/workspace/gate-horizon-python27/.tox/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/util/connection.py", line 64, in create_connection
    for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
ProtocolError: ('Connection aborted.', gaierror(-2, 'Name or service not known'))

Revision history for this message
Akihiro Motoki (amotoki) wrote :

Previously test_set_external_network_empty has a line:

   self.assertMessageCount(res, error=2)

but one of them comes from an error of tenant_list().
The number of message counts should 1 due to no externel network found.

Revision history for this message
Akihiro Motoki (amotoki) wrote :

When api.keystone.tenant_list raises ConnectionRefused, the unit test admin.routers.tests.RouterTests.test_set_external_network_empty succeeds.
keystoneclient.openstack.common.apiclient.exceptions.ConnectionRefused is aliased to keystoneclient.exceptions.ConnectionError, and ConnectionError is one of openstack_dashboard.exceptions RECOVERABLE exceptions. Thus it is caught and the unit test didn't fail.

On the other hand, if ProtocolError (perhaps from eventlet.websocket) is raised, it is not a part of RECOVERABLE error, so the unit test fails.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.