示例#1
0
    def setUp(self):
        self.output_stream = BytesIO()
        self.formatter = TextFormatter(self._COL_WIDTHS, self.output_stream)

        self.timestamp = 1511376242067
        command_time = datetime.datetime.fromtimestamp(self.timestamp / 1000)
        self.formatted_time = datetime.datetime.strftime(
            command_time, '%Y-%m-%d %I:%M:%S %p')
示例#2
0
    def setUp(self):
        self.output_stream = BytesIO()
        self.formatter = TextFormatter(self._COL_WIDTHS, self.output_stream)

        self.timestamp = 1511376242067
        command_time = datetime.datetime.fromtimestamp(self.timestamp / 1000)
        self.formatted_time = datetime.datetime.strftime(
            command_time, '%Y-%m-%d %I:%M:%S %p')
示例#3
0
 def setUp(self):
     history_recorder = self._make_clean_history_recorder()
     super(BaseHistoryCommandParamsTest, self).setUp()
     self.history_recorder = history_recorder
     self.files = FileCreator()
     config_contents = ('[default]\n' 'cli_history = enabled')
     self.environ['AWS_CONFIG_FILE'] = self.files.create_file(
         'config', config_contents)
     self.environ['AWS_CLI_HISTORY_FILE'] = self.files.create_file(
         'history.db', '')
     self.driver = create_clidriver()
     # The run_cmd patches stdout with a StringIO object (similar to what
     # nose does). Therefore it will run into issues when
     # get_binary_stdout is called because it returns sys.stdout.buffer
     # for Py3 and StringIO does not have a buffer
     self.binary_stdout_patch = mock.patch('awscli.utils.get_binary_stdout')
     mock_get_binary_stdout = self.binary_stdout_patch.start()
     self.binary_stdout = BytesIO()
     mock_get_binary_stdout.return_value = self.binary_stdout
示例#4
0
 def setUp(self):
     self.output = BytesIO()
     self.formatter = DetailedFormatter(self.output, colorize=False)
示例#5
0
class TestDetailedFormatter(unittest.TestCase):
    def setUp(self):
        self.output = BytesIO()
        self.formatter = DetailedFormatter(self.output, colorize=False)

    def get_pretty_xml(self, xml_str):
        xml_dom = xml.dom.minidom.parseString(xml_str)
        return xml_dom.toprettyxml(indent=' '*4, newl='\n')

    def assert_output(self, for_event, contains):
        self.formatter.display(for_event)
        collected_output = ensure_text_type(self.output.getvalue())
        for line in contains:
            self.assertIn(line, collected_output)

    def test_display_cli_version(self):
        self.assert_output(
            for_event={
                'event_type': 'CLI_VERSION',
                'id': 'my-id',
                'payload': 'aws-cli/1.11.188',
                'timestamp': 86400000,
                'request_id': None
            },
            contains=[
                'AWS CLI command entered',
                'with AWS CLI version: aws-cli/1.11.188'
            ]
        )

    def test_can_use_color(self):
        self.formatter = DetailedFormatter(self.output, colorize=True)
        self.assert_output(
            for_event={
                'event_type': 'CLI_VERSION',
                'id': 'my-id',
                'payload': 'aws-cli/1.11.188',
                'timestamp': 86400000,
                'request_id': None
            },
            contains=[
                '\x1b[1mAWS CLI command entered',
                '\x1b[36mwith AWS CLI version:'
            ]
        )

    def test_display_cli_arguments(self):
        self.assert_output(
            for_event={
                'event_type': 'CLI_ARGUMENTS',
                'id': 'my-id',
                'payload': ['ec2', 'describe-regions'],
                'timestamp': 86400000,
                'request_id': None
            },
            contains=[
                 "with arguments: ['ec2', 'describe-regions']"
            ]
        )

    def test_display_api_call(self):
        self.assert_output(
            for_event={
                'event_type': 'API_CALL',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'service': 'ec2',
                    'operation': 'DescribeRegions',
                    'params': {}
                },
                'timestamp': 86400000,
            },
            contains=[
                'to service: ec2\n',
                'using operation: DescribeRegions\n',
                'with parameters: {}\n'
            ]
        )

    def test_two_different_api_calls_have_different_numbers(self):
        event = {
            'event_type': 'API_CALL',
            'id': 'my-id',
            'request_id': 'some-id',
            'payload': {
                'service': 'ec2',
                'operation': 'DescribeRegions',
                'params': {}
            },
            'timestamp': 86400000,
        }
        self.formatter.display(event)
        collected_output = ensure_text_type(self.output.getvalue())
        self.assertIn('[0] API call made', collected_output)

        other_event = {
            'event_type': 'API_CALL',
            'id': 'my-id',
            'request_id': 'other-id',
            'payload': {
                'service': 'ec2',
                'operation': 'DescribeRegions',
                'params': {}
            },
            'timestamp': 86400000,
        }
        self.formatter.display(other_event)
        new_output = ensure_text_type(self.output.getvalue())[
            len(collected_output):]
        self.assertIn('[1] API call made', new_output)

    def test_display_http_request(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': 'This is my body'
                },
                'timestamp': 86400000,
            },
            contains=[
                'to URL: https://myservice.us-west-2.amazonaws.com\n',
                'with method: GET\n',
                'with headers: {}\n',
                'with body: This is my body\n'
            ]
        )

    def test_display_http_request_with_streaming_body(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': 'This should not be printed out',
                    'streaming': True
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: The body is a stream and will not be displayed',
            ]
        )

    def test_display_http_request_with_no_payload(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': None
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: There is no associated body'
            ]
        )

    def test_display_http_request_with_empty_string_payload(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': ''
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: There is no associated body'
            ]
        )

    def test_display_http_request_with_xml_payload(self):
        xml_body = '<?xml version="1.0" ?><foo><bar>text</bar></foo>'
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': xml_body
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: ' + self.get_pretty_xml(xml_body)
            ]
        )

    def test_display_http_request_with_xml_payload_and_whitespace(self):
        xml_body = '<?xml version="1.0" ?><foo><bar>text</bar></foo>'
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': self.get_pretty_xml(xml_body)
                },
                'timestamp': 86400000,
            },
            # The XML should not be prettified more than once if the body
            # of the request was already prettied.
            contains=[
                'with body: ' + self.get_pretty_xml(xml_body)
            ]
        )

    def test_display_http_request_with_json_struct_payload(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': '{"foo": "bar"}'
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: {\n'
                '    "foo": "bar"\n'
                '}'
            ]
        )

    def test_shares_api_number_across_events_of_same_api_call(self):
        self.assert_output(
            for_event={
                'event_type': 'API_CALL',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'service': 'ec2',
                    'operation': 'DescribeRegions',
                    'params': {}
                },
                'timestamp': 86400000,
            },
            contains=[
                '[0] API call made'
            ]
        )
        self.assert_output(
            for_event={
                'event_type': 'HTTP_REQUEST',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'method': 'GET',
                    'url': 'https://myservice.us-west-2.amazonaws.com',
                    'headers': {},
                    'body': 'This is my body'
                },
                'timestamp': 86400000,
            },
            contains=[
                '[0] HTTP request sent'
            ]
        )

    def test_display_http_response(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'status_code': 200,
                    'headers': {},
                    'body': 'This is my body'
                },
                'timestamp': 86400000,
            },
            contains=[
                '[0] HTTP response received',
                'with status code: 200\n',
                'with headers: {}\n',
                'with body: This is my body\n'

            ]
        )

    def test_display_http_response_with_streaming_body(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'status_code': 200,
                    'headers': {},
                    'body': 'This should not be printed out',
                    'streaming': True
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: The body is a stream and will not be displayed'
            ]
        )

    def test_display_http_response_with_no_payload(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'status_code': 200,
                    'headers': {},
                    'body': None
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: There is no associated body'
            ]
        )

    def test_display_http_response_with_empty_string_payload(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'status_code': 200,
                    'headers': {},
                    'body': ''
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: There is no associated body'
            ]
        )

    def test_display_http_response_with_xml_payload(self):
        xml_body = '<?xml version="1.0" ?><foo><bar>text</bar></foo>'
        self.assert_output(
            for_event={
                'event_type': 'HTTP_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'status_code': 200,
                    'headers': {},
                    'body': xml_body
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: ' + self.get_pretty_xml(xml_body)
            ]
        )

    def test_display_http_response_with_xml_payload_and_whitespace(self):
        xml_body = '<?xml version="1.0" ?><foo><bar>text</bar></foo>'
        self.assert_output(
            for_event={
                'event_type': 'HTTP_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'status_code': 200,
                    'headers': {},
                    'body': self.get_pretty_xml(xml_body)
                },
                'timestamp': 86400000,
            },
            # The XML should not be prettified more than once if the body
            # of the response was already prettied.
            contains=[
                'with body: ' + self.get_pretty_xml(xml_body)
            ]
        )

    def test_display_http_response_with_json_struct_payload(self):
        self.assert_output(
            for_event={
                'event_type': 'HTTP_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {
                    'status_code': 200,
                    'headers': {},
                    'body': '{"foo": "bar"}'
                },
                'timestamp': 86400000,
            },
            contains=[
                'with body: {\n',
                '    "foo": "bar"\n',
                '}',
            ]
        )

    def test_display_parsed_response(self):
        self.assert_output(
            for_event={
                'event_type': 'PARSED_RESPONSE',
                'id': 'my-id',
                'request_id': 'some-id',
                'payload': {},
                'timestamp': 86400000,
            },
            contains=[
                '[0] HTTP response parsed',
                'parsed to: {}'
            ]
        )

    def test_display_cli_rc(self):
        self.assert_output(
            for_event={
                'event_type': 'CLI_RC',
                'id': 'my-id',
                'payload': 0,
                'timestamp': 86400000,
                'request_id': None
            },
            contains=[
                'AWS CLI command exited',
                'with return code: 0'
            ]
        )

    def test_display_unknown_type(self):
        event = {
            'event_type': 'UNKNOWN',
            'id': 'my-id',
            'payload': 'foo',
            'timestamp': 86400000,
            'request_id': None
        }
        self.formatter.display(event)
        collected_output = ensure_text_type(self.output.getvalue())
        self.assertEqual('', collected_output)
示例#6
0
class TestTextFormatter(unittest.TestCase):
    _COL_WIDTHS = {'id_a': 10, 'timestamp': 23, 'args': 10, 'rc': 10}

    def setUp(self):
        self.output_stream = BytesIO()
        self.formatter = TextFormatter(self._COL_WIDTHS, self.output_stream)

        self.timestamp = 1511376242067
        command_time = datetime.datetime.fromtimestamp(self.timestamp / 1000)
        self.formatted_time = datetime.datetime.strftime(
            command_time, '%Y-%m-%d %I:%M:%S %p')

    def _format_records(self, records):
        adapter = RecordAdapter(iter(records))
        self.formatter(adapter)

    def test_can_emit_single_row(self):
        self._format_records([{
            'id_a': 'foo',
            'timestamp': self.timestamp,
            'args': '["s3", "ls"]',
            'rc': 0
        }])
        expected_output = 'foo       %s s3 ls     0\n' % self.formatted_time
        actual_output = ensure_text_type(self.output_stream.getvalue())
        self.assertEqual(expected_output, actual_output)

    def test_can_emit_multiple_rows(self):
        self._format_records([{
            'id_a': 'foo',
            'timestamp': self.timestamp,
            'args': '["s3", "ls"]',
            'rc': 0
        }, {
            'id_a': 'bar',
            'timestamp': self.timestamp,
            'args': '["s3", "cp"]',
            'rc': 1
        }])
        expected_output = ('foo       %s s3 ls     0\n'
                           'bar       %s s3 cp     1\n') % (
                               self.formatted_time, self.formatted_time)
        actual_output = ensure_text_type(self.output_stream.getvalue())
        self.assertEqual(expected_output, actual_output)

    def test_can_truncate_args(self):
        # Truncate the argument if it won't fit in the space alotted to the
        # arguments field.
        self._format_records([{
            'id_a':
            'foo',
            'timestamp':
            self.timestamp,
            'args': ('["s3", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]'),
            'rc':
            0
        }])
        expected_output = 'foo       %s s3 aaa... 0\n' % self.formatted_time
        actual_output = ensure_text_type(self.output_stream.getvalue())
        self.assertEqual(expected_output, actual_output)
示例#7
0
class TestTextFormatter(unittest.TestCase):
    _COL_WIDTHS = {
        'id_a': 10,
        'timestamp': 23,
        'args': 10,
        'rc': 10
    }

    def setUp(self):
        self.output_stream = BytesIO()
        self.formatter = TextFormatter(self._COL_WIDTHS, self.output_stream)

        self.timestamp = 1511376242067
        command_time = datetime.datetime.fromtimestamp(self.timestamp / 1000)
        self.formatted_time = datetime.datetime.strftime(
            command_time, '%Y-%m-%d %I:%M:%S %p')

    def _format_records(self, records):
        adapter = RecordAdapter(iter(records))
        self.formatter(adapter)

    def test_can_emit_single_row(self):
        self._format_records([
            {
                'id_a': 'foo',
                'timestamp': self.timestamp,
                'args': '["s3", "ls"]',
                'rc': 0
            }
        ])
        expected_output = 'foo       %s s3 ls     0\n' % self.formatted_time
        actual_output = ensure_text_type(self.output_stream.getvalue())
        self.assertEqual(expected_output, actual_output)

    def test_can_emit_multiple_rows(self):
        self._format_records([
            {
                'id_a': 'foo',
                'timestamp': self.timestamp,
                'args': '["s3", "ls"]',
                'rc': 0
            },
            {
                'id_a': 'bar',
                'timestamp': self.timestamp,
                'args': '["s3", "cp"]',
                'rc': 1
            }
        ])
        expected_output = ('foo       %s s3 ls     0\n'
                           'bar       %s s3 cp     1\n') % (
                               self.formatted_time, self.formatted_time)
        actual_output = ensure_text_type(self.output_stream.getvalue())
        self.assertEqual(expected_output, actual_output)

    def test_can_truncate_args(self):
        # Truncate the argument if it won't fit in the space alotted to the
        # arguments field.
        self._format_records([
            {
                'id_a': 'foo',
                'timestamp': self.timestamp,
                'args': ('["s3", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
                         'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]'),
                'rc': 0
            }
        ])
        expected_output = 'foo       %s s3 aaa... 0\n' % self.formatted_time
        actual_output = ensure_text_type(self.output_stream.getvalue())
        self.assertEqual(expected_output, actual_output)