From 4b571a9ad9a2b06ba6b28693dd32f8aac410a911 Mon Sep 17 00:00:00 2001 From: One-Fine-Day Date: Wed, 10 Jan 2018 15:18:42 -0600 Subject: [PATCH] Option 'dryrun' Added to Shipyard CLI for Commit Configdocs Shipyard API to retrieve validation status of a collection of configdocs 3 of 4 Commits (API, API Client, Documentation are in separate commits) CLI -added dryrun option to commit configdocs command in commands.py -added dryrun param for commit configdocs in actions.py -unit tests were updated in test_commit_actions.py and test_commit_commands.py Change-Id: Ieef2586335103fd09bf1e315f7366fc1622e7d92 --- shipyard_client/cli/commit/actions.py | 16 ++++++--- shipyard_client/cli/commit/commands.py | 13 +++++-- .../unit/cli/commit/test_commit_actions.py | 20 +++++++++-- .../unit/cli/commit/test_commit_commands.py | 35 +++++++++++++++++-- 4 files changed, 70 insertions(+), 14 deletions(-) diff --git a/shipyard_client/cli/commit/actions.py b/shipyard_client/cli/commit/actions.py index 169245cf..430a97d1 100644 --- a/shipyard_client/cli/commit/actions.py +++ b/shipyard_client/cli/commit/actions.py @@ -19,17 +19,19 @@ from shipyard_client.cli import format_utils class CommitConfigdocs(CliAction): """Actions to Commit Configdocs""" - def __init__(self, ctx, force): + def __init__(self, ctx, force, dryrun): """Sets parameters.""" super().__init__(ctx) self.force = force - self.logger.debug("CommitConfigdocs action initialized with force=%s", - force) + self.dryrun = dryrun + self.logger.debug("CommitConfigdocs action initialized with force=%s " + "and dryrun=%s.", force, dryrun) def invoke(self): """Calls API Client and formats response from API Client""" self.logger.debug("Calling API Client commit_configdocs.") - return self.get_api_client().commit_configdocs(force=self.force) + return self.get_api_client().commit_configdocs(force=self.force, + dryrun=self.dryrun) # Handle 400, 409 with default error handler for cli. cli_handled_err_resp_codes = [400, 409] @@ -44,7 +46,11 @@ class CommitConfigdocs(CliAction): :returns: a string representing a formatted response Handles 200 responses """ - outfmt_string = "Configuration documents committed.\n{}" + if self.dryrun: + outfmt_string = ("Configuration documents were not committed. " + "Currently in dryrun mode.\n{}") + else: + outfmt_string = "Configuration documents committed.\n{}" return outfmt_string.format( format_utils.cli_format_status_handler(response) ) diff --git a/shipyard_client/cli/commit/commands.py b/shipyard_client/cli/commit/commands.py index a8fab72c..554e841d 100644 --- a/shipyard_client/cli/commit/commands.py +++ b/shipyard_client/cli/commit/commands.py @@ -34,7 +34,7 @@ DESC_CONFIGDOCS = """ COMMAND: configdocs \n DESCRIPTION: Attempts to commit the Shipyard Buffer documents, first invoking validation by downstream components. \n -FORMAT: shipyard commit configdocs [--force] \n +FORMAT: shipyard commit configdocs [--force | --dryrun] \n EXAMPLE: shipyard commit configdocs """ @@ -49,6 +49,13 @@ SHORT_DESC_CONFIGDOCS = ("Attempts to commit the Shipyard Buffer documents, " '-f', flag_value=True, help='Force the commit to occur, even if validations fail.') +@click.option( + '--dryrun', + flag_value=True, + help='Retrieve validation status for the contents of the buffer without ' + 'committing.') @click.pass_context -def commit_configdocs(ctx, force): - click.echo(CommitConfigdocs(ctx, force).invoke_and_return_resp()) +def commit_configdocs(ctx, force, dryrun): + if (force and dryrun): + ctx.fail('Either force or dryrun may be selected but not both.') + click.echo(CommitConfigdocs(ctx, force, dryrun).invoke_and_return_resp()) diff --git a/shipyard_client/tests/unit/cli/commit/test_commit_actions.py b/shipyard_client/tests/unit/cli/commit/test_commit_actions.py index cee036f2..c11488da 100644 --- a/shipyard_client/tests/unit/cli/commit/test_commit_actions.py +++ b/shipyard_client/tests/unit/cli/commit/test_commit_actions.py @@ -29,7 +29,7 @@ def test_commit_configdocs(*args): body=None, status=200) response = CommitConfigdocs(stubs.StubCliContext(), - False).invoke_and_return_resp() + False, False).invoke_and_return_resp() assert response == 'Configuration documents committed.\n' @@ -48,7 +48,7 @@ def test_commit_configdocs_409(*args): body=api_resp, status=409) response = CommitConfigdocs(stubs.StubCliContext(), - False).invoke_and_return_resp() + False, False).invoke_and_return_resp() assert 'Error: Conflicts message' in response assert 'Configuration documents committed' not in response assert 'Reason: Conflicts reason' in response @@ -69,7 +69,21 @@ def test_commit_configdocs_forced(*args): body=api_resp, status=200) response = CommitConfigdocs(stubs.StubCliContext(), - True).invoke_and_return_resp() + True, False).invoke_and_return_resp() assert 'Status: Conflicts message forced' in response assert 'Configuration documents committed' in response assert 'Reason: Conflicts reason' in response + + +@responses.activate +@mock.patch.object(BaseClient, 'get_endpoint', lambda x: 'http://shiptest') +@mock.patch.object(BaseClient, 'get_token', lambda x: 'abc') +def test_commit_configdocs_dryrun(*args): + responses.add(responses.POST, + 'http://shiptest/commitconfigdocs?force=false', + body=None, + status=200) + response = CommitConfigdocs(stubs.StubCliContext(), + False, True).invoke_and_return_resp() + assert response == ('Configuration documents were not committed. Currently' + ' in dryrun mode.\n') diff --git a/shipyard_client/tests/unit/cli/commit/test_commit_commands.py b/shipyard_client/tests/unit/cli/commit/test_commit_commands.py index ddedc3db..1d66b3de 100644 --- a/shipyard_client/tests/unit/cli/commit/test_commit_commands.py +++ b/shipyard_client/tests/unit/cli/commit/test_commit_commands.py @@ -11,6 +11,7 @@ # 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 from click.testing import CliRunner from mock import patch, ANY @@ -26,14 +27,28 @@ auth_vars = ('--os-project-domain-name=OS_PROJECT_DOMAIN_NAME_test ' def test_commit_configdocs(*args): - """test commit_configdocs""" + """test commit configdocs command""" runner = CliRunner() with patch.object(CommitConfigdocs, '__init__') as mock_method: results = runner.invoke(shipyard, [auth_vars, 'commit', 'configdocs']) - mock_method.assert_called_once_with(ANY, False) + mock_method.assert_called_once_with(ANY, False, False) -def test_commit_configdocs_negative(): +def test_commit_configdocs_options(*args): + """test commit configdocs command with options""" + runner = CliRunner() + options = ['--force', '--dryrun'] + with patch.object(CommitConfigdocs, '__init__') as mock_method: + for opt in options: + results = runner.invoke(shipyard, [auth_vars, 'commit', + 'configdocs', opt]) + mock_method.assert_has_calls([ + mock.call(ANY, True, False), + mock.call(ANY, False, True) + ]) + + +def test_commit_configdocs_negative_invalid_arg(): """ negative unit test for commit configdocs command verifies invalid argument results in error @@ -43,3 +58,17 @@ def test_commit_configdocs_negative(): results = runner.invoke(shipyard, [auth_vars, 'commit', 'configdocs', invalid_arg]) assert 'Error' in results.output + + +def test_commit_configdocs_negative_force_dryrun(): + """ + negative unit test for commit configdocs command + verifies when force and dryrun are selected, and error occurs + """ + invalid_arg = 'invalid' + runner = CliRunner() + results = runner.invoke(shipyard, + [auth_vars, 'commit', 'configdocs', '--force', + '--dryrun']) + assert ('Error: Either force or dryrun may be selected but not both' in + results.output)