You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.8 KiB
104 lines
3.8 KiB
package sse_test
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"testing"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestPlainObjectRangeAndHeadHeaders ensures non-SSE objects advertise correct
|
|
// Content-Length and Content-Range information for both HEAD and ranged GETs.
|
|
func TestPlainObjectRangeAndHeadHeaders(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
client, err := createS3Client(ctx, defaultConfig)
|
|
require.NoError(t, err, "failed to create S3 client")
|
|
|
|
bucketName, err := createTestBucket(ctx, client, defaultConfig.BucketPrefix+"range-plain-")
|
|
require.NoError(t, err, "failed to create test bucket")
|
|
defer cleanupTestBucket(ctx, client, bucketName)
|
|
|
|
// SeaweedFS S3 auto-chunks uploads at 8MiB (see chunkSize in putToFiler).
|
|
// Using 16MiB ensures at least two chunks without stressing CI resources.
|
|
const chunkSize = 8 * 1024 * 1024
|
|
const objectSize = 2 * chunkSize
|
|
objectKey := "plain-range-validation"
|
|
testData := generateTestData(objectSize)
|
|
|
|
_, err = client.PutObject(ctx, &s3.PutObjectInput{
|
|
Bucket: aws.String(bucketName),
|
|
Key: aws.String(objectKey),
|
|
Body: bytes.NewReader(testData),
|
|
})
|
|
require.NoError(t, err, "failed to upload test object")
|
|
|
|
t.Run("HeadObject reports accurate Content-Length", func(t *testing.T) {
|
|
resp, err := client.HeadObject(ctx, &s3.HeadObjectInput{
|
|
Bucket: aws.String(bucketName),
|
|
Key: aws.String(objectKey),
|
|
})
|
|
require.NoError(t, err, "HeadObject request failed")
|
|
assert.Equal(t, int64(objectSize), resp.ContentLength, "Content-Length mismatch on HEAD")
|
|
assert.Equal(t, "bytes", aws.ToString(resp.AcceptRanges), "Accept-Ranges should advertise bytes")
|
|
})
|
|
|
|
t.Run("Range request across chunk boundary", func(t *testing.T) {
|
|
// Test range that spans an 8MiB chunk boundary (chunkSize - 1KB to chunkSize + 3KB)
|
|
rangeStart := int64(chunkSize - 1024)
|
|
rangeEnd := rangeStart + 4096 - 1
|
|
rangeHeader := fmt.Sprintf("bytes=%d-%d", rangeStart, rangeEnd)
|
|
|
|
resp, err := client.GetObject(ctx, &s3.GetObjectInput{
|
|
Bucket: aws.String(bucketName),
|
|
Key: aws.String(objectKey),
|
|
Range: aws.String(rangeHeader),
|
|
})
|
|
require.NoError(t, err, "GetObject range request failed")
|
|
defer resp.Body.Close()
|
|
|
|
expectedLen := rangeEnd - rangeStart + 1
|
|
assert.Equal(t, expectedLen, resp.ContentLength, "Content-Length must match requested range size")
|
|
assert.Equal(t,
|
|
fmt.Sprintf("bytes %d-%d/%d", rangeStart, rangeEnd, objectSize),
|
|
aws.ToString(resp.ContentRange),
|
|
"Content-Range header mismatch")
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
require.NoError(t, err, "failed to read range response body")
|
|
assert.Equal(t, int(expectedLen), len(body), "actual bytes read mismatch")
|
|
assert.Equal(t, testData[rangeStart:rangeEnd+1], body, "range payload mismatch")
|
|
})
|
|
|
|
t.Run("Suffix range request", func(t *testing.T) {
|
|
const suffixSize = 2048
|
|
resp, err := client.GetObject(ctx, &s3.GetObjectInput{
|
|
Bucket: aws.String(bucketName),
|
|
Key: aws.String(objectKey),
|
|
Range: aws.String(fmt.Sprintf("bytes=-%d", suffixSize)),
|
|
})
|
|
require.NoError(t, err, "GetObject suffix range request failed")
|
|
defer resp.Body.Close()
|
|
|
|
expectedStart := int64(objectSize - suffixSize)
|
|
expectedEnd := int64(objectSize - 1)
|
|
expectedLen := expectedEnd - expectedStart + 1
|
|
|
|
assert.Equal(t, expectedLen, resp.ContentLength, "suffix Content-Length mismatch")
|
|
assert.Equal(t,
|
|
fmt.Sprintf("bytes %d-%d/%d", expectedStart, expectedEnd, objectSize),
|
|
aws.ToString(resp.ContentRange),
|
|
"suffix Content-Range mismatch")
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
require.NoError(t, err, "failed to read suffix range response body")
|
|
assert.Equal(t, int(expectedLen), len(body), "suffix range byte count mismatch")
|
|
assert.Equal(t, testData[expectedStart:expectedEnd+1], body, "suffix range payload mismatch")
|
|
})
|
|
}
|