123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- package s3api
- import (
- "encoding/json"
- "fmt"
- "github.com/aws/aws-sdk-go/service/s3"
- "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
- "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
- "github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
- "github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
- "reflect"
- "sync"
- "testing"
- "time"
- )
- type BucketMetadataTestCase struct {
- filerEntry *filer_pb.Entry
- expectBucketMetadata *BucketMetaData
- }
- var (
- //bad entry
- badEntry = &filer_pb.Entry{
- Name: "badEntry",
- }
- //good entry
- goodEntryAcl, _ = json.Marshal(s3_constants.PublicRead)
- goodEntry = &filer_pb.Entry{
- Name: "entryWithValidAcp",
- Extended: map[string][]byte{
- s3_constants.ExtOwnershipKey: []byte(s3_constants.OwnershipBucketOwnerEnforced),
- s3_constants.ExtAmzOwnerKey: []byte(AccountAdmin.DisplayName),
- s3_constants.ExtAmzAclKey: goodEntryAcl,
- },
- }
- //ownership is ""
- ownershipEmptyStr = &filer_pb.Entry{
- Name: "ownershipEmptyStr",
- Extended: map[string][]byte{
- s3_constants.ExtOwnershipKey: []byte(""),
- },
- }
- //ownership valid
- ownershipValid = &filer_pb.Entry{
- Name: "ownershipValid",
- Extended: map[string][]byte{
- s3_constants.ExtOwnershipKey: []byte(s3_constants.OwnershipBucketOwnerEnforced),
- },
- }
- //owner is ""
- acpEmptyStr = &filer_pb.Entry{
- Name: "acpEmptyStr",
- Extended: map[string][]byte{
- s3_constants.ExtAmzOwnerKey: []byte(""),
- },
- }
- //owner not exists
- acpEmptyObject = &filer_pb.Entry{
- Name: "acpEmptyObject",
- Extended: map[string][]byte{
- s3_constants.ExtAmzOwnerKey: []byte("xxxxx"),
- },
- }
- //grants is nil
- acpOwnerNilAcp, _ = json.Marshal(make([]*s3.Grant, 0))
- acpOwnerNil = &filer_pb.Entry{
- Name: "acpOwnerNil",
- Extended: map[string][]byte{
- s3_constants.ExtAmzAclKey: acpOwnerNilAcp,
- },
- }
- //load filer is
- loadFilerBucket = make(map[string]int, 1)
- //override `loadBucketMetadataFromFiler` to avoid really load from filer
- )
- var tcs = []*BucketMetadataTestCase{
- {
- badEntry, &BucketMetaData{
- Name: badEntry.Name,
- ObjectOwnership: s3_constants.DefaultOwnershipForExists,
- Owner: &s3.Owner{
- DisplayName: &AccountAdmin.DisplayName,
- ID: &AccountAdmin.Id,
- },
- Acl: nil,
- },
- },
- {
- goodEntry, &BucketMetaData{
- Name: goodEntry.Name,
- ObjectOwnership: s3_constants.OwnershipBucketOwnerEnforced,
- Owner: &s3.Owner{
- DisplayName: &AccountAdmin.DisplayName,
- ID: &AccountAdmin.Id,
- },
- Acl: s3_constants.PublicRead,
- },
- },
- {
- ownershipEmptyStr, &BucketMetaData{
- Name: ownershipEmptyStr.Name,
- ObjectOwnership: s3_constants.DefaultOwnershipForExists,
- Owner: &s3.Owner{
- DisplayName: &AccountAdmin.DisplayName,
- ID: &AccountAdmin.Id,
- },
- Acl: nil,
- },
- },
- {
- ownershipValid, &BucketMetaData{
- Name: ownershipValid.Name,
- ObjectOwnership: s3_constants.OwnershipBucketOwnerEnforced,
- Owner: &s3.Owner{
- DisplayName: &AccountAdmin.DisplayName,
- ID: &AccountAdmin.Id,
- },
- Acl: nil,
- },
- },
- {
- acpEmptyStr, &BucketMetaData{
- Name: acpEmptyStr.Name,
- ObjectOwnership: s3_constants.DefaultOwnershipForExists,
- Owner: &s3.Owner{
- DisplayName: &AccountAdmin.DisplayName,
- ID: &AccountAdmin.Id,
- },
- Acl: nil,
- },
- },
- {
- acpEmptyObject, &BucketMetaData{
- Name: acpEmptyObject.Name,
- ObjectOwnership: s3_constants.DefaultOwnershipForExists,
- Owner: &s3.Owner{
- DisplayName: &AccountAdmin.DisplayName,
- ID: &AccountAdmin.Id,
- },
- Acl: nil,
- },
- },
- {
- acpOwnerNil, &BucketMetaData{
- Name: acpOwnerNil.Name,
- ObjectOwnership: s3_constants.DefaultOwnershipForExists,
- Owner: &s3.Owner{
- DisplayName: &AccountAdmin.DisplayName,
- ID: &AccountAdmin.Id,
- },
- Acl: make([]*s3.Grant, 0),
- },
- },
- }
- func TestBuildBucketMetadata(t *testing.T) {
- iam := &IdentityAccessManagement{}
- _ = iam.loadS3ApiConfiguration(&iam_pb.S3ApiConfiguration{})
- for _, tc := range tcs {
- resultBucketMetadata := buildBucketMetadata(iam, tc.filerEntry)
- if !reflect.DeepEqual(resultBucketMetadata, tc.expectBucketMetadata) {
- t.Fatalf("result is unexpect: \nresult: %v, \nexpect: %v", resultBucketMetadata, tc.expectBucketMetadata)
- }
- }
- }
- func TestGetBucketMetadata(t *testing.T) {
- loadBucketMetadataFromFiler = func(r *BucketRegistry, bucketName string) (*BucketMetaData, error) {
- time.Sleep(time.Second)
- loadFilerBucket[bucketName] = loadFilerBucket[bucketName] + 1
- return &BucketMetaData{
- Name: bucketName,
- }, nil
- }
- br := &BucketRegistry{
- metadataCache: make(map[string]*BucketMetaData),
- notFound: make(map[string]struct{}),
- s3a: nil,
- }
- //start 40 goroutine for
- var wg sync.WaitGroup
- closeCh := make(chan struct{})
- for i := 0; i < 40; i++ {
- wg.Add(1)
- go func() {
- defer wg.Done()
- outLoop:
- for {
- for j := 0; j < 5; j++ {
- select {
- case <-closeCh:
- break outLoop
- default:
- reqBucket := fmt.Sprintf("%c", 67+j)
- _, errCode := br.GetBucketMetadata(reqBucket)
- if errCode != s3err.ErrNone {
- close(closeCh)
- t.Error("not expect")
- }
- }
- }
- time.Sleep(10 * time.Microsecond)
- }
- }()
- }
- time.Sleep(time.Second)
- close(closeCh)
- wg.Wait()
- //Each bucket is loaded from the filer only once
- for bucketName, loadCount := range loadFilerBucket {
- if loadCount != 1 {
- t.Fatalf("lock is uneffict: %s, %d", bucketName, loadCount)
- }
- }
- }
|