CLDSRV-898: CompleteMultipartUpload checksums #6166
CLDSRV-898: CompleteMultipartUpload checksums #6166leif-scality wants to merge 9 commits intodevelopment/9.4from
Conversation
leif-scality
commented
May 7, 2026
- Calculate and stores the final checksum when FULL_OBJECT (COMPOSITE are going to be stored by https://scality.atlassian.net/browse/S3C-10399)
- Calculate and compare the final object checksum with the one sent by the headers
- Check that all parts have the correct checksum and checksum type
Hello leif-scality,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
Incorrect fix versionThe
Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:
Please check the |
| ]; | ||
|
|
||
| describe(label, () => { | ||
| it('accepts when every part includes the matching checksum', () => { |
There was a problem hiding this comment.
Test names using it() should start with should (e.g. should accept when every part includes the matching checksum). Multiple tests in this file use verb-first naming like accepts..., returns..., rejects..., does not....
— Claude Code
| assert(got.value.endsWith('-3'), | ||
| `expected -N suffix, got ${got.value}`); | ||
| // computeCompositeMPUChecksum's deterministic output for these | ||
| // exact placeholder digests: |
There was a problem hiding this comment.
Move require('crypto') and require('.../validateChecksums') to the top of the file. crypto is already imported at line 2 and algorithms at line 18 — these inner requires are unnecessary duplicates.
— Claude Code
| }); | ||
| }); | ||
| }); | ||
| }); No newline at end of file |
There was a problem hiding this comment.
Missing newline at end of file.
— Claude Code
| module.exports = completeMultipartUpload; | ||
| module.exports.validatePerPartChecksums = validatePerPartChecksums; | ||
| module.exports.computeFinalChecksum = computeFinalChecksum; | ||
| module.exports.validateExpectedFinalChecksum = validateExpectedFinalChecksum; No newline at end of file |
There was a problem hiding this comment.
Missing newline at end of file.
— Claude Code
3a4f7e2 to
223fb7f
Compare
|
| ]; | ||
|
|
||
| describe(label, () => { | ||
| it('accepts when every part includes the matching checksum', () => { |
There was a problem hiding this comment.
Multiple it() test names in this file do not start with "should" (e.g. line 108 "accepts when every part...", line 120 "returns BadDigest when...", line 357 "accepts CompleteMPU when...", line 413 "rejects CompleteMPU with..."). Per project convention, it() names should start with "should".
— Claude Code
| // exact placeholder digests: | ||
| const expected = require('crypto').createHash('sha256') | ||
| .update(Buffer.concat([d1, d2, d3].map(x => Buffer.from(x, 'base64')))) | ||
| .digest('base64'); |
There was a problem hiding this comment.
require() calls inside it() blocks. crypto is already imported at line 2 and algorithms at line 18. These should be removed in favor of the top-level imports.
Same pattern repeats at lines 568-569 (crypto2/algorithms re-imported) and line 659 (require('crypto') inline).
— Claude Code
| module.exports = completeMultipartUpload; | ||
| module.exports.validatePerPartChecksums = validatePerPartChecksums; | ||
| module.exports.computeFinalChecksum = computeFinalChecksum; | ||
| module.exports.validateExpectedFinalChecksum = validateExpectedFinalChecksum; No newline at end of file |
There was a problem hiding this comment.
Missing trailing newline at end of file.
— Claude Code
| }); | ||
| }); | ||
| }); | ||
| }); No newline at end of file |
There was a problem hiding this comment.
Missing trailing newline at end of file.
— Claude Code
| "@hapi/joi": "^17.1.1", | ||
| "@smithy/node-http-handler": "^3.0.0", | ||
| "arsenal": "git+https://github.com/scality/Arsenal#8.4.1", | ||
| "arsenal": "git+https://github.com/scality/Arsenal#improvement/ARSN-580-handle-checksums-in-complete-mpu", |
There was a problem hiding this comment.
arsenal is pinned to a branch (improvement/ARSN-580-handle-checksums-in-complete-mpu) instead of a tag. Git-based dependencies must pin to a tag for reproducible builds. Replace with the actual release tag once the Arsenal changes are tagged.
— Claude Code
|
❌ 20 Tests Failed:
View the top 3 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
223fb7f to
8095101
Compare
| "@hapi/joi": "^17.1.1", | ||
| "@smithy/node-http-handler": "^3.0.0", | ||
| "arsenal": "git+https://github.com/scality/Arsenal#8.4.1", | ||
| "arsenal": "git+https://github.com/scality/Arsenal#improvement/ARSN-580-handle-checksums-in-complete-mpu", |
There was a problem hiding this comment.
Arsenal is pinned to a branch (improvement/ARSN-580-handle-checksums-in-complete-mpu) instead of a tag. Git-based deps must pin to a tag for reproducible builds; branch refs are mutable and can change without warning.
— Claude Code
| module.exports = completeMultipartUpload; | ||
| module.exports.validatePerPartChecksums = validatePerPartChecksums; | ||
| module.exports.computeFinalChecksum = computeFinalChecksum; | ||
| module.exports.validateExpectedFinalChecksum = validateExpectedFinalChecksum; No newline at end of file |
There was a problem hiding this comment.
Missing newline at end of file. The diff shows No newline at end of file — this will cause lint warnings and untidy diffs on future edits.
— Claude Code
| }); | ||
|
|
||
| it('should return FULL_OBJECT checksum without -N suffix for CRC64NVME', async () => { | ||
| const crypto2 = require('crypto'); |
There was a problem hiding this comment.
require('crypto') and require('.../validateChecksums') are called inside it() blocks (lines 543, 568-570, 659) instead of at the top of the file. Both modules are already imported at the top-level (crypto on line 2, algorithms on line 18). Use the existing top-level bindings instead.
— Claude Code
| ]; | ||
|
|
||
| describe(label, () => { | ||
| it('accepts when every part includes the matching checksum', () => { |
There was a problem hiding this comment.
Test names using it() should start with should per project convention. Multiple tests in this file use imperative forms like accepts, returns, rejects, does not, header comparison, validateMethodChecksumNoChunking, etc. For example: it('accepts when every part includes...') → it('should accept when every part includes...').
— Claude Code
|
8095101 to
9e8bcea
Compare
| "@hapi/joi": "^17.1.1", | ||
| "@smithy/node-http-handler": "^3.0.0", | ||
| "arsenal": "git+https://github.com/scality/Arsenal#8.4.1", | ||
| "arsenal": "git+https://github.com/scality/Arsenal#improvement/ARSN-580-handle-checksums-in-complete-mpu", |
There was a problem hiding this comment.
Arsenal is pinned to a branch (improvement/ARSN-580-handle-checksums-in-complete-mpu) instead of a tag. Git-based dependencies must pin to a tag for reproducible builds.
— Claude Code
| ]; | ||
|
|
||
| describe(label, () => { | ||
| it('accepts when every part includes the matching checksum', () => { |
There was a problem hiding this comment.
Many it() test names in this file don't start with should (e.g. "accepts when every part includes...", "returns BadDigest when...", "header comparison is case-insensitive"). Per project convention, test names should start with should.
— Claude Code
| `expected -N suffix, got ${got.value}`); | ||
| // computeCompositeMPUChecksum's deterministic output for these | ||
| // exact placeholder digests: | ||
| const expected = require('crypto').createHash('sha256') |
There was a problem hiding this comment.
crypto and algorithms are already imported at the top of the file (lines 2 and 19). Move these require() calls out of the test body — the same redundant requires appear at lines 568-569 and 659.
— Claude Code
|