Skip to content

Commit

Permalink
Address multiple bits of feedback
Browse files Browse the repository at this point in the history
* Added changelog entry
* Renamed cases to prefixes
* Fix bug in awscli/testutils with patch_send vs send_patch
* Add functional tests for all the current cases
* Added spec to mocks in clidriver unit tests
  • Loading branch information
stealthycoin committed Jun 25, 2018
1 parent 954a01b commit c9e08e3
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"category": "Argument processing",
"type": "enhancement",
"description": "Added cli_follow_urlparam option in the config file which can be set to false to disable following of http"
}
12 changes: 6 additions & 6 deletions awscli/paramfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ def register_uri_param_handler(session, **kwargs):


class UriArgumentHandler(object):
def __init__(self, cases=None):
if cases is None:
cases = copy.deepcopy(LOCAL_PREFIX_MAP)
cases.update(REMOTE_PREFIX_MAP)
self._cases = cases
def __init__(self, prefixes=None):
if prefixes is None:
prefixes = copy.deepcopy(LOCAL_PREFIX_MAP)
prefixes.update(REMOTE_PREFIX_MAP)
self._prefixes = prefixes

def __call__(self, event_name, param, value, **kwargs):
"""Handler that supports param values from URIs."""
Expand All @@ -156,7 +156,7 @@ def _check_for_uri_param(self, param, value):
if isinstance(value, list) and len(value) == 1:
value = value[0]
try:
return get_paramfile(value, self._cases)
return get_paramfile(value, self._prefixes)
except ResourceLoadingError as e:
raise ParamError(param.cli_name, six.text_type(e))

Expand Down
2 changes: 1 addition & 1 deletion awscli/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ def tearDown(self):

def patch_send(self, status_code=200, headers={}, content=b''):
if self.send_is_patched:
self.patch_send.stop()
self.send_patch.stop()
self.send_is_patched = False
send_patch = self.send_patch.start()
send_patch.return_value = mock.Mock(status_code=status_code,
Expand Down
186 changes: 186 additions & 0 deletions tests/functional/test_paramfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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 json
import logging

from mock import patch, Mock, mock_open

from awscli.testutils import FileCreator, BaseCLIWireResponseTest
from awscli.clidriver import create_clidriver
from botocore.vendored import requests

logger = logging.getLogger(__name__)


class FakeResponse(object):
def __init__(self, *args, **kwargs):
self.status_code = 200
self.text = 'function-name'


class BaseTestCLIFollowParamURL(BaseCLIWireResponseTest):
def setUp(self):
super(BaseTestCLIFollowParamURL, self).setUp()
self.wire_response = json.dumps({}).encode('utf-8')
self.patch_send(content=self.wire_response)
self.files = FileCreator()
self.command_prefix = ['lambda', 'get-function', '--function-name']
self.start_patches()

def tearDown(self):
super(BaseTestCLIFollowParamURL, self).tearDown()
self.files.remove_all()
self.stop_patches()

def start_patches(self):
self.mock_open = mock_open(read_data='function-name')
self.open_patch = patch(
'awscli.paramfile.compat_open', self.mock_open
)
self.open_patch.start()

self.mock_get = Mock(spec=requests.get, side_effect=FakeResponse)
self.requests_patch = patch(
'awscli.paramfile.requests.get', self.mock_get
)
self.requests_patch.start()

def stop_patches(self):
self.requests_patch.stop()
self.open_patch.stop()

def run_cmd_with_arg(self, argument):
command = self.command_prefix + [argument]
self.run_cmd(command)


class TestCLIFollowParamURLDefault(BaseTestCLIFollowParamURL):
def test_does_not_prefixes_when_none_in_param(self):
self.run_cmd_with_arg('foobar')

self.assertFalse(self.mock_get.called)
self.assertFalse(self.mock_open.called)

def test_does_use_http_prefix(self):
param = 'http://foobar.com'
self.run_cmd_with_arg(param)

self.assertTrue(self.mock_get.called)
self.mock_get.assert_called_once_with(param)

def test_does_use_https_prefix(self):
param = 'https://foobar.com'
self.run_cmd_with_arg(param)

self.assertTrue(self.mock_get.called)
self.mock_get.assert_called_once_with(param)

def test_does_use_file_prefix(self):
param = 'file://foobar.txt'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.mock_open.assert_called_once_with('foobar.txt', 'r')

def test_does_use_fileb_prefix(self):
param = 'fileb://foobar.txt'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.mock_open.assert_called_once_with('foobar.txt', 'rb')


class TestCLIFollowParamURLDisabled(BaseTestCLIFollowParamURL):
def setUp(self):
super(TestCLIFollowParamURLDisabled, self).setUp()
self.environ['AWS_CONFIG_FILE'] = self.files.create_file(
'config',
'[default]\ncli_follow_urlparam = false\n')
self.driver = create_clidriver()

def test_does_not_prefixes_when_none_in_param(self):
self.run_cmd_with_arg('foobar')

self.assertFalse(self.mock_get.called)
self.assertFalse(self.mock_open.called)

def test_does_not_use_http_prefix(self):
param = 'http://foobar.com'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.assertFalse(self.mock_open.called)

def test_does_not_use_https_prefix(self):
param = 'https://foobar.com'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.assertFalse(self.mock_open.called)

def test_does_use_file_prefix(self):
param = 'file://foobar.txt'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.mock_open.assert_called_once_with('foobar.txt', 'r')

def test_does_not_disable_fileb(self):
param = 'fileb://foobar.txt'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.mock_open.assert_called_once_with('foobar.txt', 'rb')


class TestCLIFollowParamURLEnabled(BaseTestCLIFollowParamURL):
def setUp(self):
super(TestCLIFollowParamURLEnabled, self).setUp()
self.environ['AWS_CONFIG_FILE'] = self.files.create_file(
'config',
'[default]\ncli_follow_urlparam = true\n')
self.driver = create_clidriver()

def test_does_not_prefixes_when_none_in_param(self):
self.run_cmd_with_arg('foobar')

self.assertFalse(self.mock_get.called)
self.assertFalse(self.mock_open.called)

def test_does_use_http_prefix(self):
param = 'http://foobar.com'
self.run_cmd_with_arg(param)

self.assertTrue(self.mock_get.called)
self.assertFalse(self.mock_open.called)

def test_does_use_https_prefix(self):
param = 'https://foobar.com'
self.run_cmd_with_arg(param)

self.assertTrue(self.mock_get.called)
self.assertFalse(self.mock_open.called)

def test_does_use_file_prefix(self):
param = 'file://foobar.txt'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.mock_open.assert_called_once_with('foobar.txt', 'r')

def test_does_use_fileb_prefix(self):
param = 'fileb://foobar.txt'
self.run_cmd_with_arg(param)

self.assertFalse(self.mock_get.called)
self.mock_open.assert_called_once_with('foobar.txt', 'rb')
5 changes: 3 additions & 2 deletions tests/unit/test_clidriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from awscli.clidriver import CLICommand
from awscli.clidriver import ServiceCommand
from awscli.clidriver import ServiceOperation
from awslci.paramfile import UriArgumentHandler
from awscli.customizations.commands import BasicCommand
from awscli import formatter
from awscli.argparser import HELP_BLURB
Expand Down Expand Up @@ -511,7 +512,7 @@ def test_event_emission_for_top_level_params(self):
self.assertEqual(args_seen[0].unknown_arg, 'foo')

def test_custom_arg_paramfile(self):
mock_paramfile_handler = mock.MagicMock()
mock_paramfile_handler = mock.MagicMock(spec=UriArgumentHandler)
mock_paramfile_handler.return_value = None
with mock.patch('awscli.paramfile.UriArgumentHandler',
return_value=mock_paramfile_handler) as uri_param_mock:
Expand Down Expand Up @@ -539,7 +540,7 @@ def test_custom_arg_paramfile(self):
mock_paramfile_handler.call_args_list[-1][1]['value'])

def test_custom_command_paramfile(self):
mock_paramfile_handler = mock.MagicMock()
mock_paramfile_handler = mock.MagicMock(spec=UriArgumentHandler)
mock_paramfile_handler.return_value = None
with mock.patch('awscli.paramfile.UriArgumentHandler',
return_value=mock_paramfile_handler) as uri_param_mock:
Expand Down

0 comments on commit c9e08e3

Please sign in to comment.