From 59ee90791d47352f1293cb83b4902a572961aecc Mon Sep 17 00:00:00 2001 From: Naoya Harada Date: Fri, 11 Nov 2016 21:08:12 +0900 Subject: [PATCH] Fix invalid unit test code in python-tackerclient Unit tests are not testing the behavior of command-line client code properly since mox was replaced with mock in [1]. [1] https://review.openstack.org/#/c/313165/ assert_called_once_with() should be called after the target call of the patched method. Change-Id: I99873e9cb1d75d1fa2e41c02b9f87dfa4f9ef1f7 Partial-Bug: #1572706 --- tackerclient/tests/unit/test_cli10.py | 109 ++++++++---------- tackerclient/tests/unit/test_utils.py | 38 ++++++ tackerclient/tests/unit/vm/test_cli10_vnf.py | 13 +-- .../tests/unit/vm/test_cli10_vnffg.py | 4 +- 4 files changed, 95 insertions(+), 69 deletions(-) diff --git a/tackerclient/tests/unit/test_cli10.py b/tackerclient/tests/unit/test_cli10.py index e1bc512..5f3993d 100644 --- a/tackerclient/tests/unit/test_cli10.py +++ b/tackerclient/tests/unit/test_cli10.py @@ -29,6 +29,7 @@ from tackerclient.common import exceptions from tackerclient import shell from tackerclient.tacker import v1_0 as tackerV1_0 from tackerclient.tacker.v1_0 import TackerCommand +from tackerclient.tests.unit import test_utils from tackerclient.v1_0 import client API_VERSION = "1.0" @@ -114,6 +115,12 @@ class MyUrlComparator(object): def __repr__(self): return str(self) + def __eq__(self, rhs): + return self.equals(rhs) + + def __ne__(self, rhs): + return not self.__eq__(rhs) + class MyComparator(object): def __init__(self, lhs, client): @@ -243,17 +250,13 @@ class CLITestV10Base(testtools.TestCase): _body = self.client.serialize(body) with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (MyResp(200), resstr) - self.client.httpclient.request( - end_url(path, format=self.format), 'POST', - body=_body, - headers={'X-Auth-Token', TOKEN}) - mock_req.assert_called_once_with( - end_url(path, format=self.format), 'POST', - body=_body, - headers={'X-Auth-Token', TOKEN}) args.extend(['--request-format', self.format]) cmd_parser = cmd.get_parser('create_' + resource) shell.run_command(cmd, cmd_parser, args) + mock_req.assert_called_once_with( + end_url(path, format=self.format), 'POST', + body=_body, + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) self.assertEqual(get_client_called_count, mock_get.call_count) _str = self.fake_stdout.make_string() self.assertIn(myid, _str) @@ -271,17 +274,13 @@ class CLITestV10Base(testtools.TestCase): path = getattr(self.client, resources_collection + "_path") with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (MyResp(200), resstr) - self.client.httpclient.request( - end_url(path, format=self.format), 'GET', - body=None, - headers={'X-Auth-Token': TOKEN}) - mock_req.assert_called_once_with( - end_url(path, format=self.format), 'GET', - body=None, - headers={'X-Auth-Token': TOKEN}) args.extend(['--request-format', self.format]) cmd_parser = cmd.get_parser("list_" + resources_collection) shell.run_command(cmd, cmd_parser, args) + mock_req.assert_called_once_with( + end_url(path, format=self.format), 'GET', + body=None, + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) mock_get.assert_called_once_with() def _test_list_resources(self, resources, cmd, detail=False, tags=[], @@ -362,16 +361,16 @@ class CLITestV10Base(testtools.TestCase): path = getattr(self.client, resources + "_path") with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (MyResp(200), resstr) - self.client.httpclient.request( - MyUrlComparator(end_url(path, query, format=self.format), - self.client), - 'GET', - body=None, - headers={'X-Auth-Token': TOKEN}) with mock.patch.object(TackerCommand, 'get_client') as mock_get: mock_get.return_value = self.client cmd_parser = cmd.get_parser("list_" + resources) shell.run_command(cmd, cmd_parser, args) + mock_req.assert_called_once_with( + MyUrlComparator(end_url(path, query, format=self.format), + self.client), + 'GET', + body=None, + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) _str = self.fake_stdout.make_string() if response_contents is None: self.assertIn('myid1', _str) @@ -459,18 +458,16 @@ class CLITestV10Base(testtools.TestCase): path = getattr(self.client, resources + "_path") with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (MyResp(200), resstr) - self.client.httpclient.request( - end_url(path, format=self.format), 'GET', - body=None, - headers={'X-Auth-Token': TOKEN}) - mock_req.assert_called_once_with( - end_url(path, format=self.format), 'GET', - body=None, - headers={'X-Auth-Token': TOKEN}) + comparator = MyUrlComparator( + end_url(path % myid, query=query, format=self.format), + self.client) args.extend(['--request-format', self.format]) cmd_parser = cmd.get_parser("list_" + resources) shell.run_command(cmd, cmd_parser, args) - + mock_req.assert_called_once_with( + comparator, 'GET', + body=None, + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) _str = self.fake_stdout.make_string() if response_contents is None: self.assertIn('myid1', _str) @@ -562,17 +559,14 @@ class CLITestV10Base(testtools.TestCase): comparator = MyUrlComparator( end_url(path % myid, format=self.format), self.client) mock_req.return_value = (MyResp(204), None) - self.client.httpclient.request( - comparator, 'PUT', body=_body, - headers={'X-Auth-Token', TOKEN}) + args.extend(['--request-format', self.format]) + cmd_parser = cmd.get_parser("update_" + resource) + shell.run_command(cmd, cmd_parser, args) mock_req.assert_called_once_with( comparator, 'PUT', body=_body, - headers={'X-Auth-Token', TOKEN}) - args.extend(['--request-format', self.format]) - cmd_parser = cmd.get_parser("update_" + resource) - shell.run_command(cmd, cmd_parser, args) + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) self.assertEqual(get_client_called_count, mock_get.call_count) _str = self.fake_stdout.make_string() self.assertIn(myid, _str) @@ -590,15 +584,13 @@ class CLITestV10Base(testtools.TestCase): with mock.patch.object(self.client.httpclient, 'request') as\ mock_req: mock_req.return_value = (MyResp(200), resstr) - self.client.httpclient.request( - end_url(path % myid, query, format=self.format), 'GET', - body=None, headers={'X-Auth-Token': TOKEN}) - mock_req.assert_called_once_with( - end_url(path % myid, query, format=self.format), 'GET', - body=None, headers={'X-Auth-Token': TOKEN}) args.extend(['--request-format', self.format]) cmd_parser = cmd.get_parser("show_" + resource) shell.run_command(cmd, cmd_parser, args) + mock_req.assert_called_once_with( + end_url(path % myid, query, format=self.format), 'GET', + body=None, + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) _str = self.fake_stdout.make_string() mock_get.assert_called_once_with() self.assertIn(myid, _str) @@ -611,16 +603,13 @@ class CLITestV10Base(testtools.TestCase): path = getattr(self.client, resource + "_path") with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (MyResp(204), None) - self.client.httpclient.request( - end_url(path % myid, format=self.format), 'DELETE', - body=None, - headers={'X-Auth-Token', TOKEN}) args.extend(['--request-format', self.format]) - mock_req.assert_called_once_with( - end_url(path % myid, format=self.format), 'DELETE', - body=None, headers={'X-Auth-Token', TOKEN}) cmd_parser = cmd.get_parser("delete_" + resource) shell.run_command(cmd, cmd_parser, args) + mock_req.assert_called_once_with( + end_url(path % myid, format=self.format), 'DELETE', + body=None, + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) mock_get.assert_called_once_with() _str = self.fake_stdout.make_string() msg = 'All %(resource)s(s) %(msg)s successfully\n' % { @@ -636,13 +625,13 @@ class CLITestV10Base(testtools.TestCase): path_action = '%s/%s' % (myid, action) with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (MyResp(204), retval) - self.client.httpclient.request( - end_url(path % path_action, format=self.format), 'PUT', - body=MyComparator(body, self.client), - headers={'X-Auth-Token': TOKEN}) args.extend(['--request-format', self.format]) cmd_parser = cmd.get_parser("delete_" + resource) shell.run_command(cmd, cmd_parser, args) + mock_req.assert_called_once_with( + end_url(path % path_action, format=self.format), 'PUT', + body=MyComparator(body, self.client), + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) _str = self.fake_stdout.make_string() self.assertIn(myid, _str) @@ -666,12 +655,14 @@ class ClientV1TestJson(CLITestV10Base): expected_auth_token = unicode_text.encode('utf-8') with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (MyResp(200), expect_body) - self.client.httpclient.request( - end_url(expected_action, query=expect_query, - format=self.format), 'PUT', body=expect_body, - headers={'X-Auth-Token': expected_auth_token}) res_body = self.client.do_request('PUT', action, body=body, params=params) + mock_req.assert_called_once_with( + end_url(expected_action, query=expect_query, + format=self.format), + 'PUT', body=expect_body, + headers=test_utils.ContainsKeyValue('X-Auth-Token', + expected_auth_token)) # test response with unicode self.assertEqual(res_body, body) diff --git a/tackerclient/tests/unit/test_utils.py b/tackerclient/tests/unit/test_utils.py index ae5a63f..ef5a1da 100644 --- a/tackerclient/tests/unit/test_utils.py +++ b/tackerclient/tests/unit/test_utils.py @@ -109,3 +109,41 @@ class ImportClassTestCase(testtools.TestCase): self.assertRaises( exceptions.UnsupportedVersion, utils.get_client_class, 'image', '2', {'image': '2'}) + + +class ContainsKeyValue(object): + """Checks whether a key/value pair is in a dict parameter. + + The ContainsKeyValue class is a helper for mock.assert_*() + method. It enables strict check than the built in mock.ANY + helper, and is the equivalent of the mox.ContainsKeyValue() + function from the legacy mox library + + Example usage could be: + + mock_some_method.assert_called_once_with( + "hello", + ContainsKeyValue('foo', bar), + mock.ANY, + "world", + ContainsKeyValue('hello', world)) + """ + def __init__(self, wantkey, wantvalue): + self.wantkey = wantkey + self.wantvalue = wantvalue + + def __eq__(self, other): + try: + return other[self.wantkey] == self.wantvalue + except (KeyError, TypeError): + return False + + def __ne__(self, other): + try: + return other[self.wantkey] != self.wantvalue + except (KeyError, TypeError): + return True + + def __repr__(self): + return "" diff --git a/tackerclient/tests/unit/vm/test_cli10_vnf.py b/tackerclient/tests/unit/vm/test_cli10_vnf.py index f886c8c..eedad92 100644 --- a/tackerclient/tests/unit/vm/test_cli10_vnf.py +++ b/tackerclient/tests/unit/vm/test_cli10_vnf.py @@ -22,6 +22,7 @@ from tackerclient.tacker import v1_0 as tackerV1_0 from tackerclient.tacker.v1_0 import TackerCommand from tackerclient.tacker.v1_0.vnfm import vnf from tackerclient.tests.unit import test_cli10 +from tackerclient.tests.unit import test_utils API_VERSION = "1.0" FORMAT = 'json' @@ -78,18 +79,14 @@ class CLITestV10VmVNFJSON(test_cli10.CLITestV10Base): _body = self.client.serialize(body) with mock.patch.object(self.client.httpclient, 'request') as mock_req: mock_req.return_value = (test_cli10.MyResp(200), resstr) - self.client.httpclient.request( - test_cli10.end_url(path, format=self.format), 'POST', - body=_body, - headers={'X-Auth-Token', TOKEN}) - mock_req.assert_called_once_with( - test_cli10.end_url(path, format=self.format), 'POST', - body=_body, - headers={'X-Auth-Token', TOKEN}) args.extend(['--request-format', self.format]) args.extend(['--vnfd-id', 'vnfd']) cmd_parser = cmd.get_parser('create_' + resource) shell.run_command(cmd, cmd_parser, args) + mock_req.assert_called_once_with( + test_cli10.end_url(path, format=self.format), 'POST', + body=_body, + headers=test_utils.ContainsKeyValue('X-Auth-Token', TOKEN)) mock_get.assert_any_call() def test_create_vnf_all_params(self): diff --git a/tackerclient/tests/unit/vm/test_cli10_vnffg.py b/tackerclient/tests/unit/vm/test_cli10_vnffg.py index 075e515..cb2fb70 100644 --- a/tackerclient/tests/unit/vm/test_cli10_vnffg.py +++ b/tackerclient/tests/unit/vm/test_cli10_vnffg.py @@ -47,7 +47,7 @@ class CLITestV10VmVNFFGJSON(test_cli10.CLITestV10Base): '--symmetrical', 'True'] position_names = ['vnffgd_id', 'vnf_mapping', 'symmetrical'] position_values = [vnffgd_id, {"VNFD1": "VNF1"}, 'True'] - extra_body = {'name': vnffg_name} + extra_body = {'name': vnffg_name, 'attributes': {}} self._test_create_resource(self._RESOURCE, cmd, None, my_id, args, position_names, position_values, extra_body=extra_body, @@ -64,7 +64,7 @@ class CLITestV10VmVNFFGJSON(test_cli10.CLITestV10Base): ] position_names = ['vnffgd_id'] position_values = [vnffgd_id] - extra_body = {'name': vnffg_name} + extra_body = {'name': vnffg_name, 'attributes': {}} self._test_create_resource(self._RESOURCE, cmd, vnffg_name, my_id, args, position_names, position_values, extra_body=extra_body,