github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/admin-handlers-users-race_test.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  //go:build !race
    19  // +build !race
    20  
    21  // Tests in this file are not run under the `-race` flag as they are too slow
    22  // and cause context deadline errors.
    23  
    24  package cmd
    25  
    26  import (
    27  	"context"
    28  	"fmt"
    29  	"runtime"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/minio/madmin-go/v3"
    34  	minio "github.com/minio/minio-go/v7"
    35  	"github.com/minio/pkg/v2/sync/errgroup"
    36  )
    37  
    38  func runAllIAMConcurrencyTests(suite *TestSuiteIAM, c *check) {
    39  	suite.SetUpSuite(c)
    40  	suite.TestDeleteUserRace(c)
    41  	suite.TearDownSuite(c)
    42  }
    43  
    44  func TestIAMInternalIDPConcurrencyServerSuite(t *testing.T) {
    45  	if runtime.GOOS == globalWindowsOSName {
    46  		t.Skip("windows is clunky")
    47  	}
    48  
    49  	baseTestCases := []TestSuiteCommon{
    50  		// Init and run test on ErasureSD backend with signature v4.
    51  		{serverType: "ErasureSD", signer: signerV4},
    52  		// Init and run test on ErasureSD backend, with tls enabled.
    53  		{serverType: "ErasureSD", signer: signerV4, secure: true},
    54  		// Init and run test on Erasure backend.
    55  		{serverType: "Erasure", signer: signerV4},
    56  		// Init and run test on ErasureSet backend.
    57  		{serverType: "ErasureSet", signer: signerV4},
    58  	}
    59  	testCases := []*TestSuiteIAM{}
    60  	for _, bt := range baseTestCases {
    61  		testCases = append(testCases,
    62  			newTestSuiteIAM(bt, false),
    63  			newTestSuiteIAM(bt, true),
    64  		)
    65  	}
    66  	for i, testCase := range testCases {
    67  		etcdStr := ""
    68  		if testCase.withEtcdBackend {
    69  			etcdStr = " (with etcd backend)"
    70  		}
    71  		t.Run(
    72  			fmt.Sprintf("Test: %d, ServerType: %s%s", i+1, testCase.serverType, etcdStr),
    73  			func(t *testing.T) {
    74  				runAllIAMConcurrencyTests(testCase, &check{t, testCase.serverType})
    75  			},
    76  		)
    77  	}
    78  }
    79  
    80  func (s *TestSuiteIAM) TestDeleteUserRace(c *check) {
    81  	ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second)
    82  	defer cancel()
    83  
    84  	bucket := getRandomBucketName()
    85  	err := s.client.MakeBucket(ctx, bucket, minio.MakeBucketOptions{})
    86  	if err != nil {
    87  		c.Fatalf("bucket creat error: %v", err)
    88  	}
    89  
    90  	// Create a policy policy
    91  	policy := "mypolicy"
    92  	policyBytes := []byte(fmt.Sprintf(`{
    93   "Version": "2012-10-17",
    94   "Statement": [
    95    {
    96     "Effect": "Allow",
    97     "Action": [
    98      "s3:PutObject",
    99      "s3:GetObject",
   100      "s3:ListBucket"
   101     ],
   102     "Resource": [
   103      "arn:aws:s3:::%s/*"
   104     ]
   105    }
   106   ]
   107  }`, bucket))
   108  	err = s.adm.AddCannedPolicy(ctx, policy, policyBytes)
   109  	if err != nil {
   110  		c.Fatalf("policy add error: %v", err)
   111  	}
   112  
   113  	userCount := 50
   114  	accessKeys := make([]string, userCount)
   115  	secretKeys := make([]string, userCount)
   116  	for i := 0; i < userCount; i++ {
   117  		accessKey, secretKey := mustGenerateCredentials(c)
   118  		err = s.adm.SetUser(ctx, accessKey, secretKey, madmin.AccountEnabled)
   119  		if err != nil {
   120  			c.Fatalf("Unable to set user: %v", err)
   121  		}
   122  
   123  		err = s.adm.SetPolicy(ctx, policy, accessKey, false)
   124  		if err != nil {
   125  			c.Fatalf("Unable to set policy: %v", err)
   126  		}
   127  
   128  		accessKeys[i] = accessKey
   129  		secretKeys[i] = secretKey
   130  	}
   131  
   132  	g := errgroup.Group{}
   133  	for i := 0; i < userCount; i++ {
   134  		g.Go(func(i int) func() error {
   135  			return func() error {
   136  				uClient := s.getUserClient(c, accessKeys[i], secretKeys[i], "")
   137  				err := s.adm.RemoveUser(ctx, accessKeys[i])
   138  				if err != nil {
   139  					return err
   140  				}
   141  				c.mustNotListObjects(ctx, uClient, bucket)
   142  				return nil
   143  			}
   144  		}(i), i)
   145  	}
   146  	if errs := g.Wait(); len(errs) > 0 {
   147  		c.Fatalf("unable to remove users: %v", errs)
   148  	}
   149  }