Skip to content

Commit

Permalink
Fix a bug in when setting nested config as last item
Browse files Browse the repository at this point in the history
  • Loading branch information
Nitin Gupta authored and jamesls committed Mar 9, 2015
1 parent 435918f commit 93860e3
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 22 deletions.
8 changes: 7 additions & 1 deletion awscli/customizations/configure.py
Expand Up @@ -17,8 +17,8 @@

from botocore.exceptions import ProfileNotFound

from awscli.customizations.commands import BasicCommand
from awscli.compat import raw_input
from awscli.customizations.commands import BasicCommand


logger = logging.getLogger(__name__)
Expand All @@ -31,6 +31,7 @@ def register_configure_cmd(cli):


class ConfigValue(object):

def __init__(self, value, config_type, config_variable):
self.value = value
self.config_type = config_type
Expand All @@ -54,6 +55,7 @@ def _mask_value(current_value):


class InteractivePrompter(object):

def get_value(self, current_value, config_name, prompt_text=''):
if config_name in ('aws_access_key_id', 'aws_secret_access_key'):
current_value = _mask_value(current_value)
Expand Down Expand Up @@ -218,6 +220,10 @@ def _update_subattributes(self, index, contents, values, starting_indent):
# write out all the values now.
self._insert_new_values(i - 1, contents, values, ' ')
break
else:
if starting_indent != current_indent:
# The option is the last option in the file
self._insert_new_values(i, contents, values, ' ')
return i

def _insert_new_values(self, line_number, contents, new_values, indent=''):
Expand Down
74 changes: 53 additions & 21 deletions tests/unit/customizations/test_configure.py
Expand Up @@ -10,22 +10,21 @@
# 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 sys
import os
import tempfile
import shutil
from awscli.testutils import unittest
import sys
import tempfile

import mock
from awscli.compat import six
from six import StringIO
from botocore.exceptions import ProfileNotFound

from awscli.customizations import configure

from awscli.testutils import unittest
from botocore.exceptions import ProfileNotFound
import mock
from six import StringIO


class PrecannedPrompter(object):

def __init__(self, value):
self._value = value

Expand All @@ -34,11 +33,13 @@ def get_value(self, current_value, logical_name, prompt_text=''):


class EchoPrompter(object):

def get_value(self, current_value, logical_name, prompt_text=''):
return current_value


class KeyValuePrompter(object):

def __init__(self, mapping):
self.mapping = mapping

Expand All @@ -47,6 +48,7 @@ def get_value(self, current_value, config_name, prompt_text=''):


class FakeSession(object):

def __init__(self, all_variables, profile_does_not_exist=False,
config_file_vars=None, environment_vars=None,
credentials=None):
Expand Down Expand Up @@ -93,6 +95,7 @@ def emit_first_non_none_response(self, *args, **kwargs):


class TestConfigureCommand(unittest.TestCase):

def setUp(self):
self.writer = mock.Mock()
self.global_args = mock.Mock()
Expand Down Expand Up @@ -202,6 +205,7 @@ def test_session_says_profile_does_not_exist(self):


class TestInteractivePrompter(unittest.TestCase):

def setUp(self):
self.patch = mock.patch('awscli.customizations.configure.raw_input')
self.mock_raw_input = self.patch.start()
Expand Down Expand Up @@ -268,6 +272,7 @@ def test_user_hits_enter_returns_none(self):


class TestConfigFileWriter(unittest.TestCase):

def setUp(self):
self.dirname = tempfile.mkdtemp()
self.config_filename = os.path.join(self.dirname, 'config')
Expand Down Expand Up @@ -492,7 +497,8 @@ def test_profile_with_multiple_spaces(self):
'bar = 1\n'
)
self.assert_update_config(
original, {'foo': 'newvalue', '__section__': 'profile two spaces'},
original, {
'foo': 'newvalue', '__section__': 'profile two spaces'},
'[profile "two spaces"]\n'
'foo = newvalue\n'
'bar = 1\n'
Expand All @@ -507,7 +513,7 @@ def test_nested_attributes_new_file(self):
's3 =\n'
' signature_version = s3v4\n')

def test_add_to_end_of_nested(self):
def test_add_to_nested_with_nested_in_the_middle(self):
original = (
'[default]\n'
's3 =\n'
Expand All @@ -523,6 +529,20 @@ def test_add_to_end_of_nested(self):
' signature_version = newval\n'
'ec2 = bar\n')

def test_add_to_nested_with_nested_in_the_end(self):
original = (
'[default]\n'
's3 =\n'
' other = foo\n'
)
self.assert_update_config(
original, {'__section__': 'default',
's3': {'signature_version': 'newval'}},
'[default]\n'
's3 =\n'
' other = foo\n'
' signature_version = newval\n')

def test_update_nested_attribute(self):
original = (
'[default]\n'
Expand Down Expand Up @@ -576,7 +596,8 @@ class TestConfigureListCommand(unittest.TestCase):

def test_configure_list_command_nothing_set(self):
# Test the case where the user only wants to change a single_value.
session = FakeSession(all_variables={'config_file': '/config/location'})
session = FakeSession(
all_variables={'config_file': '/config/location'})
stream = StringIO()
self.configure_list = configure.ConfigureListCommand(session, stream)
self.configure_list(args=[], parsed_globals=None)
Expand Down Expand Up @@ -738,6 +759,7 @@ def test_get_nested_attribute_from_default_does_not_exist(self):


class TestConfigureSetCommand(unittest.TestCase):

def setUp(self):
self.session = FakeSession({'config_file': 'myconfigfile'})
self.fake_credentials_filename = os.path.expanduser(
Expand All @@ -746,68 +768,77 @@ def setUp(self):
self.config_writer = mock.Mock()

def test_configure_set_command(self):
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['region', 'us-west-2'], parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'default', 'region': 'us-west-2'}, 'myconfigfile')

def test_configure_set_command_dotted(self):
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['preview.emr', 'true'], parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'preview', 'emr': 'true'}, 'myconfigfile')

def test_configure_set_with_profile(self):
self.session.profile = 'testing'
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['region', 'us-west-2'], parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'profile testing', 'region': 'us-west-2'}, 'myconfigfile')

def test_configure_set_triple_dotted(self):
# aws configure set default.s3.signature_version s3v4
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['default.s3.signature_version', 's3v4'],
parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'default', 's3': {'signature_version': 's3v4'}},
'myconfigfile')
'myconfigfile')

def test_configure_set_with_profile_nested(self):
# aws configure set default.s3.signature_version s3v4
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['profile.foo.s3.signature_version', 's3v4'],
parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'profile foo',
's3': {'signature_version': 's3v4'}}, 'myconfigfile')

def test_access_key_written_to_shared_credentials_file(self):
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['aws_access_key_id', 'foo'],
parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'default',
'aws_access_key_id': 'foo'}, self.fake_credentials_filename)

def test_secret_key_written_to_shared_credentials_file(self):
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['aws_secret_access_key', 'foo'],
parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'default',
'aws_secret_access_key': 'foo'}, self.fake_credentials_filename)

def test_session_token_written_to_shared_credentials_file(self):
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['aws_session_token', 'foo'],
parsed_globals=None)
self.config_writer.update_config.assert_called_with(
{'__section__': 'default',
'aws_session_token': 'foo'}, self.fake_credentials_filename)

def test_access_key_written_to_shared_credentials_file_profile(self):
set_command = configure.ConfigureSetCommand(self.session, self.config_writer)
set_command = configure.ConfigureSetCommand(
self.session, self.config_writer)
set_command(args=['profile.foo.aws_access_key_id', 'bar'],
parsed_globals=None)
self.config_writer.update_config.assert_called_with(
Expand All @@ -816,6 +847,7 @@ def test_access_key_written_to_shared_credentials_file_profile(self):


class TestConfigValueMasking(unittest.TestCase):

def test_config_value_is_masked(self):
config_value = configure.ConfigValue(
'fake_access_key', 'config_file', 'aws_access_key_id')
Expand Down

0 comments on commit 93860e3

Please sign in to comment.