Upstream versity/versitygw state of the touched files before 95a6da83b9
This commit is contained in:
1 parent
b7ff97181d
commit
f12ba37b26
4 files changed
+208
-85
No files matched your search
@@ -0,0 +1,205 @@
|
|||||||
|
// Copyright 2026 Versity Software
|
||||||
|
// This file is licensed under the Apache License, Version 2.0
|
||||||
|
// (the "License"); you may not use this file except in compliance
|
||||||
|
// with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing,
|
||||||
|
// software distributed under the License is distributed on an
|
||||||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
// KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations
|
||||||
|
// under the License.
|
||||||
|
|
||||||
|
package backend
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/versity/versitygw/s3err"
|
||||||
|
"github.com/versity/versitygw/s3response"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListMultipartUploads initializes a multipart upload lister and calls Run()
|
||||||
|
func ListMultipartUploads(uploads []s3response.Upload, prefix, delimiter, keyMarker, uploadIdMarker string, maxUploads int) (*ListMultipartUploadsPage, error) {
|
||||||
|
lister := &MultipartUploadLister{
|
||||||
|
Uploads: uploads,
|
||||||
|
Prefix: prefix,
|
||||||
|
Delimiter: delimiter,
|
||||||
|
KeyMarker: keyMarker,
|
||||||
|
UploadIDMarker: uploadIdMarker,
|
||||||
|
MaxUploads: maxUploads,
|
||||||
|
}
|
||||||
|
|
||||||
|
return lister.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultipartUploadLister emits a ListMultipartUploads-compatible page from an
|
||||||
|
// already-sorted, already prefix- and key-marker-filtered upload list.
|
||||||
|
//
|
||||||
|
// Assumptions about input Uploads:
|
||||||
|
// - Sorted by (Key asc, Initiated asc)
|
||||||
|
// - Filtered by Prefix
|
||||||
|
// - Filtered to start strictly after key-marker when key-marker was provided.
|
||||||
|
type MultipartUploadLister struct {
|
||||||
|
Uploads []s3response.Upload
|
||||||
|
Prefix string
|
||||||
|
Delimiter string
|
||||||
|
MaxUploads int
|
||||||
|
KeyMarker string
|
||||||
|
UploadIDMarker string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMultipartUploadsPage is the lister output
|
||||||
|
type ListMultipartUploadsPage struct {
|
||||||
|
Uploads []s3response.Upload
|
||||||
|
CommonPrefixes []s3response.CommonPrefix
|
||||||
|
IsTruncated bool
|
||||||
|
NextKeyMarker string
|
||||||
|
NextUploadIDMarker string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run validates marker constraints, then performs a single-pass list that:
|
||||||
|
// - collapses uploads into CommonPrefixes when delimiter is set
|
||||||
|
// - enforces MaxUploads over (Uploads + CommonPrefixes)
|
||||||
|
// - computes truncation and next markers
|
||||||
|
func (l *MultipartUploadLister) Run() (*ListMultipartUploadsPage, error) {
|
||||||
|
out := &ListMultipartUploadsPage{}
|
||||||
|
|
||||||
|
var startIndex int
|
||||||
|
|
||||||
|
// if upload-id-marker is provided without a corresponding key-marker, ignore it.
|
||||||
|
uploadIDMarker := l.UploadIDMarker
|
||||||
|
if l.KeyMarker == "" {
|
||||||
|
uploadIDMarker = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if uploadIDMarker != "" {
|
||||||
|
// any invalid uuid is considered as an invalid uploadIdMarker
|
||||||
|
_, err := uuid.Parse(uploadIDMarker)
|
||||||
|
if err != nil {
|
||||||
|
return nil, s3err.GetInvalidArgumentErr(s3err.InvalidArgUploadIdMarker, uploadIDMarker)
|
||||||
|
}
|
||||||
|
startIndex = l.findUploadIdMarkerIndex(uploadIDMarker)
|
||||||
|
if startIndex == -1 {
|
||||||
|
return nil, s3err.GetInvalidArgumentErr(s3err.InvalidArgUploadIdMarker, uploadIDMarker)
|
||||||
|
}
|
||||||
|
if startIndex >= len(l.Uploads) {
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Common prefix uniqueness tracking.
|
||||||
|
seenCP := make(map[string]struct{})
|
||||||
|
|
||||||
|
emitted := 0
|
||||||
|
var lastKey string
|
||||||
|
|
||||||
|
// emitUpload appends a new upload to out.Uplodas
|
||||||
|
emitUpload := func(up s3response.Upload) bool {
|
||||||
|
out.Uploads = append(out.Uploads, up)
|
||||||
|
emitted++
|
||||||
|
lastKey = up.Key
|
||||||
|
return emitted == l.MaxUploads
|
||||||
|
}
|
||||||
|
// emitCp appends a new common prefix to out.CommonPrefixes
|
||||||
|
emitCP := func(cpref string) bool {
|
||||||
|
out.CommonPrefixes = append(out.CommonPrefixes, s3response.CommonPrefix{Prefix: cpref})
|
||||||
|
emitted++
|
||||||
|
lastKey = cpref
|
||||||
|
return emitted == l.MaxUploads
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, up := range l.Uploads[startIndex:] {
|
||||||
|
if l.Delimiter != "" {
|
||||||
|
// delimiter check
|
||||||
|
suffix := strings.TrimPrefix(up.Key, l.Prefix)
|
||||||
|
before, _, found := strings.Cut(suffix, l.Delimiter)
|
||||||
|
if found {
|
||||||
|
cpref := l.Prefix + before + l.Delimiter
|
||||||
|
if _, ok := seenCP[cpref]; !ok {
|
||||||
|
seenCP[cpref] = struct{}{}
|
||||||
|
if emitCP(cpref) {
|
||||||
|
out.IsTruncated = l.hasMoreAfter(i+1, seenCP)
|
||||||
|
if out.IsTruncated {
|
||||||
|
out.NextKeyMarker = lastKey
|
||||||
|
out.NextUploadIDMarker = up.UploadID
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if emitUpload(up) {
|
||||||
|
out.IsTruncated = l.hasMoreAfter(i+1, seenCP)
|
||||||
|
if out.IsTruncated {
|
||||||
|
out.NextKeyMarker = lastKey
|
||||||
|
out.NextUploadIDMarker = up.UploadID
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// findUploadIdMarkerIndex finds the index of given uploadId marker in uploads
|
||||||
|
// uploadIDMarker must match an upload-id among uploads with the first key after KeyMarker.
|
||||||
|
// Since caller filtered to Key > KeyMarker and the list is sorted by key/time,
|
||||||
|
// the first key after KeyMarker is Uploads[0].Key (if any).
|
||||||
|
// -1 is returned if no uploadId is found
|
||||||
|
func (l *MultipartUploadLister) findUploadIdMarkerIndex(uploadIDMarker string) int {
|
||||||
|
if len(l.Uploads) == 0 {
|
||||||
|
// key-marker provided but nothing after it => upload-id-marker can never be valid.
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
firstKey := l.Uploads[0].Key
|
||||||
|
|
||||||
|
// it must match an upload-id under firstKey only.
|
||||||
|
// If firstKey has multiple uploads, any of those IDs is valid.
|
||||||
|
for i, up := range l.Uploads {
|
||||||
|
if up.Key != firstKey {
|
||||||
|
// sorted by key, so we're past firstKey group
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if up.UploadID == uploadIDMarker {
|
||||||
|
// the listing should start from the next index
|
||||||
|
// to skip the uploadId marker
|
||||||
|
return i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasMoreAfter checks if there exists at least one more effective item after idx,
|
||||||
|
// considering delimiter collapse and already-emitted common prefixes.
|
||||||
|
func (l *MultipartUploadLister) hasMoreAfter(idx int, seenCP map[string]struct{}) bool {
|
||||||
|
if idx >= len(l.Uploads) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if l.Delimiter == "" {
|
||||||
|
// any remaining upload would be emitted
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := idx; i < len(l.Uploads); i++ {
|
||||||
|
up := l.Uploads[i]
|
||||||
|
suffix := strings.TrimPrefix(up.Key, l.Prefix)
|
||||||
|
before, _, found := strings.Cut(suffix, l.Delimiter)
|
||||||
|
if !found {
|
||||||
|
// would emit an upload
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
cpref := l.Prefix + before + l.Delimiter
|
||||||
|
if _, ok := seenCP[cpref]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// would emit a new common prefix
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ package integration
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -580,30 +579,6 @@ func ListMultipartUploads_delimiter_no_matches(s *S3Conf) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListMultipartUploads_with_upload_id(s *S3Conf) error {
|
|
||||||
testName := "ListMultipartUploads_with_upload_id"
|
|
||||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
||||||
out, err := createMp(s3client, bucket, "my-obj")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := createSignedReq(http.MethodGet, s.endpoint,
|
|
||||||
fmt.Sprintf("%v?uploads&uploadId=%v", bucket, *out.UploadId),
|
|
||||||
s.awsID, s.awsSecret, "s3", s.awsRegion, "", nil, time.Now(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.httpClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkHTTPResponseApiErr(resp, s3err.GetInvalidArgumentErr(s3err.InvalidArgUploadIdWithUploads, "uploadId"))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListMultipartUploads_with_checksums(s *S3Conf) error {
|
func ListMultipartUploads_with_checksums(s *S3Conf) error {
|
||||||
testName := "ListMultipartUploads_with_checksums"
|
testName := "ListMultipartUploads_with_checksums"
|
||||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||||
|
|||||||
@@ -110,8 +110,6 @@ func TestListBuckets(ts *TestState) {
|
|||||||
ts.Sync(ListBuckets_as_admin)
|
ts.Sync(ListBuckets_as_admin)
|
||||||
ts.Sync(ListBuckets_with_prefix)
|
ts.Sync(ListBuckets_with_prefix)
|
||||||
ts.Sync(ListBuckets_invalid_max_buckets)
|
ts.Sync(ListBuckets_invalid_max_buckets)
|
||||||
ts.Sync(ListBuckets_invalid_bucket_region)
|
|
||||||
ts.Sync(ListBuckets_bucket_region)
|
|
||||||
ts.Sync(ListBuckets_truncated)
|
ts.Sync(ListBuckets_truncated)
|
||||||
ts.Sync(ListBuckets_success)
|
ts.Sync(ListBuckets_success)
|
||||||
ts.Sync(ListBuckets_empty_success)
|
ts.Sync(ListBuckets_empty_success)
|
||||||
@@ -207,8 +205,6 @@ func TestPutObject(ts *TestState) {
|
|||||||
ts.Run(PutObject_with_metadata)
|
ts.Run(PutObject_with_metadata)
|
||||||
}
|
}
|
||||||
ts.Run(PutObject_success)
|
ts.Run(PutObject_success)
|
||||||
ts.Run(PutObject_sse_c_invalid_headers)
|
|
||||||
ts.Run(PutObject_unsupported_sse_not_implemented)
|
|
||||||
ts.Run(PutObject_default_content_type)
|
ts.Run(PutObject_default_content_type)
|
||||||
ts.Run(PutObject_overwrite_resets_attributes)
|
ts.Run(PutObject_overwrite_resets_attributes)
|
||||||
ts.Run(PutObject_overwrite_multipart_object)
|
ts.Run(PutObject_overwrite_multipart_object)
|
||||||
@@ -242,7 +238,6 @@ func TestHeadObject(ts *TestState) {
|
|||||||
ts.Run(HeadObject_ranged_with_checksum_mode)
|
ts.Run(HeadObject_ranged_with_checksum_mode)
|
||||||
}
|
}
|
||||||
ts.Run(HeadObject_success)
|
ts.Run(HeadObject_success)
|
||||||
ts.Run(HeadObject_sse_c_invalid_headers)
|
|
||||||
ts.Run(HeadObject_overrides_success)
|
ts.Run(HeadObject_overrides_success)
|
||||||
ts.Run(HeadObject_overrides_presign_success)
|
ts.Run(HeadObject_overrides_presign_success)
|
||||||
ts.Run(HeadObject_overrides_fail_public)
|
ts.Run(HeadObject_overrides_fail_public)
|
||||||
@@ -422,7 +417,6 @@ func TestCopyObject(ts *TestState) {
|
|||||||
}
|
}
|
||||||
ts.Run(CopyObject_with_special_characters)
|
ts.Run(CopyObject_with_special_characters)
|
||||||
ts.Run(CopyObject_success)
|
ts.Run(CopyObject_success)
|
||||||
ts.Run(CopyObject_sse_c_invalid_copy_source_headers)
|
|
||||||
ts.Run(CopyObject_cross_bucket_server_side_copy)
|
ts.Run(CopyObject_cross_bucket_server_side_copy)
|
||||||
ts.Run(CopyObject_incorrect_source_bucket_expected_owner)
|
ts.Run(CopyObject_incorrect_source_bucket_expected_owner)
|
||||||
}
|
}
|
||||||
@@ -548,17 +542,14 @@ func TestListMultipartUploads(ts *TestState) {
|
|||||||
ts.Run(ListMultipartUploads_empty_result)
|
ts.Run(ListMultipartUploads_empty_result)
|
||||||
ts.Run(ListMultipartUploads_invalid_max_uploads)
|
ts.Run(ListMultipartUploads_invalid_max_uploads)
|
||||||
ts.Run(ListMultipartUploads_max_uploads)
|
ts.Run(ListMultipartUploads_max_uploads)
|
||||||
ts.Run(ListMultipartUploads_next_markers_not_truncated)
|
|
||||||
ts.Run(ListMultipartUploads_exceeding_max_uploads)
|
ts.Run(ListMultipartUploads_exceeding_max_uploads)
|
||||||
ts.Run(ListMultipartUploads_ignore_upload_id_marker)
|
ts.Run(ListMultipartUploads_ignore_upload_id_marker)
|
||||||
ts.Run(ListMultipartUploads_invalid_uploadId_marker)
|
ts.Run(ListMultipartUploads_invalid_uploadId_marker)
|
||||||
ts.Run(ListMultipartUploads_keyMarker_not_from_list)
|
ts.Run(ListMultipartUploads_keyMarker_not_from_list)
|
||||||
ts.Run(ListMultipartUploads_upload_id_marker_with_key_marker)
|
|
||||||
ts.Run(ListMultipartUploads_delimiter_truncated)
|
ts.Run(ListMultipartUploads_delimiter_truncated)
|
||||||
ts.Run(ListMultipartUploads_prefix)
|
ts.Run(ListMultipartUploads_prefix)
|
||||||
ts.Run(ListMultipartUploads_both_delimiter_and_prefix)
|
ts.Run(ListMultipartUploads_both_delimiter_and_prefix)
|
||||||
ts.Run(ListMultipartUploads_delimiter_no_matches)
|
ts.Run(ListMultipartUploads_delimiter_no_matches)
|
||||||
ts.Run(ListMultipartUploads_with_upload_id)
|
|
||||||
//TODO: remove the condition after implementing checksums in azure
|
//TODO: remove the condition after implementing checksums in azure
|
||||||
if !ts.conf.azureTests {
|
if !ts.conf.azureTests {
|
||||||
ts.Run(ListMultipartUploads_with_checksums)
|
ts.Run(ListMultipartUploads_with_checksums)
|
||||||
@@ -912,28 +903,6 @@ func TestNotImplementedActions(ts *TestState) {
|
|||||||
ts.Run(GetObjectAcl_not_implemented)
|
ts.Run(GetObjectAcl_not_implemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestSSECNotImplemented is for backends that reject SSE-C rather than forward it.
|
|
||||||
func TestSSECNotImplemented(ts *TestState) {
|
|
||||||
ts.Run(PutObject_sse_c_not_implemented)
|
|
||||||
ts.Run(PostObject_sse_c_not_implemented)
|
|
||||||
ts.Run(GetObject_sse_c_not_implemented)
|
|
||||||
ts.Run(HeadObject_sse_c_not_implemented)
|
|
||||||
ts.Run(GetObjectAttributes_sse_c_not_implemented)
|
|
||||||
ts.Run(CopyObject_sse_c_not_implemented)
|
|
||||||
ts.Run(CreateMultipartUpload_sse_c_not_implemented)
|
|
||||||
ts.Run(UploadPart_sse_c_not_implemented)
|
|
||||||
ts.Run(UploadPartCopy_sse_c_not_implemented)
|
|
||||||
ts.Run(CompleteMultipartUpload_sse_c_not_implemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSSECTransport(ts *TestState) {
|
|
||||||
if ts.conf.tlsStatus {
|
|
||||||
TestSSECNotImplemented(ts)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ts.Run(PutObject_sse_c_requires_tls)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWORMProtection(ts *TestState) {
|
func TestWORMProtection(ts *TestState) {
|
||||||
ts.Run(WORMProtection_bucket_object_lock_configuration_compliance_mode)
|
ts.Run(WORMProtection_bucket_object_lock_configuration_compliance_mode)
|
||||||
ts.Run(WORMProtection_bucket_object_lock_configuration_governance_mode)
|
ts.Run(WORMProtection_bucket_object_lock_configuration_governance_mode)
|
||||||
@@ -1034,9 +1003,6 @@ func TestFullFlow(ts *TestState) {
|
|||||||
if ts.conf.versioningEnabled {
|
if ts.conf.versioningEnabled {
|
||||||
TestVersioning(ts)
|
TestVersioning(ts)
|
||||||
}
|
}
|
||||||
if ts.conf.azureTests {
|
|
||||||
TestSSECTransport(ts)
|
|
||||||
}
|
|
||||||
TestGatewayIAM(ts)
|
TestGatewayIAM(ts)
|
||||||
TestServer(ts)
|
TestServer(ts)
|
||||||
}
|
}
|
||||||
@@ -1067,7 +1033,6 @@ func TestPosix(ts *TestState) {
|
|||||||
if !ts.conf.versioningEnabled {
|
if !ts.conf.versioningEnabled {
|
||||||
TestVersioningDisabled(ts)
|
TestVersioningDisabled(ts)
|
||||||
}
|
}
|
||||||
TestSSECTransport(ts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScoutfs(ts *TestState) {
|
func TestScoutfs(ts *TestState) {
|
||||||
@@ -1169,7 +1134,6 @@ func TestScoutfs(ts *TestState) {
|
|||||||
ts.Run(ObjectTagging_trailing_slash_counterpart)
|
ts.Run(ObjectTagging_trailing_slash_counterpart)
|
||||||
ts.Run(ObjectLock_trailing_slash_counterpart)
|
ts.Run(ObjectLock_trailing_slash_counterpart)
|
||||||
ts.Run(DeleteObject_directory_not_empty)
|
ts.Run(DeleteObject_directory_not_empty)
|
||||||
TestSSECTransport(ts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGatewayIAM(ts *TestState) {
|
func TestGatewayIAM(ts *TestState) {
|
||||||
@@ -2195,11 +2159,9 @@ func TestRouter(ts *TestState) {
|
|||||||
ts.Run(RouterGetUploadsWithKey)
|
ts.Run(RouterGetUploadsWithKey)
|
||||||
ts.Run(RouterCopySourceNotAllowed)
|
ts.Run(RouterCopySourceNotAllowed)
|
||||||
ts.Run(RouterListVersionsWithKey)
|
ts.Run(RouterListVersionsWithKey)
|
||||||
ts.Run(RouterUploadsWithUploadId)
|
|
||||||
ts.Run(RouterObjectAnnotationNotImplemented)
|
ts.Run(RouterObjectAnnotationNotImplemented)
|
||||||
ts.Run(RouterRenameObjectNotImplemented)
|
ts.Run(RouterRenameObjectNotImplemented)
|
||||||
ts.Run(RouterObjectTorrentMethodNotAllowed)
|
ts.Run(RouterObjectTorrentMethodNotAllowed)
|
||||||
ts.Run(RouterInvalidURLEscape)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPostObject(ts *TestState) {
|
func TestPostObject(ts *TestState) {
|
||||||
@@ -2987,8 +2949,6 @@ func GetIntTests() IntTests {
|
|||||||
"ListBuckets_as_admin": ListBuckets_as_admin,
|
"ListBuckets_as_admin": ListBuckets_as_admin,
|
||||||
"ListBuckets_with_prefix": ListBuckets_with_prefix,
|
"ListBuckets_with_prefix": ListBuckets_with_prefix,
|
||||||
"ListBuckets_invalid_max_buckets": ListBuckets_invalid_max_buckets,
|
"ListBuckets_invalid_max_buckets": ListBuckets_invalid_max_buckets,
|
||||||
"ListBuckets_invalid_bucket_region": ListBuckets_invalid_bucket_region,
|
|
||||||
"ListBuckets_bucket_region": ListBuckets_bucket_region,
|
|
||||||
"ListBuckets_truncated": ListBuckets_truncated,
|
"ListBuckets_truncated": ListBuckets_truncated,
|
||||||
"ListBuckets_success": ListBuckets_success,
|
"ListBuckets_success": ListBuckets_success,
|
||||||
"ListBuckets_empty_success": ListBuckets_empty_success,
|
"ListBuckets_empty_success": ListBuckets_empty_success,
|
||||||
@@ -3290,16 +3250,13 @@ func GetIntTests() IntTests {
|
|||||||
"ListMultipartUploads_empty_result": ListMultipartUploads_empty_result,
|
"ListMultipartUploads_empty_result": ListMultipartUploads_empty_result,
|
||||||
"ListMultipartUploads_invalid_max_uploads": ListMultipartUploads_invalid_max_uploads,
|
"ListMultipartUploads_invalid_max_uploads": ListMultipartUploads_invalid_max_uploads,
|
||||||
"ListMultipartUploads_max_uploads": ListMultipartUploads_max_uploads,
|
"ListMultipartUploads_max_uploads": ListMultipartUploads_max_uploads,
|
||||||
"ListMultipartUploads_next_markers_not_truncated": ListMultipartUploads_next_markers_not_truncated,
|
|
||||||
"ListMultipartUploads_exceeding_max_uploads": ListMultipartUploads_exceeding_max_uploads,
|
"ListMultipartUploads_exceeding_max_uploads": ListMultipartUploads_exceeding_max_uploads,
|
||||||
"ListMultipartUploads_ignore_upload_id_marker": ListMultipartUploads_ignore_upload_id_marker,
|
"ListMultipartUploads_ignore_upload_id_marker": ListMultipartUploads_ignore_upload_id_marker,
|
||||||
"ListMultipartUploads_invalid_uploadId_marker": ListMultipartUploads_invalid_uploadId_marker,
|
"ListMultipartUploads_invalid_uploadId_marker": ListMultipartUploads_invalid_uploadId_marker,
|
||||||
"ListMultipartUploads_keyMarker_not_from_list": ListMultipartUploads_keyMarker_not_from_list,
|
"ListMultipartUploads_keyMarker_not_from_list": ListMultipartUploads_keyMarker_not_from_list,
|
||||||
"ListMultipartUploads_upload_id_marker_with_key_marker": ListMultipartUploads_upload_id_marker_with_key_marker,
|
|
||||||
"ListMultipartUploads_delimiter_truncated": ListMultipartUploads_delimiter_truncated,
|
"ListMultipartUploads_delimiter_truncated": ListMultipartUploads_delimiter_truncated,
|
||||||
"ListMultipartUploads_prefix": ListMultipartUploads_prefix,
|
"ListMultipartUploads_prefix": ListMultipartUploads_prefix,
|
||||||
"ListMultipartUploads_both_delimiter_and_prefix": ListMultipartUploads_both_delimiter_and_prefix,
|
"ListMultipartUploads_both_delimiter_and_prefix": ListMultipartUploads_both_delimiter_and_prefix,
|
||||||
"ListMultipartUploads_with_upload_id": ListMultipartUploads_with_upload_id,
|
|
||||||
"ListMultipartUploads_with_checksums": ListMultipartUploads_with_checksums,
|
"ListMultipartUploads_with_checksums": ListMultipartUploads_with_checksums,
|
||||||
"AbortMultipartUpload_non_existing_bucket": AbortMultipartUpload_non_existing_bucket,
|
"AbortMultipartUpload_non_existing_bucket": AbortMultipartUpload_non_existing_bucket,
|
||||||
"AbortMultipartUpload_incorrect_uploadId": AbortMultipartUpload_incorrect_uploadId,
|
"AbortMultipartUpload_incorrect_uploadId": AbortMultipartUpload_incorrect_uploadId,
|
||||||
@@ -3582,21 +3539,6 @@ func GetIntTests() IntTests {
|
|||||||
"PutObject_with_slashes": PutObject_with_slashes,
|
"PutObject_with_slashes": PutObject_with_slashes,
|
||||||
"PutObject_race_with_delete": PutObject_race_with_delete,
|
"PutObject_race_with_delete": PutObject_race_with_delete,
|
||||||
"CreateMultipartUpload_dir_obj": CreateMultipartUpload_dir_obj,
|
"CreateMultipartUpload_dir_obj": CreateMultipartUpload_dir_obj,
|
||||||
"PutObject_sse_c_not_implemented": PutObject_sse_c_not_implemented,
|
|
||||||
"PutObject_unsupported_sse_not_implemented": PutObject_unsupported_sse_not_implemented,
|
|
||||||
"PutObject_sse_c_requires_tls": PutObject_sse_c_requires_tls,
|
|
||||||
"PostObject_sse_c_not_implemented": PostObject_sse_c_not_implemented,
|
|
||||||
"GetObject_sse_c_not_implemented": GetObject_sse_c_not_implemented,
|
|
||||||
"HeadObject_sse_c_not_implemented": HeadObject_sse_c_not_implemented,
|
|
||||||
"GetObjectAttributes_sse_c_not_implemented": GetObjectAttributes_sse_c_not_implemented,
|
|
||||||
"CopyObject_sse_c_not_implemented": CopyObject_sse_c_not_implemented,
|
|
||||||
"CreateMultipartUpload_sse_c_not_implemented": CreateMultipartUpload_sse_c_not_implemented,
|
|
||||||
"UploadPart_sse_c_not_implemented": UploadPart_sse_c_not_implemented,
|
|
||||||
"UploadPartCopy_sse_c_not_implemented": UploadPartCopy_sse_c_not_implemented,
|
|
||||||
"CompleteMultipartUpload_sse_c_not_implemented": CompleteMultipartUpload_sse_c_not_implemented,
|
|
||||||
"PutObject_sse_c_invalid_headers": PutObject_sse_c_invalid_headers,
|
|
||||||
"HeadObject_sse_c_invalid_headers": HeadObject_sse_c_invalid_headers,
|
|
||||||
"CopyObject_sse_c_invalid_copy_source_headers": CopyObject_sse_c_invalid_copy_source_headers,
|
|
||||||
"IAM_user_access_denied": IAM_user_access_denied,
|
"IAM_user_access_denied": IAM_user_access_denied,
|
||||||
"IAM_userplus_access_denied": IAM_userplus_access_denied,
|
"IAM_userplus_access_denied": IAM_userplus_access_denied,
|
||||||
"IAM_userplus_CreateBucket": IAM_userplus_CreateBucket,
|
"IAM_userplus_CreateBucket": IAM_userplus_CreateBucket,
|
||||||
@@ -3804,11 +3746,9 @@ func GetIntTests() IntTests {
|
|||||||
"RouterGetUploadsWithKey": RouterGetUploadsWithKey,
|
"RouterGetUploadsWithKey": RouterGetUploadsWithKey,
|
||||||
"RouterCopySourceNotAllowed": RouterCopySourceNotAllowed,
|
"RouterCopySourceNotAllowed": RouterCopySourceNotAllowed,
|
||||||
"RouterListVersionsWithKey": RouterListVersionsWithKey,
|
"RouterListVersionsWithKey": RouterListVersionsWithKey,
|
||||||
"RouterUploadsWithUploadId": RouterUploadsWithUploadId,
|
|
||||||
"RouterObjectAnnotationNotImplemented": RouterObjectAnnotationNotImplemented,
|
"RouterObjectAnnotationNotImplemented": RouterObjectAnnotationNotImplemented,
|
||||||
"RouterRenameObjectNotImplemented": RouterRenameObjectNotImplemented,
|
"RouterRenameObjectNotImplemented": RouterRenameObjectNotImplemented,
|
||||||
"RouterObjectTorrentMethodNotAllowed": RouterObjectTorrentMethodNotAllowed,
|
"RouterObjectTorrentMethodNotAllowed": RouterObjectTorrentMethodNotAllowed,
|
||||||
"RouterInvalidURLEscape": RouterInvalidURLEscape,
|
|
||||||
"UnsignedStreaminPayloadTrailer_malformed_trailer": UnsignedStreaminPayloadTrailer_malformed_trailer,
|
"UnsignedStreaminPayloadTrailer_malformed_trailer": UnsignedStreaminPayloadTrailer_malformed_trailer,
|
||||||
"UnsignedStreamingPayloadTrailer_aborted_connection": UnsignedStreamingPayloadTrailer_aborted_connection,
|
"UnsignedStreamingPayloadTrailer_aborted_connection": UnsignedStreamingPayloadTrailer_aborted_connection,
|
||||||
"UnsignedStreamingPayloadTrailer_missing_invalid_dec_content_length": UnsignedStreamingPayloadTrailer_missing_invalid_dec_content_length,
|
"UnsignedStreamingPayloadTrailer_missing_invalid_dec_content_length": UnsignedStreamingPayloadTrailer_missing_invalid_dec_content_length,
|
||||||
|
|||||||
@@ -215,6 +215,9 @@ source ./tests/setup.sh
|
|||||||
|
|
||||||
# tags: curl,ListMultipartUploads,multipart,uploadId,invalid-query
|
# tags: curl,ListMultipartUploads,multipart,uploadId,invalid-query
|
||||||
@test "REST - ListMultipartUploads - uploads/uploadId combo" {
|
@test "REST - ListMultipartUploads - uploads/uploadId combo" {
|
||||||
|
if [ "$DIRECT" != "true" ]; then
|
||||||
|
skip "https://github.com/versity/versitygw/issues/2155"
|
||||||
|
fi
|
||||||
run setup_bucket_and_file_v3 "$BUCKET_ONE_NAME"
|
run setup_bucket_and_file_v3 "$BUCKET_ONE_NAME"
|
||||||
assert_success
|
assert_success
|
||||||
read -r bucket_name test_file <<< "$output"
|
read -r bucket_name test_file <<< "$output"
|
||||||
|
|||||||
Reference in new issue
Block a user