tests: Add context cancelation (#15374)

A huge number of goroutines would build up from various monitors

When creating test filesystems provide a context so they can shut down when no longer needed.
This commit is contained in:
Klaus Post 2022-07-21 11:52:18 -07:00 committed by GitHub
parent cab8d3d568
commit 1e332f0eb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 136 additions and 69 deletions

View File

@ -74,7 +74,7 @@ func prepareAdminErasureTestBed(ctx context.Context) (*adminErasureTestBed, erro
globalEndpoints = mustGetPoolEndpoints(erasureDirs...)
initAllSubsystems()
initAllSubsystems(ctx)
initConfigSubsystem(ctx, objLayer)

View File

@ -100,14 +100,14 @@ type allHealState struct {
}
// newHealState - initialize global heal state management
func newHealState(cleanup bool) *allHealState {
func newHealState(ctx context.Context, cleanup bool) *allHealState {
hstate := &allHealState{
healSeqMap: make(map[string]*healSequence),
healLocalDisks: make(map[Endpoint]bool),
healStatus: make(map[string]healingTracker),
}
if cleanup {
go hstate.periodicHealSeqsClean(GlobalContext)
go hstate.periodicHealSeqsClean(ctx)
}
return hstate
}

View File

@ -360,7 +360,10 @@ func mustNewSignedBadMD5Request(method string, urlStr string, contentLength int6
// Tests is requested authenticated function, tests replies for s3 errors.
func TestIsReqAuthenticated(t *testing.T) {
objLayer, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(GlobalContext)
defer cancel()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -369,10 +372,7 @@ func TestIsReqAuthenticated(t *testing.T) {
t.Fatalf("unable initialize config file, %s", err)
}
initAllSubsystems()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
initAllSubsystems(ctx)
initConfigSubsystem(ctx, objLayer)
@ -414,7 +414,10 @@ func TestIsReqAuthenticated(t *testing.T) {
}
func TestCheckAdminRequestAuthType(t *testing.T) {
objLayer, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -440,7 +443,6 @@ func TestCheckAdminRequestAuthType(t *testing.T) {
{Request: mustNewPresignedV2Request(http.MethodGet, "http://127.0.0.1:9000", 0, nil, t), ErrCode: ErrAccessDenied},
{Request: mustNewPresignedRequest(http.MethodGet, "http://127.0.0.1:9000", 0, nil, t), ErrCode: ErrAccessDenied},
}
ctx := context.Background()
for i, testCase := range testCases {
if _, s3Error := checkAdminRequestAuth(ctx, testCase.Request, iampolicy.AllAdminActions, globalSite.Region); s3Error != testCase.ErrCode {
t.Errorf("Test %d: Unexpected s3error returned wanted %d, got %d", i, testCase.ErrCode, s3Error)
@ -452,7 +454,7 @@ func TestValidateAdminSignature(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
objLayer, fsDir, err := prepareFS()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -462,8 +464,7 @@ func TestValidateAdminSignature(t *testing.T) {
t.Fatalf("unable initialize config file, %s", err)
}
initAllSubsystems()
initAllSubsystems(ctx)
initConfigSubsystem(ctx, objLayer)
globalIAMSys.Init(ctx, objLayer, globalEtcdClient, 2*time.Second)

View File

@ -26,7 +26,10 @@ import (
)
func TestServerConfig(t *testing.T) {
objLayer, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}

View File

@ -18,6 +18,7 @@
package cmd
import (
"context"
"fmt"
"io/ioutil"
"os"
@ -28,7 +29,10 @@ import (
// Test if config v1 is purged
func TestServerConfigMigrateV1(t *testing.T) {
objLayer, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -164,6 +168,9 @@ func TestServerConfigMigrateInexistentConfig(t *testing.T) {
// Test if a config migration from v2 to v33 is successfully done
func TestServerConfigMigrateV2toV33(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
rootPath, err := ioutil.TempDir(globalTestTmpDir, "minio-")
if err != nil {
t.Fatal(err)
@ -172,7 +179,7 @@ func TestServerConfigMigrateV2toV33(t *testing.T) {
globalConfigDir = &ConfigDir{path: rootPath}
objLayer, fsDir, err := prepareFS()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}

View File

@ -130,7 +130,6 @@ func TestDynamicTimeoutConcurrent(t *testing.T) {
go func() {
defer wg.Done()
for i := 0; i < 100; i++ {
timeout.LogFailure()
for j := 0; j < 100; j++ {
timeout.LogSuccess(time.Duration(float64(time.Second) * rng.Float64()))
}

View File

@ -118,8 +118,7 @@ func initMetaVolumeFS(fsPath, fsUUID string) error {
}
// NewFSObjectLayer - initialize new fs object layer.
func NewFSObjectLayer(fsPath string) (ObjectLayer, error) {
ctx := GlobalContext
func NewFSObjectLayer(ctx context.Context, fsPath string) (ObjectLayer, error) {
if fsPath == "" {
return nil, errInvalidArgument
}

View File

@ -19,6 +19,7 @@ package cmd
import (
"bytes"
"context"
"os"
"path/filepath"
"testing"
@ -29,17 +30,19 @@ import (
// TestNewFS - tests initialization of all input disks
// and constructs a valid `FS` object layer.
func TestNewFS(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Do not attempt to create this path, the test validates
// so that NewFSObjectLayer initializes non existing paths
// and successfully returns initialized object layer.
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer os.RemoveAll(disk)
_, err := NewFSObjectLayer("")
_, err := NewFSObjectLayer(ctx, "")
if err != errInvalidArgument {
t.Errorf("Expecting error invalid argument, got %s", err)
}
_, err = NewFSObjectLayer(disk)
_, err = NewFSObjectLayer(ctx, disk)
if err != nil {
errMsg := "Unable to recognize backend format, Disk is not in FS format."
if err.Error() == errMsg {

View File

@ -300,7 +300,7 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
newObject = NewGatewayLayerWithLocker(newObject)
// Calls all New() for all sub-systems.
initAllSubsystems()
initAllSubsystems(GlobalContext)
// Once endpoints are finalized, initialize the new object api in safe mode.
globalObjLayerMutex.Lock()

View File

@ -18,13 +18,17 @@
package cmd
import (
"context"
"os"
"testing"
)
// Test printing Gateway common message.
func TestPrintGatewayCommonMessage(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -39,7 +43,10 @@ func TestPrintGatewayCommonMessage(t *testing.T) {
// Test print gateway startup message.
func TestPrintGatewayStartupMessage(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}

View File

@ -87,7 +87,7 @@ func (g *NAS) Name() string {
// NewGatewayLayer returns nas gatewaylayer.
func (g *NAS) NewGatewayLayer(creds madmin.Credentials) (minio.ObjectLayer, error) {
var err error
newObject, err := minio.NewFSObjectLayer(g.path)
newObject, err := minio.NewFSObjectLayer(minio.GlobalContext, g.path)
if err != nil {
return nil, err
}

View File

@ -34,7 +34,10 @@ import (
// Tests validate bucket LocationConstraint.
func TestIsValidLocationContraint(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}

View File

@ -18,6 +18,7 @@
package cmd
import (
"context"
"net/http"
"os"
"testing"
@ -29,7 +30,10 @@ import (
)
func testAuthenticate(authType string, t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -103,7 +107,10 @@ func getTokenString(accessKey, secretKey string) (string, error) {
// Tests web request authenticator.
func TestWebRequestAuthenticate(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -157,7 +164,10 @@ func TestWebRequestAuthenticate(t *testing.T) {
}
func BenchmarkParseJWTStandardClaims(b *testing.B) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
b.Fatal(err)
}
@ -185,7 +195,10 @@ func BenchmarkParseJWTStandardClaims(b *testing.B) {
}
func BenchmarkParseJWTMapClaims(b *testing.B) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
b.Fatal(err)
}
@ -215,7 +228,10 @@ func BenchmarkParseJWTMapClaims(b *testing.B) {
}
func BenchmarkAuthenticateNode(b *testing.B) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
b.Fatal(err)
}
@ -244,7 +260,10 @@ func BenchmarkAuthenticateNode(b *testing.B) {
}
func BenchmarkAuthenticateWeb(b *testing.B) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
b.Fatal(err)
}

View File

@ -18,6 +18,7 @@
package cmd
import (
"context"
"os"
"reflect"
"sync"
@ -27,8 +28,8 @@ import (
)
// Helper function to create a lock server for testing
func createLockTestServer(t *testing.T) (string, *lockRESTServer, string) {
obj, fsDir, err := prepareFS()
func createLockTestServer(ctx context.Context, t *testing.T) (string, *lockRESTServer, string) {
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -52,7 +53,10 @@ func createLockTestServer(t *testing.T) (string, *lockRESTServer, string) {
// Test function to remove lock entries from map based on name & uid combination
func TestLockRpcServerRemoveEntry(t *testing.T) {
testPath, locker, _ := createLockTestServer(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
testPath, locker, _ := createLockTestServer(ctx, t)
defer os.RemoveAll(testPath)
lockRequesterInfo1 := lockRequesterInfo{

View File

@ -1879,7 +1879,7 @@ func initFSObjectsB(disk string, t *testing.B) (obj ObjectLayer) {
newTestConfig(globalMinioDefaultRegion, obj)
initAllSubsystems()
initAllSubsystems(GlobalContext)
return obj
}

View File

@ -37,7 +37,7 @@ import (
"sync"
"testing"
humanize "github.com/dustin/go-humanize"
"github.com/dustin/go-humanize"
"github.com/minio/minio/internal/auth"
xhttp "github.com/minio/minio/internal/http"
ioutilx "github.com/minio/minio/internal/ioutil"

View File

@ -35,7 +35,7 @@ import (
"time"
"github.com/minio/cli"
minio "github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio/internal/auth"
"github.com/minio/minio/internal/bucket/bandwidth"
@ -242,11 +242,11 @@ func serverHandleEnvVars() {
var globalHealStateLK sync.RWMutex
func initAllSubsystems() {
func initAllSubsystems(ctx context.Context) {
globalHealStateLK.Lock()
// New global heal state
globalAllHealState = newHealState(true)
globalBackgroundHealState = newHealState(false)
globalAllHealState = newHealState(ctx, true)
globalBackgroundHealState = newHealState(ctx, false)
globalHealStateLK.Unlock()
// Create new notification system and initialize notification peer targets
@ -261,7 +261,7 @@ func initAllSubsystems() {
}
// Create the bucket bandwidth monitor
globalBucketMonitor = bandwidth.NewMonitor(GlobalContext, totalNodeCount())
globalBucketMonitor = bandwidth.NewMonitor(ctx, totalNodeCount())
// Create a new config system.
globalConfigSys = NewConfigSys()
@ -448,7 +448,7 @@ func serverMain(ctx *cli.Context) {
initHelp()
// Initialize all sub-systems
initAllSubsystems()
initAllSubsystems(GlobalContext)
// Is distributed setup, error out if no certificates are found for HTTPS endpoints.
if globalIsDistErasure {
@ -682,7 +682,7 @@ func newObjectLayer(ctx context.Context, endpointServerPools EndpointServerPools
// For FS only, directly use the disk.
if endpointServerPools.NEndpoints() == 1 {
// Initialize new FS object layer.
newObject, err = NewFSObjectLayer(endpointServerPools[0].Endpoints[0].Path)
newObject, err = NewFSObjectLayer(ctx, endpointServerPools[0].Endpoints[0].Path)
if err == nil {
return newObject, nil
}

View File

@ -18,6 +18,7 @@
package cmd
import (
"context"
"os"
"reflect"
"strings"
@ -71,7 +72,10 @@ func TestStripStandardPorts(t *testing.T) {
// Test printing server common message.
func TestPrintServerCommonMessage(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -86,7 +90,10 @@ func TestPrintServerCommonMessage(t *testing.T) {
// Tests print cli access message.
func TestPrintCLIAccessMsg(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -101,7 +108,10 @@ func TestPrintCLIAccessMsg(t *testing.T) {
// Test print startup message.
func TestPrintStartupMessage(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}

View File

@ -18,6 +18,7 @@
package cmd
import (
"context"
"fmt"
"net/http"
"net/url"
@ -41,7 +42,10 @@ func TestResourceListSorting(t *testing.T) {
// Tests presigned v2 signature.
func TestDoesPresignedV2SignatureMatch(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -161,7 +165,10 @@ func TestDoesPresignedV2SignatureMatch(t *testing.T) {
// TestValidateV2AuthHeader - Tests validate the logic of V2 Authorization header validator.
func TestValidateV2AuthHeader(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -232,7 +239,10 @@ func TestValidateV2AuthHeader(t *testing.T) {
}
func TestDoesPolicySignatureV2Match(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}

View File

@ -33,7 +33,7 @@ func TestCheckValid(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
objLayer, fsDir, err := prepareFS()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}
@ -42,8 +42,7 @@ func TestCheckValid(t *testing.T) {
t.Fatalf("unable initialize config file, %s", err)
}
initAllSubsystems()
initAllSubsystems(ctx)
initConfigSubsystem(ctx, objLayer)
globalIAMSys.Init(ctx, objLayer, globalEtcdClient, 2*time.Second)

View File

@ -18,6 +18,7 @@
package cmd
import (
"context"
"fmt"
"net/http"
"net/url"
@ -93,7 +94,10 @@ func TestDoesPolicySignatureMatch(t *testing.T) {
}
func TestDoesPresignedSignatureMatch(t *testing.T) {
obj, fsDir, err := prepareFS()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
obj, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatal(err)
}

View File

@ -187,7 +187,7 @@ func calculateStreamContentLength(dataLen, chunkSize int64) int64 {
return streamLen
}
func prepareFS() (ObjectLayer, string, error) {
func prepareFS(ctx context.Context) (ObjectLayer, string, error) {
nDisks := 1
fsDirs, err := getRandomDisks(nDisks)
if err != nil {
@ -198,9 +198,9 @@ func prepareFS() (ObjectLayer, string, error) {
return nil, "", err
}
initAllSubsystems()
initAllSubsystems(ctx)
globalIAMSys.Init(context.Background(), obj, globalEtcdClient, 2*time.Second)
globalIAMSys.Init(ctx, obj, globalEtcdClient, 2*time.Second)
return obj, fsDirs[0], nil
}
@ -234,7 +234,7 @@ func initFSObjects(disk string, t *testing.T) (obj ObjectLayer) {
newTestConfig(globalMinioDefaultRegion, obj)
initAllSubsystems()
initAllSubsystems(GlobalContext)
return obj
}
@ -366,7 +366,7 @@ func initTestServerWithBackend(ctx context.Context, t TestErrHandler, testServer
globalMinioPort = port
globalMinioAddr = getEndpointsLocalAddr(testServer.Disks)
initAllSubsystems()
initAllSubsystems(ctx)
globalEtcdClient = nil
@ -445,7 +445,7 @@ func resetGlobalIsErasure() {
func resetGlobalHealState() {
// Init global heal state
if globalAllHealState == nil {
globalAllHealState = newHealState(false)
globalAllHealState = newHealState(GlobalContext, false)
} else {
globalAllHealState.Lock()
for _, v := range globalAllHealState.healSeqMap {
@ -458,7 +458,7 @@ func resetGlobalHealState() {
// Init background heal state
if globalBackgroundHealState == nil {
globalBackgroundHealState = newHealState(false)
globalBackgroundHealState = newHealState(GlobalContext, false)
} else {
globalBackgroundHealState.Lock()
for _, v := range globalBackgroundHealState.healSeqMap {
@ -1474,7 +1474,7 @@ func getRandomDisks(N int) ([]string, error) {
// Initialize object layer with the supplied disks, objectLayer is nil upon any error.
func newTestObjectLayer(ctx context.Context, endpointServerPools EndpointServerPools) (newObject ObjectLayer, err error) {
initAllSubsystems()
initAllSubsystems(ctx)
return newErasureServerPools(ctx, endpointServerPools)
}
@ -1518,7 +1518,7 @@ func removeDiskN(disks []string, n int) {
// initialies the root and returns its path.
// return credentials.
func initAPIHandlerTest(ctx context.Context, obj ObjectLayer, endpoints []string) (string, http.Handler, error) {
initAllSubsystems()
initAllSubsystems(ctx)
initConfigSubsystem(ctx, obj)
@ -1556,7 +1556,7 @@ func prepareTestBackend(ctx context.Context, instanceType string) (ObjectLayer,
return prepareErasure16(ctx)
default:
// return FS backend by default.
obj, disk, err := prepareFS()
obj, disk, err := prepareFS(ctx)
if err != nil {
return nil, nil, err
}
@ -1725,7 +1725,7 @@ func ExecObjectLayerAPITest(t *testing.T, objAPITest objAPITestType, endpoints [
// this is to make sure that the tests are not affected by modified value.
resetTestGlobals()
objLayer, fsDir, err := prepareFS()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatalf("Initialization of object layer failed for single node setup: %s", err)
}
@ -1793,13 +1793,12 @@ func ExecObjectLayerTest(t TestErrHandler, objTest objTestType) {
localMetacacheMgr.deleteAll()
}
objLayer, fsDir, err := prepareFS()
objLayer, fsDir, err := prepareFS(ctx)
if err != nil {
t.Fatalf("Initialization of object layer failed for single node setup: %s", err)
}
setObjectLayer(objLayer)
initAllSubsystems()
initAllSubsystems(ctx)
// initialize the server and obtain the credentials and root.
// credentials are necessary to sign the HTTP request.
@ -1825,7 +1824,7 @@ func ExecObjectLayerTest(t TestErrHandler, objTest objTestType) {
localMetacacheMgr.deleteAll()
}
initAllSubsystems()
initAllSubsystems(ctx)
objLayer, fsDirs, err := prepareErasureSets32(ctx)
if err != nil {
t.Fatalf("Initialization of object layer failed for Erasure setup: %s", err)