mirror of
https://github.com/pgsty/minio.git
synced 2026-09-26 04:45:59 +03:00
0c61128d23
(cherry picked from commit cf381a7151ef25fc95ace5fedcd767fa19410de2) Signed-off-by: Feng Ruohang <rh@vonng.com>
69 lines
3.8 KiB
Plaintext
69 lines
3.8 KiB
Plaintext
package cmd
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"sync/atomic"
|
|
"testing"
|
|
"github.com/minio/minio-go/v7"
|
|
"github.com/minio/minio/internal/bucket/replication"
|
|
xhttp "github.com/minio/minio/internal/http"
|
|
)
|
|
func TestReviewR6LegacyPurgeRetries(t *testing.T) {
|
|
var deletes atomic.Int32
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == http.MethodHead {
|
|
w.Header().Set(xhttp.AmzDeleteMarker, "true")
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
deletes.Add(1)
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}))
|
|
defer server.Close()
|
|
client, err := minio.New(strings.TrimPrefix(server.URL, "http://"), &minio.Options{Region: "us-east-1", MaxRetries: 1})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
old := globalBucketTargetSys
|
|
globalBucketTargetSys = &BucketTargetSys{hc: map[string]epHealth{client.EndpointURL().Host: {Online: true}}}
|
|
defer func() { globalBucketTargetSys = old }()
|
|
d := DeletedObjectReplicationInfo{Bucket: "source", DeletedObject: DeletedObject{ObjectName: "marker", DeleteMarker: true, DeleteMarkerVersionID: mustGetUUID()}}
|
|
d.ReplicationState.Targets = map[string]replication.StatusType{"arn1": replication.Completed}
|
|
d.ReplicationState.PurgeTargets = map[string]VersionPurgeStatusType{"arn1": replication.VersionPurgePending}
|
|
result := replicateDeleteToTarget(t.Context(), d, &TargetClient{Client: client, ARN: "arn1", Bucket: "target"})
|
|
t.Logf("remote DELETE calls=%d, creation=%s, purge=%s", deletes.Load(), result.ReplicationStatus, result.VersionPurgeStatus)
|
|
if deletes.Load() != 1 || result.VersionPurgeStatus != replication.VersionPurgeComplete {
|
|
t.Error("pending legacy purge was not delivered")
|
|
}
|
|
}
|
|
|
|
|
|
func TestReviewR6PurgeExits(t *testing.T) {
|
|
for _, tc := range []struct{name string; creation replication.StatusType; purge VersionPurgeStatusType; head int; existing bool; want VersionPurgeStatusType; wantCalls int; wantReset bool}{
|
|
{"head_forbidden", replication.Pending, replication.VersionPurgePending, 403, false, replication.VersionPurgeFailed, 1, false},
|
|
{"failed_resync", replication.Completed, replication.VersionPurgePending, 405, true, replication.VersionPurgeFailed, 2, false},
|
|
{"already_purged", replication.Pending, replication.VersionPurgeComplete, 405, false, replication.VersionPurgeComplete, 0, false},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T){
|
|
var calls atomic.Int32
|
|
server:=httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){
|
|
calls.Add(1)
|
|
if r.Method==http.MethodHead {w.Header().Set(xhttp.AmzDeleteMarker,"true"); w.WriteHeader(tc.head);return}
|
|
w.WriteHeader(403);fmt.Fprint(w,`<Error><Code>AccessDenied</Code></Error>`)
|
|
}))
|
|
defer server.Close()
|
|
client,err:=minio.New(strings.TrimPrefix(server.URL,"http://"),&minio.Options{Region:"us-east-1",MaxRetries:1});if err!=nil{t.Fatal(err)}
|
|
old:=globalBucketTargetSys;globalBucketTargetSys=&BucketTargetSys{hc:map[string]epHealth{client.EndpointURL().Host:{Online:true}}};defer func(){globalBucketTargetSys=old}()
|
|
d:=DeletedObjectReplicationInfo{Bucket:"source",DeletedObject:DeletedObject{ObjectName:"marker",DeleteMarker:true,DeleteMarkerVersionID:mustGetUUID()}}
|
|
d.ReplicationState.Targets=map[string]replication.StatusType{"arn1":tc.creation}
|
|
d.ReplicationState.PurgeTargets=map[string]VersionPurgeStatusType{"arn1":tc.purge}
|
|
if tc.existing {d.OpType=replication.ExistingObjectReplicationType}
|
|
got:=replicateDeleteToTarget(t.Context(),d,&TargetClient{Client:client,ARN:"arn1",Bucket:"target",ResetID:"new-reset"})
|
|
t.Logf("calls=%d, creation=%s, purge=%s, reset=%q",calls.Load(),got.ReplicationStatus,got.VersionPurgeStatus,got.ResyncTimestamp)
|
|
if got.ReplicationStatus!=tc.creation || got.VersionPurgeStatus!=tc.want || int(calls.Load())!=tc.wantCalls || (got.ResyncTimestamp!="")!=tc.wantReset {t.Errorf("operation classified inconsistently: %+v",got)}
|
|
})
|
|
}
|
|
}
|