diff --git a/.changes/next-release/enhancement-Migration-87248.json b/.changes/next-release/enhancement-Migration-87248.json new file mode 100644 index 000000000000..88099af194ab --- /dev/null +++ b/.changes/next-release/enhancement-Migration-87248.json @@ -0,0 +1,5 @@ +{ + "type": "enhancement", + "category": "Migration", + "description": "Added support to upgrade debug mode for detecting breaking change introduced in AWS CLI v2: in v2, Cyclic Redundancy Check 64 (CRC64NVME) is used by default for ``aws s3`` commands that upload a file to S3, but Cyclic Redundancy Check 32 (CRC32) is used instead in v1. To use upgrade debug mode, specify the ``--v2-debug`` global parameter on a command." +} diff --git a/awscli/customizations/s3/subcommands.py b/awscli/customizations/s3/subcommands.py index 473293c6a3c0..1fc9efe1cd44 100644 --- a/awscli/customizations/s3/subcommands.py +++ b/awscli/customizations/s3/subcommands.py @@ -1144,6 +1144,27 @@ def run(self): '#cliv2-migration-s3-copy-metadata.\n\n', out_file=sys.stderr ) + elif ( + operation_name == 'upload' + and self.parameters.get('checksum_algorithm') is None + and self.session.get_config_variable( + 'request_checksum_calculation' + ) == 'when_supported' + ): + uni_print( + '\nAWS CLI v2 UPGRADE WARNING: In AWS CLI v2, for ' + '`aws s3` commands that upload a file to an S3 bucket, ' + 'Cyclic Redundancy Check 64 (CRC64NVME) will be used to ' + 'compute object checksums by default and included in ' + 'the request. This is different from v1 behavior, where ' + 'Cyclic Redundancy Check 32 (CRC32) checksums ' + 'are used. For guidance on retaining v1 behavior ' + 'in AWS CLI v2, or for more details, see ' + 'https://docs.aws.amazon.com/cli/latest/userguide/' + 'cliv2-migration-changes.html' + '#cliv2-migration-checksums.\n\n', + out_file=sys.stderr + ) fgen_kwargs = { 'client': self._source_client, 'operation_name': operation_name, diff --git a/tests/functional/s3/test_cp_command.py b/tests/functional/s3/test_cp_command.py index d0243d657bd6..a41b375dec07 100644 --- a/tests/functional/s3/test_cp_command.py +++ b/tests/functional/s3/test_cp_command.py @@ -13,7 +13,7 @@ # language governing permissions and limitations under the License. import os -from awscli.testutils import BaseAWSCommandParamsTest, skip_if_windows +from awscli.testutils import BaseAWSCommandParamsTest, skip_if_windows, temporary_file, create_clidriver from awscli.testutils import capture_input from awscli.testutils import mock from awscli.compat import BytesIO @@ -817,6 +817,55 @@ def test_download_with_checksum_mode_crc32c(self): self.assertEqual(self.operations_called[1][0].name, 'GetObject') self.assertEqual(self.operations_called[1][1]['ChecksumMode'], 'ENABLED') + def test_upload_with_no_checksum_param_v2_debug(self): + full_path = self.files.create_file('foo.txt', 'contents') + cmdline = f'{self.prefix} {full_path} s3://bucket/key.txt --v2-debug' + _, stderr, _ = self.run_cmd(cmdline, expected_rc=0) + self.assertIn( + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, for `aws s3` ' + 'commands that upload a file to an S3 bucket, Cyclic Redundancy ' + 'Check 64 (CRC64NVME) will be used to compute object checksums by ' + 'default and included in the request.', + stderr + ) + + def test_upload_with_no_checksum_when_required_v2_debug(self): + with temporary_file('w') as f: + f.write( + "[default]\n" + "request_checksum_calculation = when_required\n" + ) + f.flush() + self.environ['AWS_CONFIG_FILE'] = f.name + self.driver = create_clidriver() + full_path = self.files.create_file('foo.txt', 'contents') + cmdline = ( + f'{self.prefix} {full_path} s3://bucket/key.txt --v2-debug' + ) + _, stderr, _ = self.run_cmd(cmdline, expected_rc=0) + self.assertNotIn( + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, for `aws s3` ' + 'commands that upload a file to an S3 bucket, Cyclic Redundancy ' + 'Check 64 (CRC64NVME) will be used to compute object checksums by ' + 'default and included in the request.', + stderr + ) + + def test_upload_with_crc32_checksum_v2_debug(self): + full_path = self.files.create_file('foo.txt', 'contents') + cmdline = ( + f'{self.prefix} {full_path} s3://bucket/key.txt ' + '--checksum-algorithm CRC32 --v2-debug' + ) + _, stderr, _ = self.run_cmd(cmdline, expected_rc=0) + self.assertNotIn( + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, for `aws s3` ' + 'commands that upload a file to an S3 bucket, Cyclic Redundancy ' + 'Check 64 (CRC64NVME) will be used to compute object checksums by ' + 'default and included in the request.', + stderr + ) + class TestStreamingCPCommand(BaseAWSCommandParamsTest): def test_streaming_upload(self): diff --git a/tests/functional/s3/test_mv_command.py b/tests/functional/s3/test_mv_command.py index b7e6ca71ed63..947122cfa7cc 100644 --- a/tests/functional/s3/test_mv_command.py +++ b/tests/functional/s3/test_mv_command.py @@ -13,7 +13,7 @@ # language governing permissions and limitations under the License. from awscli.customizations.s3.utils import S3PathResolver from awscli.compat import BytesIO -from awscli.testutils import skip_if_case_sensitive +from awscli.testutils import skip_if_case_sensitive, temporary_file, create_clidriver from tests.functional.s3 import BaseS3TransferCommandTest from tests.functional.s3.test_sync_command import TestSyncCaseConflict from tests import requires_crt @@ -165,6 +165,55 @@ def test_download_with_checksum_mode_crc32(self): self.assertEqual(self.operations_called[1][0].name, 'GetObject') self.assertEqual(self.operations_called[1][1]['ChecksumMode'], 'ENABLED') + def test_upload_with_no_checksum_param_v2_debug(self): + full_path = self.files.create_file('foo.txt', 'contents') + cmdline = f'{self.prefix} {full_path} s3://bucket/key.txt --v2-debug' + _, stderr, _ = self.run_cmd(cmdline, expected_rc=0) + self.assertIn( + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, for `aws s3` ' + 'commands that upload a file to an S3 bucket, Cyclic Redundancy ' + 'Check 64 (CRC64NVME) will be used to compute object checksums by ' + 'default and included in the request.', + stderr + ) + + def test_upload_with_no_checksum_when_required_v2_debug(self): + with temporary_file('w') as f: + f.write( + "[default]\n" + "request_checksum_calculation = when_required\n" + ) + f.flush() + self.environ['AWS_CONFIG_FILE'] = f.name + self.driver = create_clidriver() + full_path = self.files.create_file('foo.txt', 'contents') + cmdline = ( + f'{self.prefix} {full_path} s3://bucket/key.txt --v2-debug' + ) + _, stderr, _ = self.run_cmd(cmdline, expected_rc=0) + self.assertNotIn( + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, for `aws s3` ' + 'commands that upload a file to an S3 bucket, Cyclic Redundancy ' + 'Check 64 (CRC64NVME) will be used to compute object checksums by ' + 'default and included in the request.', + stderr + ) + + def test_upload_with_crc32_checksum_v2_debug(self): + full_path = self.files.create_file('foo.txt', 'contents') + cmdline = ( + f'{self.prefix} {full_path} s3://bucket/key.txt ' + f'--checksum-algorithm CRC32 --v2-debug' + ) + _, stderr, _ = self.run_cmd(cmdline, expected_rc=0) + self.assertNotIn( + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, for `aws s3` ' + 'commands that upload a file to an S3 bucket, Cyclic Redundancy ' + 'Check 64 (CRC64NVME) will be used to compute object checksums by ' + 'default and include it in the request.', + stderr + ) + class TestMvCommandWithValidateSameS3Paths(BaseS3TransferCommandTest):