# Copyright 2017 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 uuid from botocore.history import HistoryRecorder from awscli.testutils import mock, create_clidriver, FileCreator from awscli.testutils import BaseAWSCommandParamsTest from awscli.compat import BytesIO class BaseHistoryCommandParamsTest(BaseAWSCommandParamsTest): 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 def _make_clean_history_recorder(self): # This is to ensure that for each new test run the CLI is using # a brand new HistoryRecorder as this is global so previous test # runs could have injected handlers onto it as all of the tests # are ran in the same process. history_recorder = HistoryRecorder() # The HISTORY_RECORDER is instantiated on module import before we # doing any patching which means we cannot simply patch # botocore.get_global_history_recorder as the objects are already # instantiated as so we have to individually patch each one of these... self._apply_history_recorder_patch( 'awscli.clidriver', history_recorder) self._apply_history_recorder_patch( 'awscli.customizations.history', history_recorder) return history_recorder def _apply_history_recorder_patch(self, module, history_recorder): patch_history_recorder = mock.patch( module + '.HISTORY_RECORDER', history_recorder) patch_history_recorder.start() self.addCleanup(patch_history_recorder.stop) def _cleanup_db_connections(self): # Reaching into private data to close out the database connection. # Windows won't let us delete the tempdir until these connections are # closed in the tearDown step and we have no other way of forcing # them to close. handlers = self.history_recorder._handlers for handler in handlers: handler._writer.close() def tearDown(self): super(BaseHistoryCommandParamsTest, self).tearDown() self._cleanup_db_connections() self.files.remove_all() self.binary_stdout_patch.stop()