diff options
Diffstat (limited to 'heatclient/tests')
-rw-r--r-- | heatclient/tests/functional/osc/v1/base.py | 9 | ||||
-rw-r--r-- | heatclient/tests/test_templates/adopt_with_file.json | 32 | ||||
-rw-r--r-- | heatclient/tests/unit/__init__.py | 5 | ||||
-rw-r--r-- | heatclient/tests/unit/osc/v1/test_stack.py | 58 | ||||
-rw-r--r-- | heatclient/tests/unit/test_common_http.py | 8 | ||||
-rw-r--r-- | heatclient/tests/unit/test_format_utils.py | 2 | ||||
-rw-r--r-- | heatclient/tests/unit/test_resources.py | 139 | ||||
-rw-r--r-- | heatclient/tests/unit/test_shell.py | 408 | ||||
-rw-r--r-- | heatclient/tests/unit/test_template_utils.py | 16 |
9 files changed, 291 insertions, 386 deletions
diff --git a/heatclient/tests/functional/osc/v1/base.py b/heatclient/tests/functional/osc/v1/base.py index c9a946e..591225a 100644 --- a/heatclient/tests/functional/osc/v1/base.py +++ b/heatclient/tests/functional/osc/v1/base.py @@ -15,6 +15,7 @@ import os import six from tempest.lib.cli import base from tempest.lib.cli import output_parser +from tempest.lib import exceptions as tempest_exc class OpenStackClientTestBase(base.ClientTestBase): @@ -81,7 +82,13 @@ class OpenStackClientTestBase(base.ClientTestBase): if wait: cmd += ' --wait' if id in self.openstack('stack list --short'): - self.openstack(cmd) + try: + self.openstack(cmd) + except tempest_exc.CommandFailed as e: + msg = "Stack not found: %s" % id + if msg in six.text_type(e.stdout): + return + raise def _stack_suspend(self, id, wait=True): cmd = 'stack suspend ' + id diff --git a/heatclient/tests/test_templates/adopt_with_file.json b/heatclient/tests/test_templates/adopt_with_file.json new file mode 100644 index 0000000..1519043 --- /dev/null +++ b/heatclient/tests/test_templates/adopt_with_file.json @@ -0,0 +1,32 @@ +{ + "files": { + "file://empty.yaml": "{\"heat_template_version\": \"2015-10-15\"}" + }, + "status": "COMPLETE", + "name": "test", + "tags": null, + "stack_user_project_id": "8f51847805ee4994a1ac1d6d1a9bcd9b", + "environment": { + "event_sinks": [], + "parameter_defaults": {}, + "parameters": {}, + "resource_registry": { + "file://empty.yaml": "file://empty.yaml", + "resources": {} + } + }, + "template": { + "heat_template_version": "2015-04-30", + "resources": { + "empty_child": { + "type": "file://empty.yaml" + } + } + }, + "action": "CREATE", + "project_id": "02228cd21ae24ed7966768a9a41be507", + "id": "25b97c3b-2e9a-4222-bc30-da116ae74a08", + "resources": { + "empty_child": {} + } +} diff --git a/heatclient/tests/unit/__init__.py b/heatclient/tests/unit/__init__.py index b1967c8..e69de29 100644 --- a/heatclient/tests/unit/__init__.py +++ b/heatclient/tests/unit/__init__.py @@ -1,5 +0,0 @@ -import sys - -from mox3 import mox - -sys.modules['mox'] = mox diff --git a/heatclient/tests/unit/osc/v1/test_stack.py b/heatclient/tests/unit/osc/v1/test_stack.py index bcc9f69..d6a51b0 100644 --- a/heatclient/tests/unit/osc/v1/test_stack.py +++ b/heatclient/tests/unit/osc/v1/test_stack.py @@ -148,6 +148,24 @@ class TestStackCreate(TestStack): self.cmd.take_action(parsed_args) + mock_poll.assert_called_once_with(mock.ANY, 'my_stack', + action='CREATE', poll_period=5) + self.stack_client.create.assert_called_with(**self.defaults) + self.stack_client.get.assert_called_with(**{'stack_id': '1234', + 'resolve_outputs': False}) + + @mock.patch('heatclient.common.event_utils.poll_for_events', + return_value=('CREATE_COMPLETE', + 'Stack my_stack CREATE_COMPLETE')) + def test_stack_create_wait_with_poll(self, mock_poll): + arglist = ['my_stack', '-t', self.template_path, '--wait', + '--poll', '10'] + parsed_args = self.check_parser(self.cmd, arglist, []) + + self.cmd.take_action(parsed_args) + + mock_poll.assert_called_once_with(mock.ANY, 'my_stack', + action='CREATE', poll_period=10) self.stack_client.create.assert_called_with(**self.defaults) self.stack_client.get.assert_called_with(**{'stack_id': '1234', 'resolve_outputs': False}) @@ -730,9 +748,12 @@ class TestStackDelete(TestStack): class TestStackAdopt(TestStack): adopt_file = 'heatclient/tests/test_templates/adopt.json' + adopt_with_files = ('heatclient/tests/test_templates/adopt_with_file.json') with open(adopt_file, 'r') as f: adopt_data = f.read() + with open(adopt_with_files, 'r') as f: + adopt_with_files_data = f.read() defaults = { 'stack_name': 'my_stack', @@ -744,6 +765,18 @@ class TestStackAdopt(TestStack): 'timeout': None } + child_stack_yaml = "{\"heat_template_version\": \"2015-10-15\"}" + + expected_with_files = { + 'stack_name': 'my_stack', + 'disable_rollback': True, + 'adopt_stack_data': adopt_with_files_data, + 'parameters': {}, + 'files': {'file://empty.yaml': child_stack_yaml}, + 'environment': {}, + 'timeout': None + } + def setUp(self): super(TestStackAdopt, self).setUp() self.cmd = stack.AdoptStack(self.app, None) @@ -776,8 +809,8 @@ class TestStackAdopt(TestStack): 'Stack my_stack ADOPT_COMPLETE')) def test_stack_adopt_wait(self, mock_poll): arglist = ['my_stack', '--adopt-file', self.adopt_file, '--wait'] - self.stack_client.get.return_value = \ - stacks.Stack(None, {'stack_status': 'ADOPT_COMPLETE'}) + self.stack_client.get.return_value = stacks.Stack( + None, {'stack_status': 'ADOPT_COMPLETE'}) parsed_args = self.check_parser(self.cmd, arglist, []) self.cmd.take_action(parsed_args) @@ -791,12 +824,25 @@ class TestStackAdopt(TestStack): 'Stack my_stack ADOPT_FAILED')) def test_stack_adopt_wait_fail(self, mock_poll): arglist = ['my_stack', '--adopt-file', self.adopt_file, '--wait'] - self.stack_client.get.return_value = \ - stacks.Stack(None, {'stack_status': 'ADOPT_FAILED'}) + self.stack_client.get.return_value = stacks.Stack( + None, {'stack_status': 'ADOPT_FAILED'}) parsed_args = self.check_parser(self.cmd, arglist, []) self.assertRaises(exc.CommandError, self.cmd.take_action, parsed_args) + def test_stack_adopt_with_adopt_files(self): + # Make sure when we adopt with files in adopt script, we will load + # those files as part of input when calling adopt. + arglist = ['my_stack', '--adopt-file', self.adopt_with_files] + cols = ['id', 'stack_name', 'description', 'creation_time', + 'updated_time', 'stack_status', 'stack_status_reason'] + parsed_args = self.check_parser(self.cmd, arglist, []) + + columns, data = self.cmd.take_action(parsed_args) + + self.stack_client.create.assert_called_with(**self.expected_with_files) + self.assertEqual(cols, columns) + class TestStackExport(TestStack): @@ -1225,8 +1271,8 @@ class TestStackCancel(_TestStackCheckBase, TestStack): self.mock_client.actions.cancel_update, 'ROLLBACK' ) - self.mock_client.stacks.get.return_value = \ - self.stack_update_in_progress + self.mock_client.stacks.get.return_value = ( + self.stack_update_in_progress) def test_stack_cancel(self): self._test_stack_action(2) diff --git a/heatclient/tests/unit/test_common_http.py b/heatclient/tests/unit/test_common_http.py index 79cb551..17afa38 100644 --- a/heatclient/tests/unit/test_common_http.py +++ b/heatclient/tests/unit/test_common_http.py @@ -637,7 +637,8 @@ class SessionClientTest(testtools.TestCase): self.assertEqual(('', 'GET'), self.request.call_args_list[0][0]) self.assertEqual(('ishere', 'GET'), self.request.call_args_list[1][0]) for call in self.request.call_args_list: - self.assertEqual({'user_agent': 'python-heatclient', + self.assertEqual({'headers': {'Content-Type': 'application/json'}, + 'user_agent': 'python-heatclient', 'raise_exc': False, 'redirect': True}, call[1]) @@ -668,7 +669,8 @@ class SessionClientTest(testtools.TestCase): self.assertEqual(('http://no.where/ishere', 'GET'), self.request.call_args_list[1][0]) for call in self.request.call_args_list: - self.assertEqual({'user_agent': 'python-heatclient', + self.assertEqual({'headers': {'Content-Type': 'application/json'}, + 'user_agent': 'python-heatclient', 'raise_exc': False, 'redirect': True}, call[1]) @@ -750,6 +752,7 @@ class SessionClientTest(testtools.TestCase): self.assertEqual({'endpoint_override': 'http://no.where/', 'data': '"some_data"', + 'headers': {'Content-Type': 'application/json'}, 'user_agent': 'python-heatclient', 'raise_exc': False}, self.request.call_args[1]) self.assertEqual(200, resp.status_code) @@ -774,6 +777,7 @@ class SessionClientTest(testtools.TestCase): self.assertEqual({'endpoint_override': 'http://no.where/', 'data': "{'files': test}}", + 'headers': {'Content-Type': 'application/json'}, 'user_agent': 'python-heatclient', 'raise_exc': False}, self.request.call_args[1]) self.assertEqual(200, resp.status_code) diff --git a/heatclient/tests/unit/test_format_utils.py b/heatclient/tests/unit/test_format_utils.py index 340a66c..28806d4 100644 --- a/heatclient/tests/unit/test_format_utils.py +++ b/heatclient/tests/unit/test_format_utils.py @@ -53,7 +53,7 @@ class TestFormats(utils.TestCommand): self.cmd.run(parsed_args) - self.assertEqual(expected, self.app.stdout.make_string()) + self.assertEqual(expected, self.app.stdout.make_string().rstrip()) def test_yaml_format(self): self.cmd = ShowYaml(self.app, None) diff --git a/heatclient/tests/unit/test_resources.py b/heatclient/tests/unit/test_resources.py index 96e8203..8676b8c 100644 --- a/heatclient/tests/unit/test_resources.py +++ b/heatclient/tests/unit/test_resources.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -import mox +import mock from six.moves.urllib import parse import testtools @@ -20,54 +20,55 @@ from heatclient.common import utils from heatclient.v1 import resources -class ResourceManagerTest(testtools.TestCase): +class FakeAPI(object): + """Fake API and ensure request url is correct.""" - def setUp(self): - super(ResourceManagerTest, self).setUp() - self.m = mox.Mox() - self.addCleanup(self.m.UnsetStubs) + def __init__(self, expect, key): + self.expect = expect + self.key = key - def _base_test(self, expect, key): + def get(self, *args, **kwargs): + assert ('GET', args[0]) == self.expect - class FakeAPI(object): - """Fake API and ensure request url is correct.""" + def json_request(self, *args, **kwargs): + assert args == self.expect + ret = self.key and {self.key: []} or {} + return {}, {self.key: ret} - def get(self, *args, **kwargs): - assert ('GET', args[0]) == expect + def raw_request(self, *args, **kwargs): + assert args == self.expect + return {} - def json_request(self, *args, **kwargs): - assert args == expect - ret = key and {key: []} or {} - return {}, {key: ret} + def head(self, url, **kwargs): + return self.json_request("HEAD", url, **kwargs) - def raw_request(self, *args, **kwargs): - assert args == expect - return {} + def post(self, url, **kwargs): + return self.json_request("POST", url, **kwargs) - def head(self, url, **kwargs): - return self.json_request("HEAD", url, **kwargs) + def put(self, url, **kwargs): + return self.json_request("PUT", url, **kwargs) - def post(self, url, **kwargs): - return self.json_request("POST", url, **kwargs) + def delete(self, url, **kwargs): + return self.raw_request("DELETE", url, **kwargs) - def put(self, url, **kwargs): - return self.json_request("PUT", url, **kwargs) + def patch(self, url, **kwargs): + return self.json_request("PATCH", url, **kwargs) - def delete(self, url, **kwargs): - return self.raw_request("DELETE", url, **kwargs) - def patch(self, url, **kwargs): - return self.json_request("PATCH", url, **kwargs) +class ResourceManagerTest(testtools.TestCase): - manager = resources.ResourceManager(FakeAPI()) - self.m.StubOutWithMock(manager, '_resolve_stack_id') - self.m.StubOutWithMock(utils, 'get_response_body') - utils.get_response_body(mox.IgnoreArg()).AndReturn( - {key: key and {key: []} or {}}) - manager._resolve_stack_id('teststack').AndReturn('teststack/abcd1234') - self.m.ReplayAll() + def _base_test(self, func, fields, expect, key): + manager = resources.ResourceManager(FakeAPI(expect, key)) - return manager + with mock.patch.object(manager, '_resolve_stack_id') as mock_rslv, \ + mock.patch.object(utils, 'get_response_body') as mock_resp: + mock_resp.return_value = {key: key and {key: []} or {}} + mock_rslv.return_value = 'teststack/abcd1234' + + getattr(manager, func)(**fields) + + mock_resp.assert_called_once_with(mock.ANY) + mock_rslv.assert_called_once_with('teststack') def test_get(self): fields = {'stack_id': 'teststack', @@ -77,9 +78,7 @@ class ResourceManagerTest(testtools.TestCase): '/testresource') key = 'resource' - manager = self._base_test(expect, key) - manager.get(**fields) - self.m.VerifyAll() + self._base_test('get', fields, expect, key) def test_get_with_attr(self): fields = {'stack_id': 'teststack', @@ -90,9 +89,7 @@ class ResourceManagerTest(testtools.TestCase): '/testresource?with_attr=attr_a&with_attr=attr_b') key = 'resource' - manager = self._base_test(expect, key) - manager.get(**fields) - self.m.VerifyAll() + self._base_test('get', fields, expect, key) def test_get_with_unicode_resource_name(self): fields = {'stack_id': 'teststack', @@ -102,9 +99,22 @@ class ResourceManagerTest(testtools.TestCase): '/%E5%B7%A5%E4%BD%9C') key = 'resource' - manager = self._base_test(expect, key) - manager.get(**fields) - self.m.VerifyAll() + self._base_test('get', fields, expect, key) + + def _test_list(self, fields, expect): + key = 'resources' + + class FakeResponse(object): + def json(self): + return {key: {}} + + class FakeClient(object): + def get(self, *args, **kwargs): + assert args[0] == expect + return FakeResponse() + + manager = resources.ResourceManager(FakeClient()) + manager.list(**fields) def test_list(self): self._test_list( @@ -135,21 +145,6 @@ class ResourceManagerTest(testtools.TestCase): }, True) ) - def _test_list(self, fields, expect): - key = 'resources' - - class FakeResponse(object): - def json(self): - return {key: {}} - - class FakeClient(object): - def get(self, *args, **kwargs): - assert args[0] == expect - return FakeResponse() - - manager = resources.ResourceManager(FakeClient()) - manager.list(**fields) - def test_metadata(self): fields = {'stack_id': 'teststack', 'resource_name': 'testresource'} @@ -158,9 +153,7 @@ class ResourceManagerTest(testtools.TestCase): '/testresource/metadata') key = 'metadata' - manager = self._base_test(expect, key) - manager.metadata(**fields) - self.m.VerifyAll() + self._base_test('metadata', fields, expect, key) def test_generate_template(self): fields = {'resource_name': 'testresource'} @@ -179,13 +172,13 @@ class ResourceManagerTest(testtools.TestCase): return {}, {key: ret} manager = resources.ResourceManager(FakeAPI()) - self.m.StubOutWithMock(utils, 'get_response_body') - utils.get_response_body(mox.IgnoreArg()).AndReturn( - {key: key and {key: []} or {}}) - self.m.ReplayAll() - manager.generate_template(**fields) - self.m.VerifyAll() + with mock.patch.object(utils, 'get_response_body') as mock_resp: + mock_resp.return_value = {key: key and {key: []} or {}} + + manager.generate_template(**fields) + + mock_resp.assert_called_once_with(mock.ANY) def test_signal(self): fields = {'stack_id': 'teststack', @@ -196,9 +189,7 @@ class ResourceManagerTest(testtools.TestCase): '/testresource/signal') key = 'signal' - manager = self._base_test(expect, key) - manager.signal(**fields) - self.m.VerifyAll() + self._base_test('signal', fields, expect, key) def test_mark_unhealthy(self): fields = {'stack_id': 'teststack', @@ -210,9 +201,7 @@ class ResourceManagerTest(testtools.TestCase): '/testresource') key = 'mark_unhealthy' - manager = self._base_test(expect, key) - manager.mark_unhealthy(**fields) - self.m.VerifyAll() + self._base_test('mark_unhealthy', fields, expect, key) class ResourceStackNameTest(testtools.TestCase): diff --git a/heatclient/tests/unit/test_shell.py b/heatclient/tests/unit/test_shell.py index 2ea4fd4..fcb019c 100644 --- a/heatclient/tests/unit/test_shell.py +++ b/heatclient/tests/unit/test_shell.py @@ -19,10 +19,8 @@ import uuid import fixtures from keystoneauth1 import fixture as keystone_fixture import mock -import mox from oslo_serialization import jsonutils from oslo_utils import encodeutils -import requests from requests_mock.contrib import fixture as rm_fixture import six from six.moves.urllib import parse @@ -309,12 +307,6 @@ class ShellParamValidationTest(TestCase): err='Sorting key \'owner\' not one of')), ] - def setUp(self): - super(ShellParamValidationTest, self).setUp() - self.m = mox.Mox() - self.addCleanup(self.m.VerifyAll) - self.addCleanup(self.m.UnsetStubs) - def test_bad_parameters(self): self.register_keystone_auth_fixture() fake_env = { @@ -335,22 +327,16 @@ class ShellParamValidationTest(TestCase): class ShellValidationTest(TestCase): - def setUp(self): - super(ShellValidationTest, self).setUp() - self.m = mox.Mox() - self.addCleanup(self.m.VerifyAll) - self.addCleanup(self.m.UnsetStubs) - def test_failed_auth(self): self.register_keystone_auth_fixture() - self.m.StubOutWithMock(http.SessionClient, 'request') failed_msg = 'Unable to authenticate user with credentials provided' - http.SessionClient.request( - '/stacks?', 'GET').AndRaise(exc.Unauthorized(failed_msg)) - self.m.ReplayAll() - self.set_fake_env(FAKE_ENV_KEYSTONE_V2) - self.shell_error('stack-list', failed_msg, exception=exc.Unauthorized) + with mock.patch.object(http.SessionClient, 'request', + side_effect=exc.Unauthorized(failed_msg)) as sc: + self.set_fake_env(FAKE_ENV_KEYSTONE_V2) + self.shell_error('stack-list', failed_msg, + exception=exc.Unauthorized) + sc.assert_called_once_with('/stacks?', 'GET') def test_stack_create_validation(self): self.register_keystone_auth_fixture() @@ -390,15 +376,25 @@ class ShellValidationTest(TestCase): class ShellBase(TestCase): + (JSON, RAW, SESSION) = ('json', 'raw', 'session') + def setUp(self): super(ShellBase, self).setUp() - self.m = mox.Mox() - self.m.StubOutWithMock(http.HTTPClient, 'json_request') - self.m.StubOutWithMock(http.HTTPClient, 'raw_request') - self.m.StubOutWithMock(http.SessionClient, 'request') + self._calls = {self.JSON: [], self.RAW: [], self.SESSION: []} + self._results = {self.JSON: [], self.RAW: [], self.SESSION: []} + self.useFixture(fixtures.MockPatchObject( + http.HTTPClient, + 'json_request', + side_effect=self._results[self.JSON])) + self.useFixture(fixtures.MockPatchObject( + http.HTTPClient, + 'raw_request', + side_effect=self._results[self.RAW])) + self.useFixture(fixtures.MockPatchObject( + http.SessionClient, + 'request', + side_effect=self._results[self.SESSION])) self.client = http.SessionClient - self.addCleanup(self.m.VerifyAll) - self.addCleanup(self.m.UnsetStubs) # Some tests set exc.verbose = 1, so reset on cleanup def unset_exc_verbose(): @@ -406,6 +402,12 @@ class ShellBase(TestCase): self.addCleanup(unset_exc_verbose) + def tearDown(self): + http.HTTPClient.json_request.assert_has_calls(self._calls[self.JSON]) + http.HTTPClient.raw_request.assert_has_calls(self._calls[self.RAW]) + http.SessionClient.request.assert_has_calls(self._calls[self.SESSION]) + super(ShellBase, self).tearDown() + def shell(self, argstr): orig = sys.stdout try: @@ -426,12 +428,15 @@ class ShellBase(TestCase): def mock_request_error(self, path, verb, error): raw = verb == 'DELETE' if self.client == http.SessionClient: - self.client.request(path, verb).AndRaise(error) + request = self.SESSION + self._expect_call(request, path, verb) else: if raw: - self.client.raw_request(verb, path).AndRaise(error) + request = self.RAW else: - self.client.json_request(verb, path).AndRaise(error) + request = self.JSON + self._expect_call(request, verb, path) + self._results[request].append(error) def mock_request_get(self, path, response, raw=False, **kwargs): self.mock_request(path, 'GET', response, raw=raw, **kwargs) @@ -477,14 +482,20 @@ class ShellBase(TestCase): resp = fakes.FakeHTTPResponse(status_code, reason, headers, content) if self.client == http.SessionClient: - self.client.request(path, verb, **kwargs).AndReturn(resp) + request = self.SESSION + self._results[request].append(resp) + self._expect_call(request, path, verb, **kwargs) else: if raw: - self.client.raw_request( - verb, path, **kwargs).AndReturn(resp) + request = self.RAW + self._results[request].append(resp) else: - self.client.json_request( - verb, path, **kwargs).AndReturn((resp, response)) + request = self.JSON + self._results[request].append((resp, response)) + self._expect_call(request, verb, path, **kwargs) + + def _expect_call(self, request, *args, **kwargs): + self._calls[request].append(mock.call(*args, **kwargs)) def mock_stack_list(self, path=None, show_nested=False): if path is None: @@ -494,11 +505,11 @@ class ShellBase(TestCase): self.mock_request_get(path, resp_dict) -class ShellTestNoMox(TestCase): +class ShellTestNoMoxBase(TestCase): # NOTE(dhu): This class is reserved for no Mox usage. Instead, # use requests_mock to expose errors from json_request. def setUp(self): - super(ShellTestNoMox, self).setUp() + super(ShellTestNoMoxBase, self).setUp() self._set_fake_env() def _set_fake_env(self): @@ -528,6 +539,8 @@ class ShellTestNoMox(TestCase): return out + +class ShellTestNoMox(ShellTestNoMoxBase): # This function tests err msg handling def test_stack_create_parameter_missing_err_msg(self): self.register_keystone_auth_fixture() @@ -602,75 +615,74 @@ class ShellTestEndpointType(TestCase): def setUp(self): super(ShellTestEndpointType, self).setUp() - self.m = mox.Mox() - self.m.StubOutWithMock(http, '_construct_http_client') - self.m.StubOutWithMock(heatclient.v1.shell, 'do_stack_list') - self.addCleanup(self.m.VerifyAll) - self.addCleanup(self.m.UnsetStubs) + self.useFixture(fixtures.MockPatchObject(http, + '_construct_http_client')) + self.useFixture(fixtures.MockPatchObject(heatclient.v1.shell, + 'do_stack_list')) self.set_fake_env(FAKE_ENV_KEYSTONE_V2) def test_endpoint_type_public_url(self): self.register_keystone_auth_fixture() kwargs = { 'auth_url': 'http://keystone.example.com:5000/', - 'session': mox.IgnoreArg(), - 'auth': mox.IgnoreArg(), + 'session': mock.ANY, + 'auth': mock.ANY, 'service_type': 'orchestration', 'endpoint_type': 'publicURL', 'region_name': '', 'username': 'username', 'password': 'password', 'include_pass': False, - 'endpoint_override': mox.IgnoreArg(), + 'endpoint_override': mock.ANY, } - http._construct_http_client(**kwargs) - heatclient.v1.shell.do_stack_list(mox.IgnoreArg(), mox.IgnoreArg()) - self.m.ReplayAll() heatclient.shell.main(('stack-list',)) + http._construct_http_client.assert_called_once_with(**kwargs) + heatclient.v1.shell.do_stack_list.assert_called_once() + def test_endpoint_type_admin_url(self): self.register_keystone_auth_fixture() kwargs = { 'auth_url': 'http://keystone.example.com:5000/', - 'session': mox.IgnoreArg(), - 'auth': mox.IgnoreArg(), + 'session': mock.ANY, + 'auth': mock.ANY, 'service_type': 'orchestration', 'endpoint_type': 'adminURL', 'region_name': '', 'username': 'username', 'password': 'password', 'include_pass': False, - 'endpoint_override': mox.IgnoreArg(), + 'endpoint_override': mock.ANY, } - http._construct_http_client(**kwargs) - heatclient.v1.shell.do_stack_list(mox.IgnoreArg(), mox.IgnoreArg()) - self.m.ReplayAll() heatclient.shell.main(('--os-endpoint-type=adminURL', 'stack-list',)) + http._construct_http_client.assert_called_once_with(**kwargs) + heatclient.v1.shell.do_stack_list.assert_called_once() + def test_endpoint_type_internal_url(self): self.register_keystone_auth_fixture() self.useFixture(fixtures.EnvironmentVariable('OS_ENDPOINT_TYPE', 'internalURL')) kwargs = { 'auth_url': 'http://keystone.example.com:5000/', - 'session': mox.IgnoreArg(), - 'auth': mox.IgnoreArg(), + 'session': mock.ANY, + 'auth': mock.ANY, 'service_type': 'orchestration', 'endpoint_type': 'internalURL', 'region_name': '', 'username': 'username', 'password': 'password', 'include_pass': False, - 'endpoint_override': mox.IgnoreArg(), + 'endpoint_override': mock.ANY, } - http._construct_http_client(**kwargs) - heatclient.v1.shell.do_stack_list(mox.IgnoreArg(), mox.IgnoreArg()) - self.m.ReplayAll() heatclient.shell.main(('stack-list',)) + http._construct_http_client.assert_called_once_with(**kwargs) + heatclient.v1.shell.do_stack_list.assert_called_once() + class ShellTestCommon(ShellBase): @@ -707,7 +719,6 @@ class ShellTestCommon(ShellBase): def test_debug_switch_raises_error(self): self.register_keystone_auth_fixture() self.mock_request_error('/stacks?', 'GET', exc.Unauthorized("FAIL")) - self.m.ReplayAll() args = ['--debug', 'stack-list'] self.assertRaises(exc.Unauthorized, heatclient.shell.main, args) @@ -716,8 +727,6 @@ class ShellTestCommon(ShellBase): self.register_keystone_auth_fixture() self.mock_request_error('/stacks?', 'GET', exc.CommandError("FAIL")) - self.m.ReplayAll() - args = ['-d', 'stack-list'] self.assertRaises(exc.CommandError, heatclient.shell.main, args) @@ -725,8 +734,6 @@ class ShellTestCommon(ShellBase): self.register_keystone_auth_fixture() self.mock_request_error('/stacks?', 'GET', exc.Unauthorized("FAIL")) - self.m.ReplayAll() - args = ['stack-list'] self.assertRaises(SystemExit, heatclient.shell.main, args) @@ -759,8 +766,6 @@ class ShellTestUserPass(ShellBase): self.register_keystone_auth_fixture() self.mock_stack_list() - self.m.ReplayAll() - list_text = self.shell('stack-list') required = [ @@ -783,8 +788,6 @@ class ShellTestUserPass(ShellBase): }, True) self.mock_stack_list(expected_url, show_nested=True) - self.m.ReplayAll() - list_text = self.shell('stack-list' ' --show-nested') @@ -801,7 +804,6 @@ class ShellTestUserPass(ShellBase): def test_stack_list_show_owner(self): self.register_keystone_auth_fixture() self.mock_stack_list() - self.m.ReplayAll() list_text = self.shell('stack-list --show-owner') @@ -819,8 +821,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_error('/stacks/bad', 'GET', exc.HTTPBadRequest(message)) - self.m.ReplayAll() - e = self.assertRaises(exc.HTTPException, self.shell, "stack-show bad") self.assertEqual("ERROR: " + message, str(e)) @@ -830,8 +830,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_error('/stacks/bad', 'GET', exc.HTTPBadRequest(message)) - self.m.ReplayAll() - exc.verbose = 1 e = self.assertRaises(exc.HTTPException, self.shell, "stack-show bad") @@ -842,7 +840,6 @@ class ShellTestUserPass(ShellBase): invalid_json = "ERROR: {Invalid JSON Error." self.mock_request_error('/stacks/bad', 'GET', exc.HTTPBadRequest(invalid_json)) - self.m.ReplayAll() e = self.assertRaises(exc.HTTPException, self.shell, "stack-show bad") self.assertEqual("ERROR: " + invalid_json, str(e)) @@ -852,7 +849,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_error('/stacks/bad', 'GET', exc.HTTPBadRequest(message)) - self.m.ReplayAll() e = self.assertRaises(exc.HTTPException, self.shell, "stack-show bad") self.assertEqual("ERROR: Internal Error", str(e)) @@ -862,7 +858,6 @@ class ShellTestUserPass(ShellBase): message = "The Stack (bad) could not be found." self.mock_request_error('/stacks/bad', 'GET', exc.HTTPBadRequest(message)) - self.m.ReplayAll() exc.verbose = 1 @@ -881,8 +876,6 @@ class ShellTestUserPass(ShellBase): }} self.mock_request_get('/stacks/teststack/1', resp_dict) - self.m.ReplayAll() - list_text = self.shell('stack-show teststack/1') required = [ @@ -910,8 +903,6 @@ class ShellTestUserPass(ShellBase): params = {'resolve_outputs': False} self.mock_request_get('/stacks/teststack/1', resp_dict, params=params) - self.m.ReplayAll() - list_text = self.shell( 'stack-show teststack/1 --no-resolve-outputs') @@ -954,7 +945,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_get('/stacks/teststack/1/outputs/%s' % output_key, find_output(output_key)) - self.m.ReplayAll() def _error_output_fake_response(self, output_key): @@ -971,8 +961,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_get('/stacks/teststack/1/outputs/%s' % output_key, resp_dict) - self.m.ReplayAll() - def test_template_show_cfn(self): self.register_keystone_auth_fixture() template_data = open(os.path.join(TEST_VAR_DIR, @@ -980,8 +968,6 @@ class ShellTestUserPass(ShellBase): resp_dict = jsonutils.loads(template_data) self.mock_request_get('/stacks/teststack/template', resp_dict) - self.m.ReplayAll() - show_text = self.shell('template-show teststack') required = [ '{', @@ -1003,7 +989,6 @@ class ShellTestUserPass(ShellBase): "Parameters": {}} self.mock_request_get('/stacks/teststack/template', resp_dict) - self.m.ReplayAll() show_text = self.shell('template-show teststack') required = [ @@ -1026,8 +1011,6 @@ class ShellTestUserPass(ShellBase): "outputs": {}} self.mock_request_get('/stacks/teststack/template', resp_dict) - self.m.ReplayAll() - show_text = self.shell('template-show teststack') required = [ "heat_template_version: '2013-05-23'", @@ -1044,9 +1027,7 @@ class ShellTestUserPass(ShellBase): "parameters": {}, "resources": {}, "outputs": {}} - self.mock_request_post('/validate', resp_dict, data=mox.IgnoreArg()) - - self.m.ReplayAll() + self.mock_request_post('/validate', resp_dict, data=mock.ANY) template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') cmd = 'template-validate -f %s -P foo=bar' % template_file @@ -1074,9 +1055,7 @@ class ShellTestUserPass(ShellBase): "tags": tags }} self.mock_request_post('/stacks/preview', resp_dict, - data=mox.IgnoreArg(), req_headers=True) - - self.m.ReplayAll() + data=mock.ANY, req_headers=True) template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') cmd = ('stack-preview teststack ' @@ -1117,10 +1096,9 @@ class ShellTestUserPass(ShellBase): def test_stack_create(self): self.register_keystone_auth_fixture() - self.mock_request_post('/stacks', None, data=mox.IgnoreArg(), + self.mock_request_post('/stacks', None, data=mock.ANY, status_code=201, req_headers=True) self.mock_stack_list() - self.m.ReplayAll() template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') create_text = self.shell( @@ -1150,7 +1128,7 @@ class ShellTestUserPass(ShellBase): "creation_time": "2012-10-25T01:58:47Z" }} self.mock_request_post('/stacks', stack_create_resp_dict, - data=mox.IgnoreArg(), req_headers=True, + data=mock.ANY, req_headers=True, status_code=201) self.mock_stack_list() @@ -1169,7 +1147,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_get('/stacks/%s/events?sort_dir=asc' % stack_id, event_list_resp_dict) self.mock_request_get('/stacks/teststack2', stack_show_resp_dict) - self.m.ReplayAll() template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') create_text = self.shell( @@ -1208,7 +1185,7 @@ class ShellTestUserPass(ShellBase): "creation_time": "2012-10-25T01:58:47Z" }} self.mock_request_post('/stacks', stack_create_resp_dict, - data=mox.IgnoreArg(), req_headers=True, + data=mock.ANY, req_headers=True, status_code=201) self.mock_stack_list() @@ -1228,8 +1205,6 @@ class ShellTestUserPass(ShellBase): event_list_resp_dict) self.mock_request_get('/stacks/teststack2', stack_show_resp_dict) - self.m.ReplayAll() - template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') e = self.assertRaises(exc.StackFailure, self.shell, @@ -1243,14 +1218,13 @@ class ShellTestUserPass(ShellBase): def test_stack_create_param_file(self): self.register_keystone_auth_fixture() - self.mock_request_post('/stacks', None, data=mox.IgnoreArg(), + self.mock_request_post('/stacks', None, data=mock.ANY, status_code=201, req_headers=True) self.mock_stack_list() - self.m.StubOutWithMock(utils, 'read_url_content') + self.useFixture(fixtures.MockPatchObject(utils, 'read_url_content', + return_value='xxxxxx')) url = 'file://%s/private_key.env' % TEST_VAR_DIR - utils.read_url_content(url).AndReturn('xxxxxx') - self.m.ReplayAll() template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') create_text = self.shell( @@ -1270,17 +1244,17 @@ class ShellTestUserPass(ShellBase): for r in required: self.assertRegex(create_text, r) + utils.read_url_content.assert_called_once_with(url) def test_stack_create_only_param_file(self): self.register_keystone_auth_fixture() - self.mock_request_post('/stacks', None, data=mox.IgnoreArg(), + self.mock_request_post('/stacks', None, data=mock.ANY, status_code=201, req_headers=True) self.mock_stack_list() - self.m.StubOutWithMock(utils, 'read_url_content') + self.useFixture(fixtures.MockPatchObject(utils, 'read_url_content', + return_value='xxxxxx')) url = 'file://%s/private_key.env' % TEST_VAR_DIR - utils.read_url_content(url).AndReturn('xxxxxx') - self.m.ReplayAll() template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') create_text = self.shell( @@ -1298,6 +1272,7 @@ class ShellTestUserPass(ShellBase): for r in required: self.assertRegex(create_text, r) + utils.read_url_content.assert_called_once_with(url) def test_stack_create_timeout(self): self.register_keystone_auth_fixture() @@ -1319,8 +1294,6 @@ class ShellTestUserPass(ShellBase): status_code=201, req_headers=True) self.mock_stack_list() - self.m.ReplayAll() - create_text = self.shell( 'stack-create teststack ' '--template-file=%s ' @@ -1361,8 +1334,6 @@ class ShellTestUserPass(ShellBase): data=expected_data) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell( 'stack-update teststack2/2 ' '--template-file=%s ' @@ -1383,9 +1354,10 @@ class ShellTestUserPass(ShellBase): def test_stack_create_url(self): self.register_keystone_auth_fixture() - self.m.StubOutWithMock(request, 'urlopen') - request.urlopen('http://no.where/minimal.template').AndReturn( - six.StringIO('{"AWSTemplateFormatVersion" : "2010-09-09"}')) + url_content = six.StringIO( + '{"AWSTemplateFormatVersion" : "2010-09-09"}') + self.useFixture(fixtures.MockPatchObject(request, 'urlopen', + return_value=url_content)) expected_data = { 'files': {}, @@ -1403,8 +1375,6 @@ class ShellTestUserPass(ShellBase): status_code=201, req_headers=True) self.mock_stack_list() - self.m.ReplayAll() - create_text = self.shell( 'stack-create teststack ' '--template-url=http://no.where/minimal.template ' @@ -1420,6 +1390,8 @@ class ShellTestUserPass(ShellBase): ] for r in required: self.assertRegex(create_text, r) + request.urlopen.assert_called_once_with( + 'http://no.where/minimal.template') def test_stack_create_object(self): self.register_keystone_auth_fixture() @@ -1431,12 +1403,10 @@ class ShellTestUserPass(ShellBase): template_data, raw=True) - self.mock_request_post('/stacks', None, data=mox.IgnoreArg(), + self.mock_request_post('/stacks', None, data=mock.ANY, status_code=201, req_headers=True) self.mock_stack_list() - self.m.ReplayAll() - create_text = self.shell( 'stack-create teststack2 ' '--template-object=http://no.where/container/minimal.template ' @@ -1473,8 +1443,6 @@ class ShellTestUserPass(ShellBase): status_code=201, req_headers=True) self.mock_stack_list() - self.m.ReplayAll() - create_text = self.shell( 'stack-create teststack ' '--template-file=%s ' @@ -1516,7 +1484,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_delete('/stacks/teststack/1/abandon', abandoned_stack) - self.m.ReplayAll() abandon_resp = self.shell('stack-abandon teststack/1') self.assertEqual(abandoned_stack, jsonutils.loads(abandon_resp)) @@ -1542,7 +1509,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_delete('/stacks/teststack/1/abandon', abandoned_stack) - self.m.ReplayAll() with tempfile.NamedTemporaryFile() as file_obj: self.shell('stack-abandon teststack/1 -O %s' % file_obj.name) @@ -1551,12 +1517,10 @@ class ShellTestUserPass(ShellBase): def test_stack_adopt(self): self.register_keystone_auth_fixture() - self.mock_request_post('/stacks', None, data=mox.IgnoreArg(), + self.mock_request_post('/stacks', None, data=mock.ANY, status_code=201, req_headers=True) self.mock_stack_list() - self.m.ReplayAll() - adopt_data_file = os.path.join(TEST_VAR_DIR, 'adopt_stack_data.json') adopt_text = self.shell( 'stack-adopt teststack ' @@ -1577,10 +1541,9 @@ class ShellTestUserPass(ShellBase): def test_stack_adopt_with_environment(self): self.register_keystone_auth_fixture() - self.mock_request_post('/stacks', None, data=mox.IgnoreArg(), + self.mock_request_post('/stacks', None, data=mock.ANY, status_code=201, req_headers=True) self.mock_stack_list() - self.m.ReplayAll() adopt_data_file = os.path.join(TEST_VAR_DIR, 'adopt_stack_data.json') environment_file = os.path.join(TEST_VAR_DIR, 'environment.json') @@ -1592,14 +1555,12 @@ class ShellTestUserPass(ShellBase): def test_stack_adopt_without_data(self): self.register_keystone_auth_fixture() failed_msg = 'Need to specify --adopt-file' - self.m.ReplayAll() self.shell_error('stack-adopt teststack ', failed_msg, exception=exc.CommandError) def test_stack_adopt_empty_data_file(self): failed_msg = 'Invalid adopt-file, no data!' self.register_keystone_auth_fixture() - self.m.ReplayAll() with tempfile.NamedTemporaryFile() as file_obj: self.shell_error( 'stack-adopt teststack ' @@ -1615,14 +1576,13 @@ class ShellTestUserPass(ShellBase): 'environment': {}, 'template': template_data, 'disable_rollback': False, - 'parameters': mox.IgnoreArg() + 'parameters': mock.ANY } self.mock_request_put( '/stacks/teststack2/2', 'The request is accepted for processing.', data=expected_data) self.mock_stack_list() - self.m.ReplayAll() update_text = self.shell( 'stack-update teststack2/2 ' @@ -1650,14 +1610,13 @@ class ShellTestUserPass(ShellBase): 'environment': {}, 'template': template_data, 'disable_rollback': True, - 'parameters': mox.IgnoreArg() + 'parameters': mock.ANY } self.mock_request_put( '/stacks/teststack2', 'The request is accepted for processing.', data=expected_data) self.mock_stack_list() - self.m.ReplayAll() update_text = self.shell( 'stack-update teststack2 ' @@ -1678,7 +1637,6 @@ class ShellTestUserPass(ShellBase): def test_stack_update_fault_rollback_value(self): self.register_keystone_auth_fixture() - self.m.ReplayAll() template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') self.shell_error('stack-update teststack2/2 ' '--rollback Foo ' @@ -1695,14 +1653,13 @@ class ShellTestUserPass(ShellBase): expected_data = {'files': {}, 'environment': {}, 'template': template_data, - 'parameters': mox.IgnoreArg() + 'parameters': mock.ANY } self.mock_request_put( '/stacks/teststack2', 'The request is accepted for processing.', data=expected_data) self.mock_stack_list() - self.m.ReplayAll() update_text = self.shell( 'stack-update teststack2 ' @@ -1737,8 +1694,6 @@ class ShellTestUserPass(ShellBase): ) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell( 'stack-update teststack2/2 ' '--template-file=%s ' @@ -1771,8 +1726,6 @@ class ShellTestUserPass(ShellBase): ) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell( 'stack-update teststack2/2 ' '--template-file=%s ' @@ -1809,8 +1762,6 @@ class ShellTestUserPass(ShellBase): ) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell( 'stack-update teststack2/2 ' '--template-file=%s ' @@ -1851,8 +1802,6 @@ class ShellTestUserPass(ShellBase): ) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell( 'stack-update teststack2/2 ' '--template-file=%s ' @@ -1888,8 +1837,6 @@ class ShellTestUserPass(ShellBase): ) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell( 'stack-update teststack2/2 ' '--existing') @@ -1921,8 +1868,6 @@ class ShellTestUserPass(ShellBase): ) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell( 'stack-update teststack2/2 ' '--template-file=%s ' @@ -1989,8 +1934,6 @@ class ShellTestUserPass(ShellBase): else: self.mock_request_put(path, resp_dict, data=expected_data) - self.m.ReplayAll() - def test_stack_update_dry_run(self): template_file = os.path.join(TEST_VAR_DIR, 'minimal.template') self._setup_stubs_update_dry_run(template_file) @@ -2071,12 +2014,9 @@ class ShellTestUserPass(ShellBase): self.mock_request_delete('/stacks/teststack2/2', None) - self.m.ReplayAll() - resp = self.shell('stack-delete teststack2/2') resp_text = 'Are you sure you want to delete this stack(s) [y/N]? ' self.assertEqual(resp_text, resp) - self.m.ReplayAll() mock_stdin.readline.return_value = 'y' resp = self.shell('stack-delete teststack2/2') @@ -2098,7 +2038,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_delete('/stacks/teststack2/2') - self.m.ReplayAll() # -y from the shell should skip the n/y prompt resp = self.shell('stack-delete -y teststack2/2') msg = 'Request to delete stack teststack2/2 has been accepted.' @@ -2108,7 +2047,6 @@ class ShellTestUserPass(ShellBase): self.register_keystone_auth_fixture() self.mock_request_delete('/stacks/teststack2/2') - self.m.ReplayAll() resp = self.shell('stack-delete teststack2/2') msg = 'Request to delete stack teststack2/2 has been accepted.' self.assertRegex(resp, msg) @@ -2118,7 +2056,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_delete('/stacks/teststack/1') self.mock_request_delete('/stacks/teststack2/2') - self.m.ReplayAll() resp = self.shell('stack-delete teststack/1 teststack2/2') msg1 = 'Request to delete stack teststack/1 has been accepted.' msg2 = 'Request to delete stack teststack2/2 has been accepted.' @@ -2129,7 +2066,6 @@ class ShellTestUserPass(ShellBase): self.register_keystone_auth_fixture() self.mock_request_error('/stacks/teststack1/1', 'DELETE', exc.HTTPNotFound()) - self.m.ReplayAll() error = self.assertRaises( exc.CommandError, self.shell, 'stack-delete teststack1/1') self.assertIn('Unable to delete 1 of the 1 stacks.', @@ -2139,7 +2075,6 @@ class ShellTestUserPass(ShellBase): self.register_keystone_auth_fixture() self.mock_request_error('/stacks/teststack1/1', 'DELETE', exc.Forbidden()) - self.m.ReplayAll() error = self.assertRaises( exc.CommandError, self.shell, 'stack-delete teststack1/1') self.assertIn('Unable to delete 1 of the 1 stacks.', @@ -2155,8 +2090,6 @@ class ShellTestUserPass(ShellBase): } self.mock_request_get('/build_info', resp_dict) - self.m.ReplayAll() - build_info_text = self.shell('build-info') required = [ @@ -2180,7 +2113,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_post('/stacks/teststack/1/snapshots', resp_dict, data={}) - self.m.ReplayAll() resp = self.shell('stack-snapshot teststack/1') self.assertEqual(resp_dict, jsonutils.loads(resp)) @@ -2197,7 +2129,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_get('/stacks/teststack/1/snapshots', resp_dict) - self.m.ReplayAll() list_text = self.shell('snapshot-list teststack/1') required = [ @@ -2223,7 +2154,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_get('/stacks/teststack/1/snapshots/2', resp_dict) - self.m.ReplayAll() resp = self.shell('snapshot-show teststack/1 2') self.assertEqual(resp_dict, jsonutils.loads(resp)) @@ -2246,13 +2176,10 @@ class ShellTestUserPass(ShellBase): self.mock_request_delete('/stacks/teststack/1/snapshots/2', resp_dict) - self.m.ReplayAll() - resp = self.shell('snapshot-delete teststack/1 2') resp_text = ('Are you sure you want to delete the snapshot of ' 'this stack [Y/N]?') self.assertEqual(resp_text, resp) - self.m.ReplayAll() mock_stdin.readline.return_value = 'Y' resp = self.shell('snapshot-delete teststack/1 2') @@ -2279,7 +2206,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_delete('/stacks/teststack/1/snapshots/2', resp_dict) - self.m.ReplayAll() # -y from the shell should skip the n/y prompt resp = self.shell('snapshot-delete -y teststack/1 2') msg = _("Request to delete the snapshot 2 of the stack " @@ -2295,7 +2221,6 @@ class ShellTestUserPass(ShellBase): }} self.mock_request_delete('/stacks/teststack/1/snapshots/2', resp_dict) - self.m.ReplayAll() resp = self.shell('snapshot-delete teststack/1 2') msg = _("Request to delete the snapshot 2 of the stack " "teststack/1 has been accepted.") @@ -2307,7 +2232,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_post('/stacks/teststack/1/snapshots/2/restore', None, status_code=204) - self.m.ReplayAll() resp = self.shell('stack-restore teststack/1 2') self.assertEqual("", resp) @@ -2324,7 +2248,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_get('/stacks/teststack/1/outputs', resp_dict) - self.m.ReplayAll() list_text = self.shell('output-list teststack/1') required = [ @@ -2360,7 +2283,6 @@ class ShellTestUserPass(ShellBase): exc.HTTPNotFound()) self.mock_request_get('/stacks/teststack/1', stack_dict) - self.m.ReplayAll() list_text = self.shell('output-list teststack/1') required = [ @@ -2393,7 +2315,6 @@ class ShellTestUserPass(ShellBase): self.mock_request_get('/stacks/teststack/1/outputs', resp_dict) self.mock_request_get('/stacks/teststack/1/outputs/key', resp_dict1) - self.m.ReplayAll() list_text = self.shell('output-show --with-detail teststack/1 --all') required = [ 'output_key', @@ -2416,7 +2337,6 @@ class ShellTestUserPass(ShellBase): }} self.mock_request_get('/stacks/teststack/1/outputs/key', resp_dict) - self.m.ReplayAll() resp = self.shell('output-show --with-detail teststack/1 key') required = [ 'output_key', @@ -2448,7 +2368,6 @@ class ShellTestUserPass(ShellBase): exc.HTTPNotFound()) self.mock_request_get('/stacks/teststack/1', stack_dict) - self.m.ReplayAll() resp = self.shell('output-show --with-detail teststack/1 key') required = [ 'output_key', @@ -2577,8 +2496,6 @@ class ShellTestActions(ShellBase): status_code=202) self.mock_stack_list() - self.m.ReplayAll() - update_text = self.shell('stack-cancel-update teststack2') required = [ @@ -2600,8 +2517,6 @@ class ShellTestActions(ShellBase): status_code=202) self.mock_stack_list() - self.m.ReplayAll() - check_text = self.shell('action-check teststack2') required = [ @@ -2623,8 +2538,6 @@ class ShellTestActions(ShellBase): status_code=202) self.mock_stack_list() - self.m.ReplayAll() - suspend_text = self.shell('action-suspend teststack2') required = [ @@ -2646,8 +2559,6 @@ class ShellTestActions(ShellBase): status_code=202) self.mock_stack_list() - self.m.ReplayAll() - resume_text = self.shell('action-resume teststack2') required = [ @@ -2690,8 +2601,6 @@ class ShellTestEvents(ShellBase): resource_name))), resp_dict) - self.m.ReplayAll() - event_list_text = self.shell('event-list {0} --resource {1}'.format( stack_id, resource_name)) @@ -2724,7 +2633,6 @@ class ShellTestEvents(ShellBase): stack_id = 'teststack/1' self.mock_request_get('/stacks/%s/events?sort_dir=asc' % stack_id, resp_dict) - self.m.ReplayAll() event_list_text = self.shell('event-list {0} --format log'.format( stack_id)) @@ -2768,8 +2676,6 @@ class ShellTestEvents(ShellBase): ), resp_dict) - self.m.ReplayAll() - event_list_text = self.shell('event-show {0} {1} {2}'.format( stack_id, resource_name, self.event_id_one)) @@ -2811,8 +2717,6 @@ class ShellTestEventsNested(ShellBase): stack_id = 'teststack/1' resource_name = 'aResource' - self.m.ReplayAll() - error = self.assertRaises( exc.CommandError, self.shell, 'event-list {0} --resource {1} --nested-depth 5'.format( @@ -2838,7 +2742,6 @@ class ShellTestEventsNested(ShellBase): self.mock_request_get('/stacks/%s/events?sort_dir=asc' % stack_id, resp_dict) - self.m.ReplayAll() list_text = self.shell('event-list %s --nested-depth 0' % stack_id) required = ['id', 'eventid1', 'eventid2'] for r in required: @@ -2887,7 +2790,6 @@ class ShellTestEventsNested(ShellBase): % stack_id) self._stub_event_list_response_old_api( stack_id, nested_id, timestamps, first_request) - self.m.ReplayAll() list_text = self.shell('event-list %s --nested-depth 1' % stack_id) required = ['id', 'p_eventid1', 'p_eventid2', 'n_eventid1', 'n_eventid2', 'stack_name', 'teststack', 'nested'] @@ -2910,7 +2812,6 @@ class ShellTestEventsNested(ShellBase): '&sort_dir=asc' % stack_id) self._stub_event_list_response_old_api( stack_id, nested_id, timestamps, first_request) - self.m.ReplayAll() list_text = self.shell( 'event-list %s --nested-depth 1 --marker n_eventid1' % stack_id) required = ['id', 'p_eventid2', 'n_eventid1', 'n_eventid2', @@ -2935,7 +2836,6 @@ class ShellTestEventsNested(ShellBase): '&sort_dir=asc' % stack_id) self._stub_event_list_response_old_api( stack_id, nested_id, timestamps, first_request) - self.m.ReplayAll() list_text = self.shell( 'event-list %s --nested-depth 1 --limit 2' % stack_id) required = ['id', 'p_eventid1', 'n_eventid1', @@ -2999,7 +2899,6 @@ class ShellTestEventsNested(ShellBase): url = '/stacks/%s/events?nested_depth=1&sort_dir=asc' % stack_id self.mock_request_get(url, ev_resp_dict) - self.m.ReplayAll() list_text = self.shell('event-list %s --nested-depth 1 --format log' % stack_id) self.assertEqual('''\ @@ -3018,7 +2917,6 @@ class ShellTestEventsNested(ShellBase): url = ('/stacks/%s/events?marker=n_eventid1&nested_depth=1' '&sort_dir=asc' % stack_id) self.mock_request_get(url, ev_resp_dict) - self.m.ReplayAll() list_text = self.shell('event-list %s --nested-depth 1 --format log ' '--marker n_eventid1' % stack_id) @@ -3037,7 +2935,6 @@ class ShellTestEventsNested(ShellBase): url = ('/stacks/%s/events?limit=2&nested_depth=1&sort_dir=asc' % stack_id) self.mock_request_get(url, ev_resp_dict) - self.m.ReplayAll() list_text = self.shell('event-list %s --nested-depth 1 --format log ' '--limit 2' % stack_id) @@ -3115,7 +3012,6 @@ class ShellTestHookFunctions(ShellBase): stack_id = 'teststack/1' nested_id = 'nested/2' self._stub_responses(stack_id, nested_id, 'CREATE') - self.m.ReplayAll() list_text = self.shell('hook-poll %s --nested-depth 1' % stack_id) hook_reason = 'CREATE paused until Hook pre-create is cleared' required = ['id', 'p_eventid2', 'stack_name', 'teststack', hook_reason] @@ -3130,7 +3026,6 @@ class ShellTestHookFunctions(ShellBase): stack_id = 'teststack/1' nested_id = 'nested/2' self._stub_responses(stack_id, nested_id, 'UPDATE') - self.m.ReplayAll() list_text = self.shell('hook-poll %s --nested-depth 1' % stack_id) hook_reason = 'UPDATE paused until Hook pre-update is cleared' required = ['id', 'p_eventid2', 'stack_name', 'teststack', hook_reason] @@ -3145,7 +3040,6 @@ class ShellTestHookFunctions(ShellBase): stack_id = 'teststack/1' nested_id = 'nested/2' self._stub_responses(stack_id, nested_id, 'DELETE') - self.m.ReplayAll() list_text = self.shell('hook-poll %s --nested-depth 1' % stack_id) hook_reason = 'DELETE paused until Hook pre-delete is cleared' required = ['id', 'p_eventid2', 'stack_name', 'teststack', hook_reason] @@ -3159,7 +3053,6 @@ class ShellTestHookFunctions(ShellBase): self.register_keystone_auth_fixture() stack_id = 'teststack/1' self._stub_stack_response(stack_id, status='COMPLETE') - self.m.ReplayAll() error = self.assertRaises( exc.CommandError, self.shell, 'hook-poll %s --nested-depth 1' % stack_id) @@ -3169,7 +3062,6 @@ class ShellTestHookFunctions(ShellBase): def test_shell_nested_depth_invalid_value(self): self.register_keystone_auth_fixture() stack_id = 'teststack/1' - self.m.ReplayAll() error = self.assertRaises( exc.CommandError, self.shell, 'hook-poll %s --nested-depth Z' % stack_id) @@ -3179,7 +3071,6 @@ class ShellTestHookFunctions(ShellBase): self.register_keystone_auth_fixture() stack_id = 'teststack/1' self._stub_stack_response(stack_id, status='COMPLETE') - self.m.ReplayAll() error = self.assertRaises( exc.CommandError, self.shell, 'hook-clear %s aresource' % stack_id) @@ -3190,7 +3081,6 @@ class ShellTestHookFunctions(ShellBase): self.register_keystone_auth_fixture() stack_id = 'teststack/1' self._stub_stack_response(stack_id, action='BADACTION') - self.m.ReplayAll() error = self.assertRaises( exc.CommandError, self.shell, 'hook-clear %s aresource' % stack_id) @@ -3223,8 +3113,6 @@ class ShellTestResources(ShellBase): stack_id = 'teststack/1' self.mock_request_get('/stacks/%s/resources' % stack_id, resp_dict) - self.m.ReplayAll() - resource_list_text = self.shell('resource-list {0}'.format(stack_id)) required = [ @@ -3259,8 +3147,6 @@ class ShellTestResources(ShellBase): stack_id = 'teststack/1' self.mock_request_get('/stacks/%s/resources' % stack_id, resp_dict) - self.m.ReplayAll() - resource_list_text = self.shell('resource-list {0}'.format(stack_id)) self.assertEqual('''\ @@ -3291,8 +3177,6 @@ class ShellTestResources(ShellBase): self.mock_request_get('/stacks/%s/resources?%s' % ( stack_id, query_args), resp_dict) - self.m.ReplayAll() - shell_cmd = 'resource-list %s %s' % (stack_id, cmd_args) resource_list_text = self.shell(shell_cmd) @@ -3349,8 +3233,6 @@ class ShellTestResources(ShellBase): resource_name)) ), resp_dict) - self.m.ReplayAll() - resource_show_text = self.shell( 'resource-show {0} {1} --with-attr attr_a ' '--with-attr attr_b'.format( @@ -3394,8 +3276,6 @@ class ShellTestResources(ShellBase): data={'message': 'Content'} ) - self.m.ReplayAll() - text = self.shell( 'resource-signal {0} {1} -D {{"message":"Content"}}'.format( stack_id, resource_name)) @@ -3415,7 +3295,6 @@ class ShellTestResources(ShellBase): '', data=None ) - self.m.ReplayAll() text = self.shell( 'resource-signal {0} {1}'.format(stack_id, resource_name)) @@ -3426,8 +3305,6 @@ class ShellTestResources(ShellBase): stack_id = 'teststack/1' resource_name = 'aResource' - self.m.ReplayAll() - error = self.assertRaises( exc.CommandError, self.shell, 'resource-signal {0} {1} -D [2'.format( @@ -3439,8 +3316,6 @@ class ShellTestResources(ShellBase): stack_id = 'teststack/1' resource_name = 'aResource' - self.m.ReplayAll() - error = self.assertRaises( exc.CommandError, self.shell, 'resource-signal {0} {1} -D "message"'.format( @@ -3452,8 +3327,6 @@ class ShellTestResources(ShellBase): stack_id = 'teststack/1' resource_name = 'aResource' - self.m.ReplayAll() - error = self.assertRaises( exc.CommandError, self.shell, 'resource-signal {0} {1} -D "message" -f foo'.format( @@ -3476,8 +3349,6 @@ class ShellTestResources(ShellBase): data={'message': 'Content'} ) - self.m.ReplayAll() - with tempfile.NamedTemporaryFile() as data_file: data_file.write(b'{"message":"Content"}') data_file.flush() @@ -3502,8 +3373,6 @@ class ShellTestResources(ShellBase): data={'mark_unhealthy': True, 'resource_status_reason': 'Any'}) - self.m.ReplayAll() - text = self.shell( 'resource-mark-unhealthy {0} {1} Any'.format( stack_id, resource_name)) @@ -3525,8 +3394,6 @@ class ShellTestResources(ShellBase): data={'mark_unhealthy': False, 'resource_status_reason': 'Any'}) - self.m.ReplayAll() - text = self.shell( 'resource-mark-unhealthy --reset {0} {1} Any'.format( stack_id, resource_name)) @@ -3548,8 +3415,6 @@ class ShellTestResources(ShellBase): data={'mark_unhealthy': True, 'resource_status_reason': ''}) - self.m.ReplayAll() - text = self.shell( 'resource-mark-unhealthy {0} {1}'.format( stack_id, resource_name)) @@ -3572,8 +3437,6 @@ class ShellTestResourceTypes(ShellBase): '/resource_types/OS%3A%3ANova%3A%3AKeyPair/template' '?template_type=hot', resp_dict) - self.m.ReplayAll() - show_text = self.shell( 'resource-type-template -F yaml -t hot OS::Nova::KeyPair') required = [ @@ -3596,8 +3459,6 @@ class ShellTestResourceTypes(ShellBase): '/resource_types/OS%3A%3ANova%3A%3AKeyPair/template' '?template_type=cfn', resp_dict) - self.m.ReplayAll() - show_text = self.shell( 'resource-type-template -F json OS::Nova::KeyPair') required = [ @@ -3686,22 +3547,25 @@ class ShellTestConfig(ShellBase): 'id': 'abcd' }} - self.m.StubOutWithMock(request, 'urlopen') - request.urlopen('file:///tmp/defn').AndReturn( - six.StringIO(yaml.safe_dump(definition, indent=2))) - request.urlopen('file:///tmp/config_script').AndReturn( - six.StringIO('the config script')) + output = [ + six.StringIO(yaml.safe_dump(definition, indent=2)), + six.StringIO('the config script'), + ] + self.useFixture(fixtures.MockPatchObject(request, 'urlopen', + side_effect=output)) self.mock_request_post('/validate', resp_dict, data=validate_template) self.mock_request_post('/software_configs', resp_dict, data=create_dict) - self.m.ReplayAll() - text = self.shell('config-create -c /tmp/config_script ' '-g script -f /tmp/defn config_name') self.assertEqual(resp_dict['software_config'], jsonutils.loads(text)) + request.urlopen.assert_has_calls([ + mock.call('file:///tmp/defn'), + mock.call('file:///tmp/config_script'), + ]) def test_config_show(self): self.register_keystone_auth_fixture() @@ -3718,8 +3582,6 @@ class ShellTestConfig(ShellBase): self.mock_request_error('/software_configs/abcde', 'GET', exc.HTTPNotFound()) - self.m.ReplayAll() - text = self.shell('config-show abcd') required = [ @@ -3747,7 +3609,6 @@ class ShellTestConfig(ShellBase): exc.HTTPNotFound()) self.mock_request_error('/software_configs/qwer', 'DELETE', exc.HTTPNotFound()) - self.m.ReplayAll() self.assertEqual('', self.shell('config-delete abcd qwer')) @@ -3825,8 +3686,6 @@ class ShellTestDeployment(ShellBase): self.mock_request_error('/software_configs/defgh', 'GET', exc.HTTPNotFound()) - self.m.ReplayAll() - text = self.shell('deployment-create -c defg -sinst01 xxx') required = [ @@ -3848,7 +3707,6 @@ class ShellTestDeployment(ShellBase): self.assertRaises(exc.CommandError, self.shell, 'deployment-create -c defgh -s inst01 yyy') - self.m.VerifyAll() def test_deploy_list(self): self.register_keystone_auth_fixture() @@ -3872,8 +3730,6 @@ class ShellTestDeployment(ShellBase): self.mock_request_get('/software_deployments?', resp_dict) self.mock_request_get('/software_deployments?server_id=123', resp_dict) - self.m.ReplayAll() - list_text = self.shell('deployment-list') required = [ @@ -3916,8 +3772,6 @@ class ShellTestDeployment(ShellBase): self.mock_request_error('/software_deployments/defgh', 'GET', exc.HTTPNotFound()) - self.m.ReplayAll() - text = self.shell('deployment-show defg') required = [ @@ -3974,8 +3828,6 @@ class ShellTestDeployment(ShellBase): _delete_request_success('defg') _delete_request_success('qwer') - self.m.ReplayAll() - error = self.assertRaises( exc.CommandError, self.shell, 'deployment-delete defg qwer') self.assertIn('Unable to delete 2 of the 2 deployments.', @@ -4000,8 +3852,6 @@ class ShellTestDeployment(ShellBase): ]} self.mock_request_get('/software_deployments/metadata/aaaa', resp_dict) - self.m.ReplayAll() - build_info_text = self.shell('deployment-metadata-show aaaa') required = [ @@ -4036,8 +3886,6 @@ class ShellTestDeployment(ShellBase): for a in range(9): self.mock_request_get('/software_deployments/defg', resp_dict) - self.m.ReplayAll() - self.assertRaises(exc.CommandError, self.shell, 'deployment-output-show defgh result') self.assertEqual( @@ -4097,8 +3945,6 @@ class ShellTestBuildInfo(ShellBase): } self.mock_request_get('/build_info', resp_dict) - self.m.ReplayAll() - build_info_text = self.shell('build-info') required = [ @@ -4140,13 +3986,10 @@ class ShellTestUserPassKeystoneV3(ShellTestUserPass): self.set_fake_env(FAKE_ENV_KEYSTONE_V3) -class ShellTestStandaloneToken(ShellTestUserPass): - - # Rerun all ShellTestUserPass test in standalone mode, where we - # specify --os-no-client-auth, a token and Heat endpoint +class StandaloneTokenMixin(object): def setUp(self): self.token = 'a_token' - super(ShellTestStandaloneToken, self).setUp() + super(StandaloneTokenMixin, self).setUp() self.client = http.HTTPClient def _set_fake_env(self): @@ -4164,6 +4007,11 @@ class ShellTestStandaloneToken(ShellTestUserPass): } self.set_fake_env(fake_env) + +class ShellTestStandaloneToken(StandaloneTokenMixin, ShellTestUserPass): + # Rerun all ShellTestUserPass test in standalone mode, where we + # specify --os-no-client-auth, a token and Heat endpoint + def test_bad_template_file(self): self.register_keystone_auth_fixture() failed_msg = 'Error parsing template ' @@ -4180,25 +4028,13 @@ class ShellTestStandaloneToken(ShellTestUserPass): self.shell_error("stack-create ts -f %s" % bad_json_file.name, failed_msg, exception=exc.CommandError) + +class ShellTestStandaloneTokenArgs(StandaloneTokenMixin, ShellTestNoMoxBase): + def test_commandline_args_passed_to_requests(self): """Check that we have sent the proper arguments to requests.""" self.register_keystone_auth_fixture() - # we need a mock for 'request' to check whether proper arguments - # sent to request in the form of HTTP headers. So unset - # stubs(json_request, raw_request) and create a new mock for request. - self.m.UnsetStubs() - self.m.StubOutWithMock(requests, 'request') - - # Record a 200 - mock_conn = http.requests.request( - 'GET', 'http://no.where/stacks?', - allow_redirects=False, - headers={'Content-Type': 'application/json', - 'Accept': 'application/json', - 'X-Auth-Token': self.token, - 'X-Auth-Url': BASE_URL, - 'User-Agent': 'python-heatclient'}) resp_dict = {"stacks": [ { "id": "1", @@ -4208,14 +4044,12 @@ class ShellTestStandaloneToken(ShellTestUserPass): "stack_status": 'CREATE_COMPLETE', "creation_time": "2014-10-15T01:58:47Z" }]} - mock_conn.AndReturn( - fakes.FakeHTTPResponse( - 200, 'OK', - {'content-type': 'application/json'}, - jsonutils.dumps(resp_dict))) + self.requests.get('http://no.where/stacks', + status_code=200, + headers={'Content-Type': 'application/json'}, + json=resp_dict) # Replay, create client, assert - self.m.ReplayAll() list_text = self.shell('stack-list') required = [ 'id', @@ -4420,7 +4254,6 @@ class ShellTestManageService(ShellBase): exc.verbose = 1 - self.m.ReplayAll() e = self.assertRaises(exc.HTTPException, self.shell, "service-list") self.assertIn(message, str(e)) @@ -4442,7 +4275,6 @@ class ShellTestManageService(ShellBase): } self.mock_request_get('/services', resp_dict) - self.m.ReplayAll() services_text = self.shell('service-list') required = [ diff --git a/heatclient/tests/unit/test_template_utils.py b/heatclient/tests/unit/test_template_utils.py index 81ef955..082283a 100644 --- a/heatclient/tests/unit/test_template_utils.py +++ b/heatclient/tests/unit/test_template_utils.py @@ -11,11 +11,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import base64 import json import tempfile import mock +from oslo_serialization import base64 import six from six.moves.urllib import error import testtools @@ -727,7 +727,7 @@ class TestGetTemplateContents(testtools.TestCase): 'content': {'get_file': url}, 'encoding': 'b64'}]}}}}} with mock.patch('six.moves.urllib.request.urlopen') as mock_url: - raw_content = base64.decodestring(content) + raw_content = base64.decode_as_bytes(content) response = six.BytesIO(raw_content) mock_url.return_value = response files = {} @@ -744,8 +744,8 @@ t9SdXgLAAEE\n6AMAAATpAwAAaGVhdApQSwECHgMKAAAAAABGWVpEWzgLgQUAAAAF\ AAAACAAYAAAAAAABAAAApIEA\nAAAAaGVhdC50eHRVVAUAAxRbDVN1eAsAAQToAwA\ ABOkDAABQSwUGAAAAAAEAAQBOAAAARwAAAAAA\n''' # zip has '\0' in stream - self.assertIn(b'\0', base64.decodestring(content)) - decoded_content = base64.decodestring(content) + self.assertIn(b'\0', base64.decode_as_bytes(content)) + decoded_content = base64.decode_as_bytes(content) if six.PY3: self.assertRaises(UnicodeDecodeError, decoded_content.decode) else: @@ -760,8 +760,8 @@ ABOkDAABQSwUGAAAAAAEAAQBOAAAARwAAAAAA\n''' filename = 'heat.utf16' content = b'//4tTkhTCgA=\n' # utf6 has '\0' in stream - self.assertIn(b'\0', base64.decodestring(content)) - decoded_content = base64.decodestring(content) + self.assertIn(b'\0', base64.decode_as_bytes(content)) + decoded_content = base64.decode_as_bytes(content) if six.PY3: self.assertRaises(UnicodeDecodeError, decoded_content.decode) else: @@ -775,8 +775,8 @@ ABOkDAABQSwUGAAAAAAEAAQBOAAAARwAAAAAA\n''' filename = 'heat.gb18030' content = b'1tDO5wo=\n' # gb18030 has no '\0' in stream - self.assertNotIn('\0', base64.decodestring(content)) - decoded_content = base64.decodestring(content) + self.assertNotIn('\0', base64.decode_as_bytes(content)) + decoded_content = base64.decode_as_bytes(content) if six.PY3: self.assertRaises(UnicodeDecodeError, decoded_content.decode) else: |