summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTetyana Lashchova <tlashchova@mirantis.com>2014-10-27 17:58:47 +0200
committerTetyana Lashchova <tlashchova@mirantis.com>2014-10-28 17:28:54 +0200
commite346f5dd3e39269e882bc6886933476dce946d86 (patch)
tree9f93660b201f1a065a0abfb703c0a2919065679b
parent0cdb56139f983121771f8a6510cf34593aeb9a7e (diff)
downloadpython-heatclient-e346f5dd3e39269e882bc6886933476dce946d86.tar.gz
Fix shell tests for Python 3.4
Partial-Bug: #1384511 Change-Id: I7485184a84ec850c4cd695118f18b55e298f5124
-rw-r--r--heatclient/common/utils.py6
-rw-r--r--heatclient/tests/fakes.py35
-rw-r--r--heatclient/tests/test_shell.py163
3 files changed, 171 insertions, 33 deletions
diff --git a/heatclient/common/utils.py b/heatclient/common/utils.py
index a86593a..06df897 100644
--- a/heatclient/common/utils.py
+++ b/heatclient/common/utils.py
@@ -15,6 +15,7 @@
from __future__ import print_function
import prettytable
+from six.moves.urllib import parse
import sys
import textwrap
import uuid
@@ -147,3 +148,8 @@ def format_output(output, format='yaml'):
except KeyError:
raise exc.HTTPUnsupported("The format(%s) is unsupported."
% output_format)
+
+
+def parse_query_url(url):
+ base_url, query_params = url.split('?')
+ return base_url, parse.parse_qs(query_params)
diff --git a/heatclient/tests/fakes.py b/heatclient/tests/fakes.py
index 113d4a3..f345a60 100644
--- a/heatclient/tests/fakes.py
+++ b/heatclient/tests/fakes.py
@@ -54,6 +54,41 @@ def script_heat_list(url=None, show_nested=False):
http.HTTPClient.json_request('GET', url).AndReturn((resp, resp_dict))
+def mock_script_heat_list(show_nested=False):
+ resp_dict = {"stacks": [
+ {
+ "id": "1",
+ "stack_name": "teststack",
+ "stack_owner": "testowner",
+ "project": "testproject",
+ "stack_status": 'CREATE_COMPLETE',
+ "creation_time": "2012-10-25T01:58:47Z"
+ },
+ {
+ "id": "2",
+ "stack_name": "teststack2",
+ "stack_owner": "testowner",
+ "project": "testproject",
+ "stack_status": 'IN_PROGRESS',
+ "creation_time": "2012-10-25T01:58:47Z"
+ }]
+ }
+ if show_nested:
+ nested = {
+ "id": "3",
+ "stack_name": "teststack_nested",
+ "stack_status": 'IN_PROGRESS',
+ "creation_time": "2012-10-25T01:58:47Z",
+ "parent": "theparentof3"
+ }
+ resp_dict["stacks"].append(nested)
+ resp = FakeHTTPResponse(200,
+ 'success, you',
+ {'content-type': 'application/json'},
+ jsonutils.dumps(resp_dict))
+ return resp, resp_dict
+
+
def script_heat_normal_error():
resp_dict = {
"explanation": "The resource could not be found.",
diff --git a/heatclient/tests/test_shell.py b/heatclient/tests/test_shell.py
index 4906039..c2dbb9e 100644
--- a/heatclient/tests/test_shell.py
+++ b/heatclient/tests/test_shell.py
@@ -35,6 +35,7 @@ from heatclient.openstack.common import strutils
from mox3 import mox
from heatclient.common import http
+from heatclient.common import utils
from heatclient import exc
import heatclient.shell
from heatclient.tests import fakes
@@ -539,39 +540,6 @@ class ShellTestUserPass(ShellBase):
self.assertNotRegexpMatches(list_text, 'parent')
@httpretty.activate
- def test_stack_list_with_args(self):
- self.register_keystone_auth_fixture()
- expected_url = '/stacks?%s' % parse.urlencode({
- 'limit': 2,
- 'status': ['COMPLETE', 'FAILED'],
- 'marker': 'fake_id',
- 'global_tenant': True,
- 'show_deleted': 'True',
- }, True)
- fakes.script_heat_list(expected_url)
-
- self.m.ReplayAll()
-
- list_text = self.shell('stack-list'
- ' --limit 2'
- ' --marker fake_id'
- ' --filters=status=COMPLETE'
- ' --filters=status=FAILED'
- ' --global-tenant'
- ' --show-deleted')
-
- required = [
- 'stack_owner',
- 'project',
- 'testproject',
- 'teststack',
- 'teststack2',
- ]
- for r in required:
- self.assertRegexpMatches(list_text, r)
- self.assertNotRegexpMatches(list_text, 'parent')
-
- @httpretty.activate
def test_stack_list_show_nested(self):
self.register_keystone_auth_fixture()
expected_url = '/stacks?%s' % parse.urlencode({
@@ -2465,3 +2433,132 @@ class ShellTestStandaloneToken(ShellTestUserPass):
for r in required:
self.assertRegexpMatches(list_text, r)
self.assertNotRegexpMatches(list_text, 'parent')
+
+
+class MockShellBase(TestCase):
+
+ def setUp(self):
+ super(MockShellBase, self).setUp()
+ self.jreq_mock = self.patch(
+ 'heatclient.common.http.HTTPClient.json_request')
+
+ # Some tests set exc.verbose = 1, so reset on cleanup
+ def unset_exc_verbose():
+ exc.verbose = 0
+
+ self.addCleanup(unset_exc_verbose)
+
+ def shell(self, argstr):
+ orig = sys.stdout
+ try:
+ sys.stdout = six.StringIO()
+ _shell = heatclient.shell.HeatShell()
+ _shell.main(argstr.split())
+ self.subcommands = _shell.subcommands.keys()
+ except SystemExit:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.assertEqual(0, exc_value.code)
+ finally:
+ out = sys.stdout.getvalue()
+ sys.stdout.close()
+ sys.stdout = orig
+
+ return out
+
+
+class MockShellTestUserPass(MockShellBase):
+
+ def setUp(self):
+ super(MockShellTestUserPass, self).setUp()
+ self._set_fake_env()
+
+ def _set_fake_env(self):
+ self.set_fake_env(FAKE_ENV_KEYSTONE_V2)
+
+ @httpretty.activate
+ def test_stack_list_with_args(self):
+ self.register_keystone_auth_fixture()
+ self.jreq_mock.return_value = fakes.mock_script_heat_list()
+
+ list_text = self.shell('stack-list'
+ ' --limit 2'
+ ' --marker fake_id'
+ ' --filters=status=COMPLETE'
+ ' --filters=status=FAILED'
+ ' --global-tenant'
+ ' --show-deleted')
+
+ required = [
+ 'stack_owner',
+ 'project',
+ 'testproject',
+ 'teststack',
+ 'teststack2',
+ ]
+ for r in required:
+ self.assertRegexpMatches(list_text, r)
+ self.assertNotRegexpMatches(list_text, 'parent')
+
+ self.assertEqual(1, self.jreq_mock.call_count)
+ method, url = self.jreq_mock.call_args[0]
+ self.assertEqual('GET', method)
+ base_url, query_params = utils.parse_query_url(url)
+ self.assertEqual('/stacks', base_url)
+ expected_query_dict = {'limit': ['2'],
+ 'status': ['COMPLETE', 'FAILED'],
+ 'marker': ['fake_id'],
+ 'global_tenant': ['True'],
+ 'show_deleted': ['True']}
+ self.assertEqual(expected_query_dict, query_params)
+
+
+class MockShellTestToken(MockShellTestUserPass):
+
+ # Rerun all ShellTestUserPass test with token auth
+ def setUp(self):
+ self.token = 'a_token'
+ super(MockShellTestToken, self).setUp()
+
+ def _set_fake_env(self):
+ fake_env = {
+ 'OS_AUTH_TOKEN': self.token,
+ 'OS_TENANT_ID': 'tenant_id',
+ 'OS_AUTH_URL': keystone_client_fixtures.BASE_URL,
+ # Note we also set username/password, because create/update
+ # pass them even if we have a token to support storing credentials
+ # Hopefully at some point we can remove this and move to only
+ # storing trust id's in heat-engine instead..
+ 'OS_USERNAME': 'username',
+ 'OS_PASSWORD': 'password'
+ }
+ self.set_fake_env(fake_env)
+
+
+class MockShellTestUserPassKeystoneV3(MockShellTestUserPass):
+
+ def _set_fake_env(self):
+ self.set_fake_env(FAKE_ENV_KEYSTONE_V3)
+
+
+class MockShellTestStandaloneToken(MockShellTestUserPass):
+
+ # Rerun all ShellTestUserPass test in standalone mode, where we
+ # specify --os-no-client-auth, a token and Heat endpoint
+ def setUp(self):
+ self.token = 'a_token'
+ super(MockShellTestStandaloneToken, self).setUp()
+
+ def _set_fake_env(self):
+ fake_env = {
+ 'OS_AUTH_TOKEN': self.token,
+ 'OS_NO_CLIENT_AUTH': 'True',
+ 'HEAT_URL': 'http://no.where',
+ 'OS_AUTH_URL': keystone_client_fixtures.BASE_URL,
+ # Note we also set username/password, because create/update
+ # pass them even if we have a token to support storing credentials
+ # Hopefully at some point we can remove this and move to only
+ # storing trust id's in heat-engine instead..
+ 'OS_USERNAME': 'username',
+ 'OS_PASSWORD': 'password'
+ }
+ self.set_fake_env(fake_env)