Skip to content

Commit 2b51b25

Browse files
authored
Merge pull request kubernetes#110604 from wojtek-t/fix_leaking_goroutines_9
Fix leaking goroutines in multiple integration tests
2 parents 700fea3 + 6b59525 commit 2b51b25

File tree

6 files changed

+46
-56
lines changed

6 files changed

+46
-56
lines changed

test/integration/apiserver/flowcontrol/concurrency_test.go

+17-29
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"context"
2121
"fmt"
2222
"io"
23-
"net/http/httptest"
2423
"strings"
2524
"sync"
2625
"testing"
@@ -31,14 +30,13 @@ import (
3130

3231
flowcontrol "k8s.io/api/flowcontrol/v1beta2"
3332
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34-
"k8s.io/apimachinery/pkg/runtime/schema"
3533
"k8s.io/apimachinery/pkg/util/wait"
3634
genericfeatures "k8s.io/apiserver/pkg/features"
3735
utilfeature "k8s.io/apiserver/pkg/util/feature"
3836
clientset "k8s.io/client-go/kubernetes"
3937
"k8s.io/client-go/rest"
4038
featuregatetesting "k8s.io/component-base/featuregate/testing"
41-
"k8s.io/kubernetes/pkg/controlplane"
39+
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
4240
"k8s.io/kubernetes/test/integration/framework"
4341
)
4442

@@ -50,33 +48,27 @@ const (
5048
timeout = time.Second * 10
5149
)
5250

53-
func setup(t testing.TB, maxReadonlyRequestsInFlight, MaxMutatingRequestsInFlight int) (*httptest.Server, *rest.Config, framework.CloseFunc) {
54-
opts := framework.ControlPlaneConfigOptions{EtcdOptions: framework.DefaultEtcdOptions()}
55-
opts.EtcdOptions.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
56-
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfigWithOptions(&opts)
57-
resourceConfig := controlplane.DefaultAPIResourceConfigSource()
58-
resourceConfig.EnableVersions(schema.GroupVersion{
59-
Group: "flowcontrol.apiserver.k8s.io",
60-
Version: "v1alpha1",
51+
func setup(t testing.TB, maxReadonlyRequestsInFlight, MaxMutatingRequestsInFlight int) (*rest.Config, framework.TearDownFunc) {
52+
_, kubeConfig, tearDownFn := framework.StartTestServer(t, framework.TestServerSetup{
53+
ModifyServerRunOptions: func(opts *options.ServerRunOptions) {
54+
// Ensure all clients are allowed to send requests.
55+
opts.Authorization.Modes = []string{"AlwaysAllow"}
56+
opts.GenericServerRunOptions.MaxRequestsInFlight = maxReadonlyRequestsInFlight
57+
opts.GenericServerRunOptions.MaxMutatingRequestsInFlight = MaxMutatingRequestsInFlight
58+
},
6159
})
62-
controlPlaneConfig.GenericConfig.MaxRequestsInFlight = maxReadonlyRequestsInFlight
63-
controlPlaneConfig.GenericConfig.MaxMutatingRequestsInFlight = MaxMutatingRequestsInFlight
64-
controlPlaneConfig.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
65-
controlPlaneConfig.ExtraConfig.APIResourceConfigSource = resourceConfig
66-
_, s, closeFn := framework.RunAnAPIServer(controlPlaneConfig)
67-
68-
return s, controlPlaneConfig.GenericConfig.LoopbackClientConfig, closeFn
60+
return kubeConfig, tearDownFn
6961
}
7062

7163
func TestPriorityLevelIsolation(t *testing.T) {
7264
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.APIPriorityAndFairness, true)()
7365
// NOTE: disabling the feature should fail the test
74-
_, loopbackConfig, closeFn := setup(t, 1, 1)
66+
kubeConfig, closeFn := setup(t, 1, 1)
7567
defer closeFn()
7668

77-
loopbackClient := clientset.NewForConfigOrDie(loopbackConfig)
78-
noxu1Client := getClientFor(loopbackConfig, "noxu1")
79-
noxu2Client := getClientFor(loopbackConfig, "noxu2")
69+
loopbackClient := clientset.NewForConfigOrDie(kubeConfig)
70+
noxu1Client := getClientFor(kubeConfig, "noxu1")
71+
noxu2Client := getClientFor(kubeConfig, "noxu2")
8072

8173
queueLength := 50
8274
concurrencyShares := 1
@@ -153,13 +145,9 @@ func TestPriorityLevelIsolation(t *testing.T) {
153145
}
154146

155147
func getClientFor(loopbackConfig *rest.Config, username string) clientset.Interface {
156-
config := &rest.Config{
157-
Host: loopbackConfig.Host,
158-
QPS: -1,
159-
BearerToken: loopbackConfig.BearerToken,
160-
Impersonate: rest.ImpersonationConfig{
161-
UserName: username,
162-
},
148+
config := rest.CopyConfig(loopbackConfig)
149+
config.Impersonate = rest.ImpersonationConfig{
150+
UserName: username,
163151
}
164152
return clientset.NewForConfigOrDie(config)
165153
}

test/integration/apiserver/flowcontrol/fight_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,10 @@ func (ft *fightTest) evaluate(tBeforeCreate, tAfterCreate time.Time) {
170170
}
171171
func TestConfigConsumerFight(t *testing.T) {
172172
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.APIPriorityAndFairness, true)()
173-
_, loopbackConfig, closeFn := setup(t, 100, 100)
173+
kubeConfig, closeFn := setup(t, 100, 100)
174174
defer closeFn()
175175
const teamSize = 3
176-
ft := newFightTest(t, loopbackConfig, teamSize)
176+
ft := newFightTest(t, kubeConfig, teamSize)
177177
tBeforeCreate := time.Now()
178178
ft.createMainInformer()
179179
ft.foreach(ft.createController)

test/integration/apiserver/flowcontrol/fs_condition_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ import (
3838
func TestConditionIsolation(t *testing.T) {
3939
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.APIPriorityAndFairness, true)()
4040
// NOTE: disabling the feature should fail the test
41-
_, loopbackConfig, closeFn := setup(t, 10, 10)
41+
kubeConfig, closeFn := setup(t, 10, 10)
4242
defer closeFn()
4343

44-
loopbackClient := clientset.NewForConfigOrDie(loopbackConfig)
44+
loopbackClient := clientset.NewForConfigOrDie(kubeConfig)
4545

4646
stopCh := make(chan struct{})
4747
defer close(stopCh)

test/integration/apiserver/openapi/openapi_test.go

+11-7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
featuregatetesting "k8s.io/component-base/featuregate/testing"
2929
"k8s.io/kube-openapi/pkg/common"
3030
"k8s.io/kube-openapi/pkg/validation/spec"
31+
"k8s.io/kubernetes/pkg/controlplane"
3132
generated "k8s.io/kubernetes/pkg/generated/openapi"
3233
"k8s.io/kubernetes/test/integration/framework"
3334
)
@@ -55,9 +56,7 @@ func TestEnablingOpenAPIEnumTypes(t *testing.T) {
5556
t.Run(tc.name, func(t *testing.T) {
5657
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.OpenAPIEnums, tc.featureEnabled)()
5758

58-
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfigWithOptions(&framework.ControlPlaneConfigOptions{})
59-
controlPlaneConfig.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
60-
controlPlaneConfig.GenericConfig.OpenAPIConfig.GetDefinitions = openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(func(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
59+
getDefinitionsFn := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(func(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
6160
defs := generated.GetOpenAPIDefinitions(ref)
6261
def := defs[typeToAddEnum]
6362
// replace protocol to add the would-be enum field.
@@ -74,15 +73,20 @@ func TestEnablingOpenAPIEnumTypes(t *testing.T) {
7473
return defs
7574
})
7675

77-
instanceConfig, _, closeFn := framework.RunAnAPIServer(controlPlaneConfig)
78-
defer closeFn()
76+
_, kubeConfig, tearDownFn := framework.StartTestServer(t, framework.TestServerSetup{
77+
ModifyServerConfig: func(config *controlplane.Config) {
78+
config.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
79+
config.GenericConfig.OpenAPIConfig.GetDefinitions = getDefinitionsFn
80+
},
81+
})
82+
defer tearDownFn()
7983

80-
rt, err := restclient.TransportFor(instanceConfig.GenericAPIServer.LoopbackClientConfig)
84+
rt, err := restclient.TransportFor(kubeConfig)
8185
if err != nil {
8286
t.Fatal(err)
8387
}
8488

85-
req, err := http.NewRequest("GET", instanceConfig.GenericAPIServer.LoopbackClientConfig.Host+"/openapi/v2", nil)
89+
req, err := http.NewRequest("GET", kubeConfig.Host+"/openapi/v2", nil)
8690
if err != nil {
8791
t.Fatal(err)
8892
}

test/integration/apiserver/openapi/openapiv3_test.go

+13-15
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ import (
4646

4747
func TestOpenAPIV3SpecRoundTrip(t *testing.T) {
4848
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.OpenAPIV3, true)()
49-
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfigWithOptions(&framework.ControlPlaneConfigOptions{})
50-
controlPlaneConfig.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
51-
controlPlaneConfig.GenericConfig.OpenAPIV3Config = framework.DefaultOpenAPIV3Config()
52-
instanceConfig, _, closeFn := framework.RunAnAPIServer(controlPlaneConfig)
53-
defer closeFn()
49+
50+
_, kubeConfig, tearDownFn := framework.StartTestServer(t, framework.TestServerSetup{})
51+
defer tearDownFn()
52+
5453
paths := []string{
5554
"/apis/apps/v1",
5655
"/apis/authentication.k8s.io/v1",
@@ -60,12 +59,12 @@ func TestOpenAPIV3SpecRoundTrip(t *testing.T) {
6059
}
6160
for _, path := range paths {
6261
t.Run(path, func(t *testing.T) {
63-
rt, err := restclient.TransportFor(instanceConfig.GenericAPIServer.LoopbackClientConfig)
62+
rt, err := restclient.TransportFor(kubeConfig)
6463
if err != nil {
6564
t.Fatal(err)
6665
}
6766
// attempt to fetch and unmarshal
68-
url := instanceConfig.GenericAPIServer.LoopbackClientConfig.Host + "/openapi/v3" + path
67+
url := kubeConfig.Host + "/openapi/v3" + path
6968
req, err := http.NewRequest("GET", url, nil)
7069
if err != nil {
7170
t.Fatal(err)
@@ -191,17 +190,16 @@ func TestOpenAPIV3ProtoRoundtrip(t *testing.T) {
191190
// See https://github.com/kubernetes/kubernetes/issues/106387 for more details
192191
t.Skip("Skipping OpenAPI V3 Proto roundtrip test")
193192
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.OpenAPIV3, true)()
194-
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfigWithOptions(&framework.ControlPlaneConfigOptions{})
195-
controlPlaneConfig.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
196-
controlPlaneConfig.GenericConfig.OpenAPIV3Config = framework.DefaultOpenAPIV3Config()
197-
instanceConfig, _, closeFn := framework.RunAnAPIServer(controlPlaneConfig)
198-
defer closeFn()
199-
rt, err := restclient.TransportFor(instanceConfig.GenericAPIServer.LoopbackClientConfig)
193+
194+
_, kubeConfig, tearDownFn := framework.StartTestServer(t, framework.TestServerSetup{})
195+
defer tearDownFn()
196+
197+
rt, err := restclient.TransportFor(kubeConfig)
200198
if err != nil {
201199
t.Fatal(err)
202200
}
203201
// attempt to fetch and unmarshal
204-
req, err := http.NewRequest("GET", instanceConfig.GenericAPIServer.LoopbackClientConfig.Host+"/openapi/v3/apis/apps/v1", nil)
202+
req, err := http.NewRequest("GET", kubeConfig.Host+"/openapi/v3/apis/apps/v1", nil)
205203
if err != nil {
206204
t.Fatal(err)
207205
}
@@ -220,7 +218,7 @@ func TestOpenAPIV3ProtoRoundtrip(t *testing.T) {
220218
t.Fatal(err)
221219
}
222220

223-
protoReq, err := http.NewRequest("GET", instanceConfig.GenericAPIServer.LoopbackClientConfig.Host+"/openapi/v3/apis/apps/v1", nil)
221+
protoReq, err := http.NewRequest("GET", kubeConfig.Host+"/openapi/v3/apis/apps/v1", nil)
224222
if err != nil {
225223
t.Fatal(err)
226224
}

test/integration/framework/test_server.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type TestServerSetup struct {
5959
type TearDownFunc func()
6060

6161
// StartTestServer runs a kube-apiserver, optionally calling out to the setup.ModifyServerRunOptions and setup.ModifyServerConfig functions
62-
func StartTestServer(t *testing.T, setup TestServerSetup) (client.Interface, *rest.Config, TearDownFunc) {
62+
func StartTestServer(t testing.TB, setup TestServerSetup) (client.Interface, *rest.Config, TearDownFunc) {
6363
certDir, err := os.MkdirTemp("", "test-integration-"+strings.ReplaceAll(t.Name(), "/", "_"))
6464
if err != nil {
6565
t.Fatalf("Couldn't create temp dir: %v", err)

0 commit comments

Comments
 (0)