From 73c1a34e94e48af7a1272772dbedf6818f30e544 Mon Sep 17 00:00:00 2001 From: Nikolaj Starodubtsev Date: Fri, 14 Feb 2014 15:26:04 +0400 Subject: [PATCH] Add test coverage for base client modules Add tests for base client modules such as climateclient/base.py, climateclient/client.py, etc Change-Id: If661e4bdaefd7fb6dfac7453bec186485a99e9d9 Closes-Bug: #1272371 --- climateclient/tests/test_base.py | 102 +++++++++++++++++++++ climateclient/tests/test_client.py | 44 +++++++++ climateclient/tests/test_command.py | 136 ++++++++++++++++++++++++++++ climateclient/tests/test_shell.py | 94 +++++++++++++++++++ climateclient/utils.py | 2 +- 5 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 climateclient/tests/test_base.py create mode 100644 climateclient/tests/test_client.py create mode 100644 climateclient/tests/test_command.py create mode 100644 climateclient/tests/test_shell.py diff --git a/climateclient/tests/test_base.py b/climateclient/tests/test_base.py new file mode 100644 index 0000000..0b93e05 --- /dev/null +++ b/climateclient/tests/test_base.py @@ -0,0 +1,102 @@ +# Copyright (c) 2014 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import requests + +from climateclient import base +from climateclient import exception +from climateclient import tests + + +class BaseClientManagerTestCase(tests.TestCase): + + def setUp(self): + super(BaseClientManagerTestCase, self).setUp() + + self.url = "www.fake.com/reservation" + self.token = "aaa-bbb-ccc" + self.fake_key = "fake_key" + self.response = "RESPONSE" + self.exception = exception + + self.manager = base.BaseClientManager(self.url, self.token) + self.request = self.patch(requests, "request") + + def test_get(self): + self.patch( + self.manager, "request").return_value = ( + self.response, {"fake_key": "FAKE"}) + self.assertEqual(self.manager._get(self.url, self.fake_key), "FAKE") + + def test_create(self): + self.patch( + self.manager, "request").return_value = ( + self.response, {"fake_key": "FAKE"}) + self.assertEqual(self.manager._create(self.url, {}, self.fake_key), + "FAKE") + + def test_delete(self): + request = self.patch(self.manager, "request") + request.return_value = (self.response, {"fake_key": "FAKE"}) + self.manager._delete(self.url) + request.assert_called_once_with(self.url, "DELETE") + + def test_update(self): + self.patch( + self.manager, "request").return_value = ( + self.response, {"fake_key": "FAKE"}) + self.assertEqual(self.manager._update(self.url, {}, self.fake_key), + "FAKE") + + def test_request_ok_with_body(self): + self.request.return_value.status_code = 200 + self.request.return_value.text = '{"key": "value"}' + + kwargs = {"body": {"key": "value"}} + + self.assertEqual(( + self.request(), {"key": "value"}), + self.manager.request(self.url, "POST", **kwargs)) + + def test_request_ok_without_body(self): + self.request.return_value.status_code = 200 + self.request.return_value.text = "key" + + kwargs = {"body": "key"} + + self.assertEqual(( + self.request(), None), + self.manager.request(self.url, "POST", **kwargs)) + + def test_request_fail_with_body(self): + self.request.return_value.status_code = 400 + self.request.return_value.text = '{"key": "value"}' + + kwargs = {"body": {"key": "value"}} + + self.assertRaises(exception.ClimateClientException, + self.manager.request, + self.url, "POST", **kwargs) + + def test_request_fail_without_body(self): + self.request.return_value.status_code = 400 + self.request.return_value.text = "REAL_ERROR" + + kwargs = {"body": "key"} + + self.assertRaises(exception.ClimateClientException, + self.manager.request, + self.url, "POST", **kwargs) diff --git a/climateclient/tests/test_client.py b/climateclient/tests/test_client.py new file mode 100644 index 0000000..781b906 --- /dev/null +++ b/climateclient/tests/test_client.py @@ -0,0 +1,44 @@ +# Copyright (c) 2014 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from climateclient import client +from climateclient import exception +from climateclient.openstack.common import importutils +from climateclient import tests + + +class BaseClientTestCase(tests.TestCase): + + def setUp(self): + super(BaseClientTestCase, self).setUp() + + self.client = client + + self.import_obj = self.patch(importutils, "import_object") + + def test_with_v1(self): + self.client.Client() + self.import_obj.assert_called_once_with( + 'climateclient.v1.client.Client') + + def test_with_v1a0(self): + self.client.Client(version='1a0') + self.import_obj.assert_called_once_with( + 'climateclient.v1.client.Client') + + def test_with_wrong_vers(self): + self.assertRaises(exception.UnsupportedVersion, + self.client.Client, + version='0.0') diff --git a/climateclient/tests/test_command.py b/climateclient/tests/test_command.py new file mode 100644 index 0000000..9d91496 --- /dev/null +++ b/climateclient/tests/test_command.py @@ -0,0 +1,136 @@ +# Copyright (c) 2014 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock +import testtools + +from climateclient import command +from climateclient import tests + + +class OpenstackCommandTestCase(tests.TestCase): + + def setUp(self): + super(OpenstackCommandTestCase, self).setUp() + + @testtools.skip("Have no idea how to test super") + def test_run(self): + pass + + @testtools.skip("Unskip it when get_data will do smthg") + def test_get_data(self): + pass + + @testtools.skip("Unskip it when get_data will do smthg") + def test_take_action(self): + pass + + +class TableFormatterTestCase(tests.TestCase): + + def setUp(self): + super(TableFormatterTestCase, self).setUp() + + @testtools.skip("Have no idea how to test super") + def test_emit_list(self): + pass + + +class ClimateCommandTestCase(tests.TestCase): + + def setUp(self): + super(ClimateCommandTestCase, self).setUp() + + self.app = mock.MagicMock() + self.parser = self.patch(command.OpenStackCommand, 'get_parser') + + self.command = command.ClimateCommand(self.app, []) + + def test_get_client(self): + client = self.command.get_client() + self.assertEqual(self.app.client, client) + + def test_get_parser(self): + self.command.get_parser('TestCase') + self.parser.assert_called_once_with('TestCase') + + def test_format_output_data(self): + data_before = {'key_string': 'string_value', + 'key_dict': "{'key0': 'value', 'key1': 'value'}", + 'key_list': "['1', '2', '3',]", + 'key_none': None} + data_after = {'key_string': 'string_value', + 'key_dict': "{'key0': 'value', 'key1': 'value'}", + 'key_list': "['1', '2', '3',]", + 'key_none': ''} + + self.command.format_output_data(data_before) + + self.assertEqual(data_after, data_before) + + +class CreateCommandTestCase(tests.TestCase): + def setUp(self): + super(CreateCommandTestCase, self).setUp() + + self.app = mock.MagicMock() + self.create_command = command.CreateCommand(self.app, []) + + self.client = self.patch(self.create_command, 'get_client') + + @testtools.skip("Under construction") + def test_get_data_data(self): + data = {'key_string': 'string_value', + 'key_dict': "{'key0': 'value', 'key1': 'value'}", + 'key_list': "['1', '2', '3',]", + 'key_none': None} + self.client.resource.return_value = mock.MagicMock(return_value=data) + self.assertEqual(self.create_command.get_data({'a': 'b'}), None) + + +@testtools.skip("Under construction") +class UpdateCommandTestCase(tests.TestCase): + def setUp(self): + super(UpdateCommandTestCase, self).setUp() + + self.app = mock.MagicMock() + self.update_command = command.UpdateCommand(self.app, []) + + +@testtools.skip("Under construction") +class DeleteCommandTestCase(tests.TestCase): + def setUp(self): + super(DeleteCommandTestCase, self).setUp() + + self.app = mock.MagicMock() + self.delete_command = command.DeleteCommand(self.app, []) + + +@testtools.skip("Under construction") +class ListCommandTestCase(tests.TestCase): + def setUp(self): + super(ListCommandTestCase, self).setUp() + + self.app = mock.MagicMock() + self.list_command = command.ListCommand(self.app, []) + + +@testtools.skip("Under construction") +class ShowCommandTestCase(tests.TestCase): + def setUp(self): + super(ShowCommandTestCase, self).setUp() + + self.app = mock.MagicMock() + self.show_command = command.ShowCommand(self.app, []) diff --git a/climateclient/tests/test_shell.py b/climateclient/tests/test_shell.py new file mode 100644 index 0000000..30bdd3f --- /dev/null +++ b/climateclient/tests/test_shell.py @@ -0,0 +1,94 @@ +# Copyright (c) 2014 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +import six +import sys + +import fixtures +#note(n.s.): you may need it later +#import mock +import testtools + +#note(n.s.): you may need it later +#from climateclient import client as climate_client +#from climateclient import exception +from climateclient import shell +from climateclient import tests + +FAKE_ENV = {'OS_USERNAME': 'username', + 'OS_PASSWORD': 'password', + 'OS_TENANT_NAME': 'tenant_name', + 'OS_AUTH_URL': 'http://no.where'} + + +class ClimateShellTestCase(tests.TestCase): + + def make_env(self, exclude=None, fake_env=FAKE_ENV): + env = dict((k, v) for k, v in fake_env.items() if k != exclude) + self.useFixture(fixtures.MonkeyPatch('os.environ', env)) + + def setUp(self): + super(ClimateShellTestCase, self).setUp() + + #Create shell for non-specific tests + self.climate_shell = shell.ClimateShell() + + def shell(self, argstr, exitcodes=(0,)): + orig = sys.stdout + orig_stderr = sys.stderr + try: + sys.stdout = six.StringIO() + sys.stderr = six.StringIO() + _shell = shell.ClimateShell() + _shell.initialize_app(argstr.split()) + except SystemExit: + exc_type, exc_value, exc_traceback = sys.exc_info() + self.assertIn(exc_value.code, exitcodes) + finally: + stdout = sys.stdout.getvalue() + sys.stdout.close() + sys.stdout = orig + stderr = sys.stderr.getvalue() + sys.stderr.close() + sys.stderr = orig_stderr + return (stdout, stderr) + + def test_help_unknown_command(self): + self.assertRaises(ValueError, self.shell, 'bash-completion') + + @testtools.skip('lol') + def test_bash_completion(self): + stdout, stderr = self.shell('bash-completion') + # just check we have some output + required = [ + '.*--matching', + '.*--wrap', + '.*help', + '.*secgroup-delete-rule', + '.*--priority'] + for r in required: + self.assertThat((stdout + stderr), + testtools.matchers.MatchesRegex( + r, re.DOTALL | re.MULTILINE)) + + @testtools.skip('lol') + def test_authenticate_user(self): + obj = shell.ClimateShell() + obj.initialize_app('list-leases') + obj.options.os_token = 'aaaa-bbbb-cccc' + obj.options.os_cacert = 'cert' + + obj.authenticate_user() diff --git a/climateclient/utils.py b/climateclient/utils.py index 984c728..45d7880 100644 --- a/climateclient/utils.py +++ b/climateclient/utils.py @@ -19,9 +19,9 @@ import os import re import six -from climate.openstack.common import timeutils from climateclient import exception from climateclient.openstack.common.gettextutils import _ # noqa +from climateclient.openstack.common import timeutils HEX_ELEM = '[0-9A-Fa-f]' UUID_PATTERN = '-'.join([HEX_ELEM + '{8}', HEX_ELEM + '{4}',