# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.12import uuid1314from botocore.history import HistoryRecorder1516from awscli.testutils import mock, create_clidriver, FileCreator17from awscli.testutils import BaseAWSCommandParamsTest18from awscli.compat import BytesIO192021class BaseHistoryCommandParamsTest(BaseAWSCommandParamsTest):22def setUp(self):23history_recorder = self._make_clean_history_recorder()24super(BaseHistoryCommandParamsTest, self).setUp()25self.history_recorder = history_recorder26self.files = FileCreator()27config_contents = (28'[default]\n'29'cli_history = enabled'30)31self.environ['AWS_CONFIG_FILE'] = self.files.create_file(32'config', config_contents)33self.environ['AWS_CLI_HISTORY_FILE'] = self.files.create_file(34'history.db', '')35self.driver = create_clidriver()36# The run_cmd patches stdout with a StringIO object (similar to what37# nose does). Therefore it will run into issues when38# get_binary_stdout is called because it returns sys.stdout.buffer39# for Py3 and StringIO does not have a buffer40self.binary_stdout_patch = mock.patch(41'awscli.utils.get_binary_stdout')42mock_get_binary_stdout = self.binary_stdout_patch.start()43self.binary_stdout = BytesIO()44mock_get_binary_stdout.return_value = self.binary_stdout4546def _make_clean_history_recorder(self):47# This is to ensure that for each new test run the CLI is using48# a brand new HistoryRecorder as this is global so previous test49# runs could have injected handlers onto it as all of the tests50# are ran in the same process.51history_recorder = HistoryRecorder()5253# The HISTORY_RECORDER is instantiated on module import before we54# doing any patching which means we cannot simply patch55# botocore.get_global_history_recorder as the objects are already56# instantiated as so we have to individually patch each one of these...57self._apply_history_recorder_patch(58'awscli.clidriver', history_recorder)59self._apply_history_recorder_patch(60'awscli.customizations.history', history_recorder)61return history_recorder6263def _apply_history_recorder_patch(self, module, history_recorder):64patch_history_recorder = mock.patch(65module + '.HISTORY_RECORDER', history_recorder)66patch_history_recorder.start()67self.addCleanup(patch_history_recorder.stop)6869def _cleanup_db_connections(self):70# Reaching into private data to close out the database connection.71# Windows won't let us delete the tempdir until these connections are72# closed in the tearDown step and we have no other way of forcing73# them to close.74handlers = self.history_recorder._handlers75for handler in handlers:76handler._writer.close()7778def tearDown(self):79super(BaseHistoryCommandParamsTest, self).tearDown()80self._cleanup_db_connections()81self.files.remove_all()82self.binary_stdout_patch.stop()838485