From 2a9453782f1aabe8bfb8a11bff33db2476fd071c Mon Sep 17 00:00:00 2001 From: Matt Muller Date: Mon, 14 Oct 2024 13:19:53 -0400 Subject: [PATCH] Move create defaults to transfer manager --- gems/aws-sdk-core/CHANGELOG.md | 4 +- .../plugins/checksum_algorithm.rb | 50 ++++++++--------- .../aws/plugins/checksum_algorithm_spec.rb | 50 ++++++++--------- gems/aws-sdk-s3/lib/aws-sdk-s3/client.rb | 35 +++--------- .../lib/aws-sdk-s3/file_downloader.rb | 2 +- .../lib/aws-sdk-s3/multipart_file_uploader.rb | 12 ++-- .../aws-sdk-s3/lib/aws-sdk-s3/plugins/md5s.rb | 8 +-- .../spec/object/upload_file_spec.rb | 56 ++++++++++--------- 8 files changed, 100 insertions(+), 117 deletions(-) diff --git a/gems/aws-sdk-core/CHANGELOG.md b/gems/aws-sdk-core/CHANGELOG.md index be353df1180..af1ac935fb5 100644 --- a/gems/aws-sdk-core/CHANGELOG.md +++ b/gems/aws-sdk-core/CHANGELOG.md @@ -1,9 +1,9 @@ Unreleased Changes ------------------ -* Feature - Always calculate request checksums for operations that support or require it. Supported config options are `WHEN_SUPPORTED` and `WHEN_REQUIRED`. The default value is `WHEN_SUPPORTED`. This option is configured in code with `:request_checksum_calculation`, in the shared config file as `request_checksum_calculation`, and in the ENV as `ENV['AWS_REQUEST_CHECKSUM_CALCULATION']`. +* Feature - Always calculate request checksums for operations that support or require it. Supported config options are `when_supported` and `when_required`. The default value is `when_supported`. This option is configured in code with `:request_checksum_calculation`, in the shared config file as `request_checksum_calculation`, and in the ENV as `ENV['AWS_REQUEST_CHECKSUM_CALCULATION']`. -* Feature - Always validate response checksums for operations that support or require it. Supported config options are `WHEN_SUPPORTED` and `WHEN_REQUIRED`. The default value is `WHEN_SUPPORTED`. This option is configured in code with `:response_checksum_validation`, in the shared config file as `response_checksum_validation`, and in the ENV as `ENV['AWS_response_checksum_validation']`. +* Feature - Always validate response checksums for operations that support or require it. Supported config options are `when_supported` and `when_required`. The default value is `when_supported`. This option is configured in code with `:response_checksum_validation`, in the shared config file as `response_checksum_validation`, and in the ENV as `ENV['AWS_response_checksum_validation']`. 3.209.1 (2024-09-25) ------------------ diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb index bbb80b4e799..334df6d5285 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/checksum_algorithm.rb @@ -38,16 +38,16 @@ class ChecksumAlgorithm < Seahorse::Client::Plugin DEFAULT_CHECKSUM = 'CRC32' option(:request_checksum_calculation, - doc_default: 'WHEN_SUPPORTED', + doc_default: 'when_supported', doc_type: 'String', docstring: <<~DOCS) do |cfg| Determines when a checksum will be calculated for request payloads. Values are: - * `WHEN_SUPPORTED` - (default) When set, a checksum will be + * `when_supported` - (default) When set, a checksum will be calculated for all request payloads of operations modeled with the `httpChecksum` trait where `requestChecksumRequired` is `true` and/or a `requestAlgorithmMember` is modeled. - * `WHEN_REQUIRED` - When set, a checksum will only be calculated for + * `when_required` - When set, a checksum will only be calculated for request payloads of operations modeled with the `httpChecksum` trait where `requestChecksumRequired` is `true` or where a requestAlgorithmMember is modeled and supplied. @@ -56,16 +56,16 @@ class ChecksumAlgorithm < Seahorse::Client::Plugin end option(:response_checksum_validation, - doc_default: 'WHEN_SUPPORTED', + doc_default: 'when_supported', doc_type: 'String', docstring: <<~DOCS) do |cfg| Determines when checksum validation will be performed on response payloads. Values are: - * `WHEN_SUPPORTED` - (default) When set, checksum validation is performed on all + * `when_supported` - (default) When set, checksum validation is performed on all response payloads of operations modeled with the `httpChecksum` trait where `responseAlgorithms` is modeled, except when no modeled checksum algorithms are supported. - * `WHEN_REQUIRED` - When set, checksum validation is not performed on + * `when_required` - When set, checksum validation is not performed on response payloads of operations unless the checksum algorithm is supported and the `requestValidationModeMember` member is set to `ENABLED`. DOCS @@ -102,13 +102,13 @@ def trailer_length(algorithm, location_name) def resolve_request_checksum_calculation(cfg) mode = ENV['AWS_REQUEST_CHECKSUM_CALCULATION'] || Aws.shared_config.request_checksum_calculation(profile: cfg.profile) || - 'WHEN_SUPPORTED' - mode = mode.upcase - unless %w[WHEN_SUPPORTED WHEN_REQUIRED].include?(mode) + 'when_supported' + mode = mode.downcase + unless %w[when_supported when_required].include?(mode) raise ArgumentError, 'expected :request_checksum_calculation or' \ " ENV['AWS_REQUEST_CHECKSUM_CALCULATION'] to be " \ - '`WHEN_SUPPORTED` or `WHEN_REQUIRED`.' + '`when_supported` or `when_required`.' end mode end @@ -116,13 +116,13 @@ def resolve_request_checksum_calculation(cfg) def resolve_response_checksum_validation(cfg) mode = ENV['AWS_response_checksum_validation'] || Aws.shared_config.response_checksum_validation(profile: cfg.profile) || - 'WHEN_SUPPORTED' - mode = mode.upcase - unless %w[WHEN_SUPPORTED WHEN_REQUIRED].include?(mode) + 'when_supported' + mode = mode.downcase + unless %w[when_supported when_required].include?(mode) raise ArgumentError, 'expected :response_checksum_validation or' \ " ENV['AWS_response_checksum_validation'] to be " \ - '`WHEN_SUPPORTED` or `WHEN_REQUIRED`.' + '`when_supported` or `when_required`.' end mode end @@ -160,7 +160,7 @@ def call(context) context[:http_checksum] ||= {} # Set validation mode to enabled when supported. - if context.config.response_checksum_validation == 'WHEN_SUPPORTED' + if context.config.response_checksum_validation == 'when_supported' enable_request_validation_mode(context) end @@ -221,19 +221,19 @@ def with_metrics(config, algorithm, &block) def add_request_config_metric(config, metrics) case config.request_checksum_calculation - when 'WHEN_SUPPORTED' - metrics << 'FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED' - when 'WHEN_REQUIRED' - metrics << 'FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED' + when 'when_supported' + metrics << 'FLEXIBLE_CHECKSUMS_REQ_when_supported' + when 'when_required' + metrics << 'FLEXIBLE_CHECKSUMS_REQ_when_required' end end def add_response_config_metric(config, metrics) case config.response_checksum_validation - when 'WHEN_SUPPORTED' - metrics << 'FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED' - when 'WHEN_REQUIRED' - metrics << 'FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED' + when 'when_supported' + metrics << 'FLEXIBLE_CHECKSUMS_RES_when_supported' + when 'when_required' + metrics << 'FLEXIBLE_CHECKSUMS_RES_when_required' end end @@ -275,12 +275,12 @@ def operation_response_algorithms(context) def checksum_required?(context) (http_checksum = context.operation.http_checksum) && (checksum_required = http_checksum['requestChecksumRequired']) && - (checksum_required && context.config.request_checksum_calculation == 'WHEN_REQUIRED') + (checksum_required && context.config.request_checksum_calculation == 'when_required') end def checksum_optional?(context) context.operation.http_checksum && - context.config.request_checksum_calculation == 'WHEN_SUPPORTED' + context.config.request_checksum_calculation == 'when_supported' end def checksum_provided_as_header?(headers) diff --git a/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb b/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb index 9d5025a8dfa..c24ccadef88 100644 --- a/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb +++ b/gems/aws-sdk-core/spec/aws/plugins/checksum_algorithm_spec.rb @@ -101,58 +101,58 @@ module Plugins describe 'request_checksum_calculation' do it 'is configured to always compute by default' do expect(client.config.request_checksum_calculation) - .to eq('WHEN_SUPPORTED') + .to eq('when_supported') end it 'can be configured using shared config' do allow_any_instance_of(Aws::SharedConfig) .to receive(:request_checksum_calculation) - .and_return('WHEN_REQUIRED') + .and_return('when_required') expect(client.config.request_checksum_calculation) - .to eq('WHEN_REQUIRED') + .to eq('when_required') end it 'can be configured using ENV with precedence over shared config' do allow_any_instance_of(Aws::SharedConfig) .to receive(:request_checksum_calculation) - .and_return('WHEN_SUPPORTED') - ENV['AWS_REQUEST_CHECKSUM_CALCULATION'] = 'WHEN_REQUIRED' + .and_return('when_supported') + ENV['AWS_REQUEST_CHECKSUM_CALCULATION'] = 'when_required' expect(client.config.request_checksum_calculation) - .to eq('WHEN_REQUIRED') + .to eq('when_required') end it 'raises when request_checksum_calculation is not valid' do ENV['AWS_REQUEST_CHECKSUM_CALCULATION'] = 'peccy' - expect { client }.to raise_error(ArgumentError, /WHEN_SUPPORTED/) + expect { client }.to raise_error(ArgumentError, /when_supported/) end end describe 'response_checksum_validation' do it 'is configured to always verify by default' do expect(client.config.response_checksum_validation) - .to eq('WHEN_SUPPORTED') + .to eq('when_supported') end it 'can be configured using shared config' do allow_any_instance_of(Aws::SharedConfig) .to receive(:response_checksum_validation) - .and_return('WHEN_REQUIRED') + .and_return('when_required') expect(client.config.response_checksum_validation) - .to eq('WHEN_REQUIRED') + .to eq('when_required') end it 'can be configured using ENV with precedence over shared config' do allow_any_instance_of(Aws::SharedConfig) .to receive(:response_checksum_validation) - .and_return('WHEN_SUPPORTED') - ENV['AWS_response_checksum_validation'] = 'WHEN_REQUIRED' + .and_return('when_supported') + ENV['AWS_response_checksum_validation'] = 'when_required' expect(client.config.response_checksum_validation) - .to eq('WHEN_REQUIRED') + .to eq('when_required') end it 'raises when response_checksum_validation is not valid' do ENV['AWS_response_checksum_validation'] = 'peccy' - expect { client }.to raise_error(ArgumentError, /WHEN_SUPPORTED/) + expect { client }.to raise_error(ArgumentError, /when_supported/) end end @@ -311,16 +311,16 @@ module Plugins context 'when checksums are not required' do let(:request_checksum_required) { false } - it 'WHEN_SUPPORTED; no algorithm; includes a checksum' do + it 'when_supported; no algorithm; includes a checksum' do resp = client.http_checksum_operation(checksum_algorithm: 'CRC32') expect(resp.context.http_request.headers['x-amz-checksum-crc32']) .to eq('AAAAAA==') end - it 'WHEN_REQUIRED; no algorithm; does not include a checksum' do + it 'when_required; no algorithm; does not include a checksum' do client = checksum_client.new( stub_responses: true, - request_checksum_calculation: 'WHEN_REQUIRED' + request_checksum_calculation: 'when_required' ) resp = client.http_checksum_operation expect(resp.context.http_request.headers['x-amz-checksum-crc32']) @@ -331,16 +331,16 @@ module Plugins context 'when checksums are required' do let(:request_checksum_required) { true } - it 'WHEN_SUPPORTED; no algorithm; includes a checksum' do + it 'when_supported; no algorithm; includes a checksum' do resp = client.http_checksum_operation expect(resp.context.http_request.headers['x-amz-checksum-crc32']) .to eq('AAAAAA==') end - it 'WHEN_REQUIRED; no algorithm; includes a checksum' do + it 'when_required; no algorithm; includes a checksum' do client = checksum_client.new( stub_responses: true, - request_checksum_calculation: 'WHEN_REQUIRED' + request_checksum_calculation: 'when_required' ) resp = client.http_checksum_operation expect(resp.context.http_request.headers['x-amz-checksum-crc32']) @@ -362,7 +362,7 @@ def stub_client(client) ) end - it 'WHEN_SUPPORTED; not ENABLED; validates the checksum' do + it 'when_supported; not ENABLED; validates the checksum' do stub_client(client) resp = client.http_checksum_operation expect(resp.context[:http_checksum][:validated]).to eq('CRC32') @@ -370,20 +370,20 @@ def stub_client(client) expect(resp.context.params[:validation_mode]).to eq('ENABLED') end - it 'WHEN_REQUIRED; not ENABLED; does not validate the checksum' do + it 'when_required; not ENABLED; does not validate the checksum' do client = checksum_client.new( stub_responses: true, - response_checksum_validation: 'WHEN_REQUIRED' + response_checksum_validation: 'when_required' ) stub_client(client) resp = client.http_checksum_operation expect(resp.context[:http_checksum][:validated]).to be_nil end - it 'WHEN_REQUIRED; ENABLED; validates the checksum' do + it 'when_required; ENABLED; validates the checksum' do client = checksum_client.new( stub_responses: true, - response_checksum_validation: 'WHEN_REQUIRED' + response_checksum_validation: 'when_required' ) stub_client(client) resp = client.http_checksum_operation(validation_mode: 'ENABLED') diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/client.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/client.rb index f76b9554f32..6b303f78d2f 100644 --- a/gems/aws-sdk-s3/lib/aws-sdk-s3/client.rb +++ b/gems/aws-sdk-s3/lib/aws-sdk-s3/client.rb @@ -40,7 +40,6 @@ require 'aws-sdk-s3/plugins/arn.rb' require 'aws-sdk-s3/plugins/bucket_dns.rb' require 'aws-sdk-s3/plugins/bucket_name_restrictions.rb' -require 'aws-sdk-s3/plugins/checksum_algorithm.rb' require 'aws-sdk-s3/plugins/dualstack.rb' require 'aws-sdk-s3/plugins/expect_100_continue.rb' require 'aws-sdk-s3/plugins/express_session_auth.rb' @@ -53,6 +52,7 @@ require 'aws-sdk-s3/plugins/s3_host_id.rb' require 'aws-sdk-s3/plugins/s3_signer.rb' require 'aws-sdk-s3/plugins/sse_cpk.rb' +require 'aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb' require 'aws-sdk-s3/plugins/streaming_retry.rb' require 'aws-sdk-s3/plugins/url_encoded_keys.rb' require 'aws-sdk-core/plugins/event_stream_configuration.rb' @@ -111,7 +111,6 @@ class Client < Seahorse::Client::Base add_plugin(Aws::S3::Plugins::ARN) add_plugin(Aws::S3::Plugins::BucketDns) add_plugin(Aws::S3::Plugins::BucketNameRestrictions) - add_plugin(Aws::S3::Plugins::ChecksumAlgorithm) add_plugin(Aws::S3::Plugins::Dualstack) add_plugin(Aws::S3::Plugins::Expect100Continue) add_plugin(Aws::S3::Plugins::ExpressSessionAuth) @@ -124,6 +123,7 @@ class Client < Seahorse::Client::Base add_plugin(Aws::S3::Plugins::S3HostId) add_plugin(Aws::S3::Plugins::S3Signer) add_plugin(Aws::S3::Plugins::SseCpk) + add_plugin(Aws::S3::Plugins::SkipWholeMultipartGetChecksums) add_plugin(Aws::S3::Plugins::StreamingRetry) add_plugin(Aws::S3::Plugins::UrlEncodedKeys) add_plugin(Aws::Plugins::EventStreamConfiguration) @@ -240,9 +240,11 @@ class Client < Seahorse::Client::Base # will use the Client Side Monitoring Agent Publisher. # # @option options [Boolean] :compute_checksums (true) - # This option is deprecated. Please use `:request_checksum_calculation` - # instead. When `true`, `request_checksum_calculation` is set to `WHEN_SUPPORTED`, - # and if `false` it is set to `WHEN_REQUIRED`. + # When `true` a MD5 checksum will be computed and sent in the Content Md5 + # header for :put_object and :upload_part. When `false`, MD5 checksums + # will not be computed for these operations. Checksums are still computed + # for operations requiring them. Checksum errors returned by Amazon S3 are + # automatically retried up to `:retry_limit` times. # # @option options [Boolean] :convert_params (true) # When `true`, an attempt is made to coerce request parameters into @@ -338,18 +340,6 @@ class Client < Seahorse::Client::Base # Used when loading credentials from the shared credentials file # at HOME/.aws/credentials. When not specified, 'default' is used. # - # @option options [String] :request_checksum_calculation ("WHEN_SUPPORTED") - # Determines when a checksum will be calculated for request payloads. Values are: - # - # * `WHEN_SUPPORTED` - (default) When set, a checksum will be - # calculated for all request payloads of operations modeled with the - # `httpChecksum` trait where `requestChecksumRequired` is `true` and/or a - # `requestAlgorithmMember` is modeled. - # * `WHEN_REQUIRED` - When set, a checksum will only be calculated for - # request payloads of operations modeled with the `httpChecksum` trait where - # `requestChecksumRequired` is `true` or where a requestAlgorithmMember - # is modeled and supplied. - # # @option options [Integer] :request_min_compression_size_bytes (10240) # The minimum size in bytes that triggers compression for request # bodies. The value must be non-negative integer value between 0 @@ -360,17 +350,6 @@ class Client < Seahorse::Client::Base # where server-side-encryption is used with customer-provided keys. # This should only be disabled for local testing. # - # @option options [String] :response_checksum_validation ("WHEN_SUPPORTED") - # Determines when checksum validation will be performed on response payloads. Values are: - # - # * `WHEN_SUPPORTED` - (default) When set, checksum validation is performed on all - # response payloads of operations modeled with the `httpChecksum` trait where - # `responseAlgorithms` is modeled, except when no modeled checksum algorithms - # are supported. - # * `WHEN_REQUIRED` - When set, checksum validation is not performed on - # response payloads of operations unless the checksum algorithm is supported and - # the `requestValidationModeMember` member is set to `ENABLED`. - # # @option options [Proc] :retry_backoff # A proc or lambda used for backoff. Defaults to 2**retries * retry_base_delay. # This option is only used in the `legacy` retry mode. diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/file_downloader.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/file_downloader.rb index beb7351c836..fd45b82ac66 100644 --- a/gems/aws-sdk-s3/lib/aws-sdk-s3/file_downloader.rb +++ b/gems/aws-sdk-s3/lib/aws-sdk-s3/file_downloader.rb @@ -28,7 +28,7 @@ def download(destination, options = {}) @chunk_size = options[:chunk_size] @params = { bucket: options[:bucket], - key: options[:key], + key: options[:key] } @params[:version_id] = options[:version_id] if options[:version_id] @on_checksum_validated = options[:on_checksum_validated] diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/multipart_file_uploader.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/multipart_file_uploader.rb index 331d283af2d..b2397c2c0bb 100644 --- a/gems/aws-sdk-s3/lib/aws-sdk-s3/multipart_file_uploader.rb +++ b/gems/aws-sdk-s3/lib/aws-sdk-s3/multipart_file_uploader.rb @@ -122,7 +122,9 @@ def compute_parts(upload_id, source, options) end def create_opts(options) - CREATE_OPTIONS.inject({}) do |hash, key| + default_checksum = Aws::Plugins::ChecksumAlgorithm::DEFAULT_CHECKSUM + opts = { checksum_algorithm: default_checksum } + CREATE_OPTIONS.inject(opts) do |hash, key| hash[key] = options[key] if options.key?(key) hash end @@ -163,11 +165,9 @@ def upload_in_threads(pending, completed, options) etag: resp.etag, part_number: part[:part_number] } - # get the requested checksum from the response - if part[:checksum_algorithm] - k = "checksum_#{part[:checksum_algorithm].downcase}".to_sym - completed_part[k] = resp[k] - end + algorithm = resp.context.params[:checksum_algorithm] + k = "checksum_#{algorithm.downcase}".to_sym + completed_part[k] = resp.send(k) completed.push(completed_part) end nil diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/md5s.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/md5s.rb index cec90b7252c..002a4f6faf5 100644 --- a/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/md5s.rb +++ b/gems/aws-sdk-s3/lib/aws-sdk-s3/plugins/md5s.rb @@ -14,16 +14,16 @@ class Md5s < Seahorse::Client::Plugin doc_type: 'Boolean', docstring: <<~DOCS) This option is deprecated. Please use `:request_checksum_calculation` - instead. When `true`, `request_checksum_calculation` is set to `WHEN_SUPPORTED`, - and if `false` it is set to `WHEN_REQUIRED`. + instead. When `true`, `request_checksum_calculation` is set to `when_supported`, + and if `false` it is set to `when_required`. DOCS def after_initialize(client) client.config.request_checksum_calculation = if client.config.compute_checksums - 'WHEN_SUPPORTED' + 'when_supported' else - 'WHEN_REQUIRED' + 'when_required' end end end diff --git a/gems/aws-sdk-s3/spec/object/upload_file_spec.rb b/gems/aws-sdk-s3/spec/object/upload_file_spec.rb index 0e147d43775..a894d1782a0 100644 --- a/gems/aws-sdk-s3/spec/object/upload_file_spec.rb +++ b/gems/aws-sdk-s3/spec/object/upload_file_spec.rb @@ -131,37 +131,37 @@ module S3 context 'large objects' do it 'uses multipart APIs for objects >= 100MB' do client.stub_responses(:create_multipart_upload, upload_id: 'id') - client.stub_responses(:upload_part, etag: 'etag') + client.stub_responses(:upload_part, etag: 'etag', checksum_crc32: 'checksum') expect(client).to receive(:complete_multipart_upload).with( bucket: 'bucket', key: 'key', upload_id: 'id', multipart_upload: { parts: [ - { etag: 'etag', part_number: 1 }, - { etag: 'etag', part_number: 2 }, - { etag: 'etag', part_number: 3 }, - { etag: 'etag', part_number: 4 }, - { etag: 'etag', part_number: 5 }, - { etag: 'etag', part_number: 6 }, - { etag: 'etag', part_number: 7 }, - { etag: 'etag', part_number: 8 }, - { etag: 'etag', part_number: 9 }, - { etag: 'etag', part_number: 10 }, - { etag: 'etag', part_number: 11 }, - { etag: 'etag', part_number: 12 }, - { etag: 'etag', part_number: 13 }, - { etag: 'etag', part_number: 14 }, - { etag: 'etag', part_number: 15 }, - { etag: 'etag', part_number: 16 }, - { etag: 'etag', part_number: 17 }, - { etag: 'etag', part_number: 18 }, - { etag: 'etag', part_number: 19 }, - { etag: 'etag', part_number: 20 }, - { etag: 'etag', part_number: 21 }, - { etag: 'etag', part_number: 22 }, - { etag: 'etag', part_number: 23 }, - { etag: 'etag', part_number: 24 } + { checksum_crc32: 'checksum', etag: 'etag', part_number: 1 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 2 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 3 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 4 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 5 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 6 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 7 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 8 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 9 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 10 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 11 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 12 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 13 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 14 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 15 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 16 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 17 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 18 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 19 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 20 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 21 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 22 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 23 }, + { checksum_crc32: 'checksum', etag: 'etag', part_number: 24 } ] } ) @@ -176,7 +176,11 @@ module S3 client.stub_responses(:complete_multipart_upload) expect(client).to receive(:upload_part).exactly(24).times do |args| args[:on_chunk_sent].call(args[:body], args[:body].size, args[:body].size) - double(etag: 'etag') + double( + context: double(params: { checksum_algorithm: 'crc32' }), + checksum_crc32: 'checksum', + etag: 'etag' + ) end callback = proc do |bytes, totals| expect(bytes.size).to eq(24)