Beispiel #1
0
 def test_generate_all_commands(self):
     aws_commands = AwsCommands()
     commands, sub_commands, global_options, resource_options, \
         ec2_states = aws_commands.generate_all_commands()
     num_commands = 0
     num_sub_commands = 0
     num_global_options = 0
     num_resource_options = 0
     num_ec2_states = 0
     with open(AwsCommands.SOURCES_PATH) as f:
         for line in f:
             line = re.sub('\n', '', line)
             if AwsCommands.COMMANDS_HEADER in line:
                 num_commands = \
                     int(line.strip(AwsCommands.COMMANDS_HEADER))
             elif AwsCommands.SUB_COMMANDS_HEADER in line:
                 num_sub_commands = \
                     int(line.strip(AwsCommands.SUB_COMMANDS_HEADER))
             elif AwsCommands.GLOBAL_OPTIONS_HEADER in line:
                 num_global_options = \
                     int(line.strip(AwsCommands.GLOBAL_OPTIONS_HEADER))
             elif AwsCommands.RESOURCE_OPTIONS_HEADER in line:
                 num_resource_options = \
                     int(line.strip(AwsCommands.RESOURCE_OPTIONS_HEADER))
             elif AwsCommands.EC2_STATES_HEADER in line:
                 num_ec2_states = \
                     int(line.strip(AwsCommands.EC2_STATES_HEADER))
     assert len(commands) == num_commands
     assert len(sub_commands) == num_sub_commands
     assert len(global_options) == num_global_options
     assert len(resource_options) == num_resource_options
     assert len(ec2_states) == num_ec2_states
Beispiel #2
0
 def test_generate_all_commands(self):
     aws_commands = AwsCommands()
     commands, sub_commands, global_options, resource_options, \
         ec2_states = aws_commands.generate_all_commands()
     num_commands = 0
     num_sub_commands = 0
     num_global_options = 0
     num_resource_options = 0
     num_ec2_states = 0
     with open(AwsCommands.SOURCES_PATH) as f:
         for line in f:
             line = re.sub('\n', '', line)
             if AwsCommands.COMMANDS_HEADER in line:
                 num_commands = \
                     int(line.strip(AwsCommands.COMMANDS_HEADER))
             elif AwsCommands.SUB_COMMANDS_HEADER in line:
                 num_sub_commands = \
                     int(line.strip(AwsCommands.SUB_COMMANDS_HEADER))
             elif AwsCommands.GLOBAL_OPTIONS_HEADER in line:
                 num_global_options = \
                     int(line.strip(AwsCommands.GLOBAL_OPTIONS_HEADER))
             elif AwsCommands.RESOURCE_OPTIONS_HEADER in line:
                 num_resource_options = \
                     int(line.strip(AwsCommands.RESOURCE_OPTIONS_HEADER))
             elif AwsCommands.EC2_STATES_HEADER in line:
                 num_ec2_states = \
                     int(line.strip(AwsCommands.EC2_STATES_HEADER))
     assert len(commands) == num_commands
     assert len(sub_commands) == num_sub_commands
     assert len(global_options) == num_global_options
     assert len(resource_options) == num_resource_options
     assert len(ec2_states) == num_ec2_states
Beispiel #3
0
 def create_completer(self):
     self.aws_commands = AwsCommands()
     self.commands, self.sub_commands, self.global_options, \
         self.resource_options, self.ec2_states = \
         self.aws_commands.generate_all_commands()
     return AwsCompleter(awscli_completer,
                         self.saws.commands,
                         self.saws.config_obj,
                         self.saws.logger,
                         self.ec2_states)
Beispiel #4
0
 def test_get_all_commands(self):
     aws_commands = AwsCommands()
     command_lists = aws_commands.get_all_commands()
     num_results_list = [None] * \
         aws_commands.CommandType.NUM_COMMAND_TYPES.value
     with open(AwsCommands.SOURCES_PATH) as f:
         for line in f:
             line = re.sub('\n', '', line)
             for command_header in aws_commands.command_headers:
                 if command_header in line:
                     command_type_value = aws_commands \
                         .header_to_type_map[command_header].value
                     num_results_list[command_type_value] = \
                         int(line.strip(command_header))
                     continue
     for index, num_results in enumerate(num_results_list):
         assert(len(command_lists[index]) == num_results)
Beispiel #5
0
 def create_completer(self):
     self.aws_commands = AwsCommands()
     self.commands, self.sub_commands, self.global_options, \
         self.resource_options, self.ec2_states = \
         self.aws_commands.generate_all_commands()
     return AwsCompleter(awscli_completer,
                         self.saws.config_obj,
                         self.saws.logger,
                         self.ec2_states)
Beispiel #6
0
 def create_completer(self):
     # TODO: Fix duplicate creation of AwsCompleter, which is already
     # created by Saws init
     self.aws_commands = AwsCommands()
     self.all_commands = self.aws_commands.all_commands
     self.commands, self.sub_commands, self.global_options, \
         self.resource_options = self.all_commands
     return AwsCompleter(awscli_completer, self.all_commands,
                         self.saws.config, self.saws.config_obj,
                         self.saws.logger)
Beispiel #7
0
 def create_completer(self):
     # TODO: Fix duplicate creation of AwsCompleter, which is already
     # created by Saws init
     self.aws_commands = AwsCommands()
     self.all_commands = self.aws_commands.get_all_commands()
     self.commands, self.sub_commands, self.global_options, \
         self.resource_options, self.ec2_states = \
         self.all_commands
     return AwsCompleter(awscli_completer,
                         self.all_commands,
                         self.saws.config_obj,
                         self.saws.logger)
Beispiel #8
0
 def test_all_commands(self):
     aws_commands = AwsCommands()
     command_lists = aws_commands.all_commands
     num_results_list = [None] * \
         aws_commands.CommandType.NUM_TYPES.value
     with open(AwsCommands.DATA_PATH) as f:
         for line in f:
             line = re.sub('\n', '', line)
             for command_header in aws_commands.headers:
                 if command_header in line:
                     command_type_value = aws_commands \
                         .header_to_type_map[command_header].value
                     num_results_list[command_type_value] = \
                         int(line.strip(command_header))
                     continue
     for index, num_results in enumerate(num_results_list):
         assert (len(command_lists[index]) == num_results)
Beispiel #9
0
class CompleterTest(unittest.TestCase):

    @mock.patch('saws.resources.print')
    def setUp(self, mock_print):
        self.saws = Saws()
        self.completer = self.create_completer()
        self.completer.refresh_resources_and_options()
        self.completer_event = self.create_completer_event()
        mock_print.assert_called_with('Loaded resources from cache')

    def create_completer(self):
        # TODO: Fix duplicate creation of AwsCompleter, which is already
        # created by Saws init
        self.aws_commands = AwsCommands()
        self.all_commands = self.aws_commands.get_all_commands()
        self.commands, self.sub_commands, self.global_options, \
            self.resource_options, self.ec2_states = \
            self.all_commands
        return AwsCompleter(awscli_completer,
                            self.all_commands,
                            self.saws.config_obj,
                            self.saws.logger)

    def create_completer_event(self):
        return mock.Mock()

    def _get_completions(self, command):
        position = len(command)
        result = set(self.completer.get_completions(
            Document(text=command, cursor_position=position),
            self.completer_event))
        return result

    def verify_completions(self, commands, expected):
        result = set()
        for command in commands:
            # Call the AWS CLI autocompleter
            result.update(self._get_completions(command))
        result_texts = []
        for item in result:
            # Each result item is a Completion object,
            # we are only interested in the text portion
            result_texts.append(item.text)
        assert result_texts
        if len(expected) == 1:
            assert expected[0] in result_texts
        else:
            for item in expected:
                assert item in result_texts

    def test_no_completions(self):
        command = 'aws ec2'
        expected = set([])
        assert expected == self._get_completions(command)
        command = 'aws elb'
        assert expected == self._get_completions(command)
        command = 'aws elasticache'
        assert expected == self._get_completions(command)

    def test_ec2_commands(self):
        commands = ['aws e']
        expected = ['ec2',
                    'ecs',
                    'efs',
                    'elasticache',
                    'elasticbeanstalk',
                    'elastictranscoder',
                    'elb',
                    'emr']
        self.verify_completions(commands, expected)

    def test_ec2_subcommands(self):
        commands = ['aws ec2 c']
        expected = ['cancel-bundle-task',
                    'cancel-conversion-task',
                    'cancel-export-task',
                    'cancel-import-task',
                    'cancel-reserved-instances-listing',
                    'cancel-spot-fleet-requests',
                    'cancel-spot-instance-requests']
        self.verify_completions(commands, expected)

    def test_aws_command(self):
        commands = ['a', 'aw']
        expected = [AwsCommands.AWS_COMMAND]
        self.verify_completions(commands, expected)

    def test_global_options(self):
        commands = ['aws -', 'aws --']
        expected = self.saws \
            .all_commands[AwsCommands.CommandType.GLOBAL_OPTIONS.value]
        self.verify_completions(commands, expected)

    def test_resource_options(self):
        commands = ['aws ec2 describe-instances --',
                    'aws s3api get-bucket-acl --']
        expected = self.saws \
            .all_commands[AwsCommands.CommandType.RESOURCE_OPTIONS.value]
        self.verify_completions(commands, expected)

    def test_shortcuts(self):
        commands = ['aws ec2 ls',
                    'aws emr ls',
                    'aws elb ls',
                    'aws dynamodb ls']
        expected = ['aws ec2 describe-instances',
                    'aws emr list-clusters',
                    'aws elb describe-load-balancers',
                    'aws dynamodb list-tables']
        shortcuts = dict(zip(commands, expected))
        for command, expect in shortcuts.items():
            result = self.completer.replace_shortcut(command)
            assert result == expect

    def test_shortcuts_fuzzy(self):
        self.completer.fuzzy_match = True
        self.completer.shortcut_match = True
        commands = ['aws ec2ls']
        expected = ['ec2 ls --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2start']
        expected = ['ec2 start-instances --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2stop']
        expected = ['ec2 stop-instances --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2tagk']
        expected = ['ec2 ls --ec2-tag-key']
        self.verify_completions(commands, expected)
        commands = ['aws ec2tagv']
        expected = ['ec2 ls --ec2-tag-value']
        self.verify_completions(commands, expected)

    def test_substitutions(self):
        command = 'aws ec2 ls --filters "Name=tag-key,Values=%s prod"'
        expected = 'aws ec2 ls --filters "Name=tag-key,Values=prod"'
        result = self.completer.replace_substitution(command)
        assert result == expected
        command = 'aws ec2 ls --ec2-tag-key Stack'
        expected = 'aws ec2 describe-instances --filters "Name=tag-key,Values=Stack"'
        result = self.completer.replace_shortcut(command)
        assert result == expected
        command = 'aws ec2 ls --ec2-tag-value prod'
        expected = 'aws ec2 describe-instances --filters "Name=tag-value,Values=prod"'
        result = self.completer.replace_shortcut(command)
        assert result == expected

    @mock.patch('saws.resources.print')
    def test_refresh_resources_and_options(self, mock_print):
        self.completer.resources.RESOURCE_FILE = \
            ResourcesTest.RESOURCES_SAMPLE
        self.completer.resources.resources_map = None
        self.completer.refresh_resources_and_options(force_refresh=False)
        mock_print.assert_called_with('Loaded resources from cache')
        keys = [self.completer.resources.INSTANCE_IDS_OPT,
                self.completer.resources.EC2_TAG_KEY_OPT,
                self.completer.resources.EC2_TAG_VALUE_OPT,
                self.completer.resources.BUCKET_OPT,
                self.completer.resources.S3_URI_OPT]
        expected = [ResourcesTest.NUM_SAMPLE_INSTANCE_IDS,
                    ResourcesTest.NUM_SAMPLE_INSTANCE_TAG_KEYS,
                    ResourcesTest.NUM_SAMPLE_INSTANCE_TAG_VALUES,
                    ResourcesTest.NUM_SAMPLE_BUCKET_NAMES,
                    ResourcesTest.NUM_SAMPLE_BUCKET_NAMES]
        for i in range(len(keys)):
            assert len(
                self.completer.resources.resources_map[keys[i]]) == expected[i]
        # TODO: Add tests for options_map

    def test_instance_ids(self):
        commands = ['aws ec2 ls --instance-ids i-a']
        expected = ['i-a875ecc3', 'i-a51d05f4', 'i-a3628153']
        self.completer.resources.instance_ids.extend(expected)
        self.verify_completions(commands, expected)

    def test_instance_ids_fuzzy(self):
        self.completer.fuzzy_match = True
        commands = ['aws ec2 ls --instance-ids a5']
        expected = ['i-a875ecc3', 'i-a41d55f4', 'i-a3628153']
        self.completer.resources.instance_ids.extend(expected)
        self.verify_completions(commands, expected)

    def test_instance_keys(self):
        commands = ['aws ec2 ls --ec2-tag-key na']
        expected = ['name', 'namE']
        self.completer.resources.instance_tag_keys.update(expected)
        self.verify_completions(commands, expected)

    def test_instance_tag_values(self):
        commands = ['aws ec2 ls --ec2-tag-value prod']
        expected = ['production', 'production-blue', 'production-green']
        self.completer.resources.instance_tag_values.update(expected)
        self.verify_completions(commands, expected)

    def test_bucket_names(self):
        commands = ['aws s3pi get-bucket-acl --bucket web-']
        expected = ['web-server-logs', 'web-server-images']
        self.completer.resources.bucket_names.extend(expected)
        self.verify_completions(commands, expected)

    def test_s3_uri(self):
        commands = ['aws s3 ls s3:']
        expected = ['s3://web-server-logs', 's3://web-server-images']
        for s3_uri in expected:
            bucket_name = re.sub('s3://', '', s3_uri)
            self.completer.resources.add_bucket_name(bucket_name)
        self.verify_completions(commands, expected)
        commands = ['aws s3 ls s3://web']
        self.verify_completions(commands, expected)

    def test_ec2_states(self):
        commands = ['aws ec2 ls --ec2-state pend']
        expected = ['pending']
        self.verify_completions(commands, expected)
        commands = ['aws ec2 ls --ec2-state run']
        expected = ['running']
        self.verify_completions(commands, expected)
        commands = ['aws ec2 ls --ec2-state shut']
        expected = ['shutting-down']
        self.verify_completions(commands, expected)
        commands = ['aws ec2 ls --ec2-state term']
        expected = ['terminated']
        self.verify_completions(commands, expected)
        commands = ['aws ec2 ls --ec2-state stop']
        expected = ['stopping',
                    'stopped']
        self.verify_completions(commands, expected)

    def test_cluster_states(self):
        self.verify_cluster_states()

    def test_cluster_states_fuzzy(self):
        self.completer.fuzzy_match = True
        self.verify_cluster_states()

    def verify_cluster_states(self):
        commands = ['aws emr ls --cluster-states star']
        expected = ['STARTING']
        self.verify_completions(commands, expected)
        commands = ['emr ls --cluster-states BOOT']
        expected = ['BOOTSTRAPPING']
        self.verify_completions(commands, expected)
        commands = ['emr ls --cluster-states run']
        expected = ['RUNNING']
        self.verify_completions(commands, expected)
        commands = ['emr ls --cluster-states WAIT']
        expected = ['WAITING']
        self.verify_completions(commands, expected)
        commands = ['emr ls --cluster-states term']
        expected = ['TERMINATING',
                    'TERMINATED',
                    'TERMINATED_WITH_ERRORS']
        self.verify_completions(commands, expected)
Beispiel #10
0
class CompleterTest(unittest.TestCase):

    @mock.patch('saws.resources.print')
    def setUp(self, mock_print):
        self.saws = Saws()
        self.completer = self.create_completer()
        self.completer_event = self.create_completer_event()
        mock_print.assert_called_with('Loaded resources from cache')

    def create_completer(self):
        self.aws_commands = AwsCommands()
        self.commands, self.sub_commands, self.global_options, \
            self.resource_options, self.ec2_states = \
            self.aws_commands.generate_all_commands()
        return AwsCompleter(awscli_completer,
                            self.saws.config_obj,
                            self.saws.logger,
                            self.ec2_states)

    def create_completer_event(self):
        return mock.Mock()

    def _get_completions(self, command):
        position = len(command)
        result = set(self.completer.get_completions(
            Document(text=command, cursor_position=position),
            self.completer_event))
        return result

    def verify_completions(self, commands, expected):
        result = set()
        for command in commands:
            # Call the AWS CLI autocompleter
            result.update(self._get_completions(command))
        result_texts = []
        for item in result:
            # Each result item is a Completion object,
            # we are only interested in the text portion
            result_texts.append(item.text)
        assert result_texts
        if len(expected) == 1:
            assert expected[0] in result_texts
        else:
            for item in expected:
                assert item in result_texts

    def test_ec2_state_completions(self):
        commands = ['ec2 ls --ec2-state pend']
        expected = ['pending']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state run']
        expected = ['running']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state shut']
        expected = ['shutting-down']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state term']
        expected = ['terminated']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state stop']
        expected = ['stopping',
                    'stopped']
        self.verify_completions(commands, expected)

    def test_aws_command_completion(self):
        commands = ['a', 'aw']
        expected = [AwsCommands.AWS_COMMAND]
        self.verify_completions(commands, expected)

    def test_global_options(self):
        commands = ['aws -', 'aws --']
        expected = self.saws.global_options
        self.verify_completions(commands, expected)

    def test_resource_options(self):
        commands = ['aws ec2 describe-instances --',
                    'aws s3api get-bucket-acl --']
        expected = self.saws.resource_options
        self.verify_completions(commands, expected)

    def test_simple_shortcuts(self):
        commands = ['aws ec2 ls',
                    'aws emr ls',
                    'aws elb ls',
                    'aws dynamodb ls']
        expected = ['aws ec2 describe-instances',
                    'aws emr list-clusters',
                    'aws elb describe-load-balancers',
                    'aws dynamodb list-tables']
        shortcuts = dict(zip(commands, expected))
        for command, expect in shortcuts.items():
            result = self.completer.replace_shortcut(command)
            assert result == expect

    def test_instance_ids(self):
        commands = ['aws ec2 ls --instance-ids i-a']
        expected = ['i-a875ecc3', 'i-a51d05f4', 'i-a3628153']
        self.completer.resources.instance_ids.extend(expected)
        self.verify_completions(commands, expected)

    def test_instance_keys(self):
        commands = ['aws ec2 ls --ec2-tag-key na']
        expected = ['name', 'namE']
        self.completer.resources.instance_tag_keys.update(expected)
        self.verify_completions(commands, expected)

    def test_instance_tag_values(self):
        commands = ['aws ec2 ls --ec2-tag-value prod']
        expected = ['production', 'production-blue', 'production-green']
        self.completer.resources.instance_tag_values.update(expected)
        self.verify_completions(commands, expected)

    def test_bucket_names(self):
        commands = ['aws s3pi get-bucket-acl --bucket web-']
        expected = ['web-server-logs', 'web-server-images']
        self.completer.resources.bucket_names.extend(expected)
        self.verify_completions(commands, expected)

    def test_fuzzy_instance_ids_matching(self):
        self.completer.fuzzy_match = True
        commands = ['aws ec2 ls --instance-ids a5']
        expected = ['i-a875ecc3', 'i-a41d55f4', 'i-a3628153']
        self.completer.resources.instance_ids.extend(expected)
        self.verify_completions(commands, expected)

    def test_fuzzy_shortcut_matching(self):
        self.completer.fuzzy_match = True
        self.completer.shortcut_match = True
        commands = ['aws ec2ls']
        expected = ['ec2 ls --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2start']
        expected = ['ec2 start-instances --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2stop']
        expected = ['ec2 stop-instances --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2tagk']
        expected = ['ec2 ls --ec2-tag-key']
        self.verify_completions(commands, expected)
        commands = ['aws ec2tagv']
        expected = ['ec2 ls --ec2-tag-value']
        self.verify_completions(commands, expected)

    def test_substitutions(self):
        command = 'aws ec2 ls --filters "Name=tag-key,Values=%s prod"'
        expected = 'aws ec2 ls --filters "Name=tag-key,Values=prod"'
        result = self.completer.replace_substitution(command)
        assert result == expected
        command = 'aws ec2 ls --ec2-tag-key Stack'
        expected = 'aws ec2 describe-instances --filters "Name=tag-key,Values=Stack"'
        result = self.completer.replace_shortcut(command)
        assert result == expected
        command = 'aws ec2 ls --ec2-tag-value prod'
        expected = 'aws ec2 describe-instances --filters "Name=tag-value,Values=prod"'
        result = self.completer.replace_shortcut(command)
        assert result == expected
Beispiel #11
0
class CompleterTest(unittest.TestCase):

    @mock.patch('saws.resources.print')
    def setUp(self, mock_print):
        self.saws = Saws()
        self.completer = self.create_completer()
        self.completer_event = self.create_completer_event()
        mock_print.assert_called_with('Loaded resources from cache')

    def create_completer(self):
        self.aws_commands = AwsCommands()
        self.commands, self.sub_commands, self.global_options, \
            self.resource_options, self.ec2_states = \
            self.aws_commands.generate_all_commands()
        return AwsCompleter(awscli_completer,
                            self.saws.commands,
                            self.saws.config_obj,
                            self.saws.logger,
                            self.ec2_states)

    def create_completer_event(self):
        return mock.Mock()

    def _get_completions(self, command):
        position = len(command)
        result = set(self.completer.get_completions(
            Document(text=command, cursor_position=position),
            self.completer_event))
        return result

    def verify_completions(self, commands, expected):
        result = set()
        for command in commands:
            # Call the AWS CLI autocompleter
            result.update(self._get_completions(command))
        result_texts = []
        for item in result:
            # Each result item is a Completion object,
            # we are only interested in the text portion
            result_texts.append(item.text)
        assert result_texts
        if len(expected) == 1:
            assert expected[0] in result_texts
        else:
            for item in expected:
                assert item in result_texts

    def test_no_completions(self):
        command = 'aws ec2'
        expected = set([])
        assert expected == self._get_completions(command)
        command = 'aws elb'
        assert expected == self._get_completions(command)
        command = 'aws elasticache'
        assert expected == self._get_completions(command)

    def test_ec2_commands(self):
        commands = ['aws e']
        expected = ['ec2',
                    'ecs',
                    'efs',
                    'elasticache',
                    'elasticbeanstalk',
                    'elastictranscoder',
                    'elb',
                    'emr']
        self.verify_completions(commands, expected)

    def test_ec2_subcommands(self):
        commands = ['aws ec2 c']
        expected = ['cancel-bundle-task',
                    'cancel-conversion-task',
                    'cancel-export-task',
                    'cancel-import-task',
                    'cancel-reserved-instances-listing',
                    'cancel-spot-fleet-requests',
                    'cancel-spot-instance-requests']
        self.verify_completions(commands, expected)

    def test_ec2_state_completions(self):
        commands = ['ec2 ls --ec2-state pend']
        expected = ['pending']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state run']
        expected = ['running']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state shut']
        expected = ['shutting-down']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state term']
        expected = ['terminated']
        self.verify_completions(commands, expected)
        commands = ['ec2 ls --ec2-state stop']
        expected = ['stopping',
                    'stopped']
        self.verify_completions(commands, expected)

    def test_aws_command_completion(self):
        commands = ['a', 'aw']
        expected = [AwsCommands.AWS_COMMAND]
        self.verify_completions(commands, expected)

    def test_global_options(self):
        commands = ['aws -', 'aws --']
        expected = self.saws.global_options
        self.verify_completions(commands, expected)

    def test_resource_options(self):
        commands = ['aws ec2 describe-instances --',
                    'aws s3api get-bucket-acl --']
        expected = self.saws.resource_options
        self.verify_completions(commands, expected)

    def test_simple_shortcuts(self):
        commands = ['aws ec2 ls',
                    'aws emr ls',
                    'aws elb ls',
                    'aws dynamodb ls']
        expected = ['aws ec2 describe-instances',
                    'aws emr list-clusters',
                    'aws elb describe-load-balancers',
                    'aws dynamodb list-tables']
        shortcuts = dict(zip(commands, expected))
        for command, expect in shortcuts.items():
            result = self.completer.replace_shortcut(command)
            assert result == expect

    def test_instance_ids(self):
        commands = ['aws ec2 ls --instance-ids i-a']
        expected = ['i-a875ecc3', 'i-a51d05f4', 'i-a3628153']
        self.completer.resources.instance_ids.extend(expected)
        self.verify_completions(commands, expected)

    def test_instance_keys(self):
        commands = ['aws ec2 ls --ec2-tag-key na']
        expected = ['name', 'namE']
        self.completer.resources.instance_tag_keys.update(expected)
        self.verify_completions(commands, expected)

    def test_instance_tag_values(self):
        commands = ['aws ec2 ls --ec2-tag-value prod']
        expected = ['production', 'production-blue', 'production-green']
        self.completer.resources.instance_tag_values.update(expected)
        self.verify_completions(commands, expected)

    def test_bucket_names(self):
        commands = ['aws s3pi get-bucket-acl --bucket web-']
        expected = ['web-server-logs', 'web-server-images']
        self.completer.resources.bucket_names.extend(expected)
        self.verify_completions(commands, expected)

    def test_s3_completion(self):
        commands = ['aws s3 ls s3:']
        expected = ['s3://web-server-logs', 's3://web-server-images']
        for s3_uri in expected:
            bucket_name = re.sub('s3://', '', s3_uri)
            self.completer.resources.add_bucket_name(bucket_name)
        self.verify_completions(commands, expected)
        commands = ['aws s3 ls s3://web']
        self.verify_completions(commands, expected)

    def test_fuzzy_instance_ids_matching(self):
        self.completer.fuzzy_match = True
        commands = ['aws ec2 ls --instance-ids a5']
        expected = ['i-a875ecc3', 'i-a41d55f4', 'i-a3628153']
        self.completer.resources.instance_ids.extend(expected)
        self.verify_completions(commands, expected)

    def test_fuzzy_shortcut_matching(self):
        self.completer.fuzzy_match = True
        self.completer.shortcut_match = True
        commands = ['aws ec2ls']
        expected = ['ec2 ls --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2start']
        expected = ['ec2 start-instances --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2stop']
        expected = ['ec2 stop-instances --instance-ids']
        self.verify_completions(commands, expected)
        commands = ['aws ec2tagk']
        expected = ['ec2 ls --ec2-tag-key']
        self.verify_completions(commands, expected)
        commands = ['aws ec2tagv']
        expected = ['ec2 ls --ec2-tag-value']
        self.verify_completions(commands, expected)

    def test_substitutions(self):
        command = 'aws ec2 ls --filters "Name=tag-key,Values=%s prod"'
        expected = 'aws ec2 ls --filters "Name=tag-key,Values=prod"'
        result = self.completer.replace_substitution(command)
        assert result == expected
        command = 'aws ec2 ls --ec2-tag-key Stack'
        expected = 'aws ec2 describe-instances --filters "Name=tag-key,Values=Stack"'
        result = self.completer.replace_shortcut(command)
        assert result == expected
        command = 'aws ec2 ls --ec2-tag-value prod'
        expected = 'aws ec2 describe-instances --filters "Name=tag-value,Values=prod"'
        result = self.completer.replace_shortcut(command)
        assert result == expected

    @mock.patch('saws.resources.print')
    def test_refresh_resources(self, mock_print):
        NUM_EC2_STATE = 6
        self.completer.resources.RESOURCE_FILE = \
            ResourcesTest.RESOURCES_SAMPLE
        self.completer.resource_map = None
        self.completer.refresh_resources(force_refresh=False)
        mock_print.assert_called_with('Loaded resources from cache')
        keys = [self.completer.resources.INSTANCE_IDS,
                self.completer.resources.EC2_TAG_KEY,
                self.completer.resources.EC2_TAG_VALUE,
                self.completer.resources.EC2_STATE,
                self.completer.resources.BUCKET,
                self.completer.resources.S3_URI]
        expected = [ResourcesTest.NUM_INSTANCE_IDS,
                    ResourcesTest.NUM_INSTANCE_TAG_KEYS,
                    ResourcesTest.NUM_INSTANCE_TAG_VALUES,
                    NUM_EC2_STATE,
                    ResourcesTest.NUM_BUCKET_NAMES,
                    ResourcesTest.NUM_BUCKET_NAMES]
        for i in range(len(keys)):
            assert len(self.completer.resource_map[keys[i]]) == expected[i]