Skip to content

Commit 56b278d

Browse files
committed
fix flake in TestLeaseCandidateCleanup
1 parent 919e7ab commit 56b278d

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

pkg/controlplane/apiserver/server.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ var (
6060
// IdentityLeaseRenewIntervalPeriod is the interval of kube-apiserver renewing its lease in seconds
6161
// IdentityLeaseRenewIntervalPeriod is exposed so integration tests can tune this value.
6262
IdentityLeaseRenewIntervalPeriod = 10 * time.Second
63+
64+
// LeaseCandidateGCPeriod is the interval which the leasecandidate GC controller checks for expired leases
65+
// This is exposed so integration tests can tune this value.
66+
LeaseCandidateGCPeriod = 30 * time.Minute
6367
)
6468

6569
const (
@@ -164,7 +168,7 @@ func (c completedConfig) New(name string, delegationTarget genericapiserver.Dele
164168
)
165169
gccontroller := leaderelection.NewLeaseCandidateGC(
166170
client,
167-
1*time.Hour,
171+
LeaseCandidateGCPeriod,
168172
lcInformer,
169173
)
170174
return func(ctx context.Context, workers int) {

test/integration/apiserver/coordinated_leader_election_test.go

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package apiserver
1919
import (
2020
"context"
2121
"fmt"
22+
"sync"
2223
"testing"
2324
"time"
2425

@@ -36,6 +37,7 @@ import (
3637
featuregatetesting "k8s.io/component-base/featuregate/testing"
3738
"k8s.io/klog/v2"
3839
apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
40+
"k8s.io/kubernetes/pkg/controlplane/apiserver"
3941
"k8s.io/kubernetes/test/integration/framework"
4042
)
4143

@@ -50,10 +52,11 @@ func TestSingleLeaseCandidate(t *testing.T) {
5052
config := server.ClientConfig
5153

5254
ctx, cancel := context.WithCancel(context.Background())
55+
defer cancel()
5356
cletest := setupCLE(config, ctx, cancel, t)
5457
defer cletest.cleanup()
5558
go cletest.createAndRunFakeController("foo1", "default", "foo", "1.20.0", "1.20.0")
56-
cletest.pollForLease("foo", "default", "foo1")
59+
cletest.pollForLease(ctx, "foo", "default", "foo1")
5760
}
5861

5962
func TestMultipleLeaseCandidate(t *testing.T) {
@@ -67,14 +70,15 @@ func TestMultipleLeaseCandidate(t *testing.T) {
6770
config := server.ClientConfig
6871

6972
ctx, cancel := context.WithCancel(context.Background())
73+
defer cancel()
7074
cletest := setupCLE(config, ctx, cancel, t)
7175
defer cletest.cleanup()
72-
go cletest.createAndRunFakeController("foo1", "default", "foo", "1.20.0", "1.20.0")
73-
go cletest.createAndRunFakeController("foo2", "default", "foo", "1.20.0", "1.19.0")
74-
go cletest.createAndRunFakeController("foo3", "default", "foo", "1.19.0", "1.19.0")
75-
go cletest.createAndRunFakeController("foo4", "default", "foo", "1.2.0", "1.19.0")
76-
go cletest.createAndRunFakeController("foo5", "default", "foo", "1.20.0", "1.19.0")
77-
cletest.pollForLease("foo", "default", "foo3")
76+
go cletest.createAndRunFakeController("baz1", "default", "baz", "1.20.0", "1.20.0")
77+
go cletest.createAndRunFakeController("baz2", "default", "baz", "1.20.0", "1.19.0")
78+
go cletest.createAndRunFakeController("baz3", "default", "baz", "1.19.0", "1.19.0")
79+
go cletest.createAndRunFakeController("baz4", "default", "baz", "1.2.0", "1.19.0")
80+
go cletest.createAndRunFakeController("baz5", "default", "baz", "1.20.0", "1.19.0")
81+
cletest.pollForLease(ctx, "baz", "default", "baz3")
7882
}
7983

8084
func TestLeaseSwapIfBetterAvailable(t *testing.T) {
@@ -92,9 +96,9 @@ func TestLeaseSwapIfBetterAvailable(t *testing.T) {
9296
defer cletest.cleanup()
9397

9498
go cletest.createAndRunFakeController("bar1", "default", "bar", "1.20.0", "1.20.0")
95-
cletest.pollForLease("bar", "default", "bar1")
99+
cletest.pollForLease(ctx, "bar", "default", "bar1")
96100
go cletest.createAndRunFakeController("bar2", "default", "bar", "1.19.0", "1.19.0")
97-
cletest.pollForLease("bar", "default", "bar2")
101+
cletest.pollForLease(ctx, "bar", "default", "bar2")
98102
}
99103

100104
// TestUpgradeSkew tests that a legacy client and a CLE aware client operating on the same lease do not cause errors
@@ -109,20 +113,26 @@ func TestUpgradeSkew(t *testing.T) {
109113
config := server.ClientConfig
110114

111115
ctx, cancel := context.WithCancel(context.Background())
116+
defer cancel()
112117
cletest := setupCLE(config, ctx, cancel, t)
113118
defer cletest.cleanup()
114119

115-
go cletest.createAndRunFakeLegacyController("foo1-130", "default", "foo")
116-
cletest.pollForLease("foo", "default", "foo1-130")
117-
go cletest.createAndRunFakeController("foo1-131", "default", "foo", "1.31.0", "1.31.0")
120+
go cletest.createAndRunFakeLegacyController("foo1-130", "default", "foobar")
121+
cletest.pollForLease(ctx, "foobar", "default", "foo1-130")
122+
go cletest.createAndRunFakeController("foo1-131", "default", "foobar", "1.31.0", "1.31.0")
118123
// running a new controller should not kick off old leader
119-
cletest.pollForLease("foo", "default", "foo1-130")
124+
cletest.pollForLease(ctx, "foobar", "default", "foo1-130")
120125
cletest.cancelController("foo1-130", "default")
121-
cletest.pollForLease("foo", "default", "foo1-131")
126+
cletest.pollForLease(ctx, "foobar", "default", "foo1-131")
122127
}
123128

124129
func TestLeaseCandidateCleanup(t *testing.T) {
125130
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CoordinatedLeaderElection, true)
131+
apiserver.LeaseCandidateGCPeriod = 1 * time.Second
132+
133+
defer func() {
134+
apiserver.LeaseCandidateGCPeriod = 30 * time.Minute
135+
}()
126136

127137
server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd())
128138
if err != nil {
@@ -140,7 +150,7 @@ func TestLeaseCandidateCleanup(t *testing.T) {
140150
Namespace: "default",
141151
},
142152
Spec: v1alpha1.LeaseCandidateSpec{
143-
LeaseName: "foobar",
153+
LeaseName: "foobaz",
144154
BinaryVersion: "0.1.0",
145155
EmulationVersion: "0.1.0",
146156
PreferredStrategies: []v1.CoordinatedLeaseStrategy{v1.OldestEmulationVersion},
@@ -175,11 +185,14 @@ type cleTest struct {
175185
config *rest.Config
176186
clientset *kubernetes.Clientset
177187
t *testing.T
188+
mu sync.Mutex
178189
ctxList map[string]ctxCancelPair
179190
}
180191

181-
func (t cleTest) createAndRunFakeLegacyController(name string, namespace string, targetLease string) {
192+
func (t *cleTest) createAndRunFakeLegacyController(name string, namespace string, targetLease string) {
182193
ctx, cancel := context.WithCancel(context.Background())
194+
t.mu.Lock()
195+
defer t.mu.Unlock()
183196
t.ctxList[name+"/"+namespace] = ctxCancelPair{ctx, cancel}
184197

185198
electionChecker := leaderelection.NewLeaderHealthzAdaptor(time.Second * 20)
@@ -197,7 +210,7 @@ func (t cleTest) createAndRunFakeLegacyController(name string, namespace string,
197210
})
198211

199212
}
200-
func (t cleTest) createAndRunFakeController(name string, namespace string, targetLease string, binaryVersion string, compatibilityVersion string) {
213+
func (t *cleTest) createAndRunFakeController(name string, namespace string, targetLease string, binaryVersion string, compatibilityVersion string) {
201214
identityLease, _, err := leaderelection.NewCandidate(
202215
t.clientset,
203216
namespace,
@@ -212,7 +225,9 @@ func (t cleTest) createAndRunFakeController(name string, namespace string, targe
212225
}
213226

214227
ctx, cancel := context.WithCancel(context.Background())
228+
t.mu.Lock()
215229
t.ctxList[name+"/"+namespace] = ctxCancelPair{ctx, cancel}
230+
t.mu.Unlock()
216231
go identityLease.Run(ctx)
217232

218233
electionChecker := leaderelection.NewLeaderHealthzAdaptor(time.Second * 20)
@@ -266,8 +281,8 @@ func leaderElectAndRun(ctx context.Context, kubeconfig *rest.Config, lockIdentit
266281
})
267282
}
268283

269-
func (t cleTest) pollForLease(name, namespace, holder string) {
270-
err := wait.PollUntilContextTimeout(t.ctxList["main"].ctx, 1000*time.Millisecond, 25*time.Second, true, func(ctx context.Context) (done bool, err error) {
284+
func (t *cleTest) pollForLease(ctx context.Context, name, namespace, holder string) {
285+
err := wait.PollUntilContextTimeout(ctx, 1000*time.Millisecond, 25*time.Second, true, func(ctx context.Context) (done bool, err error) {
271286
lease, err := t.clientset.CoordinationV1().Leases(namespace).Get(ctx, name, metav1.GetOptions{})
272287
if err != nil {
273288
fmt.Println(err)
@@ -280,29 +295,33 @@ func (t cleTest) pollForLease(name, namespace, holder string) {
280295
}
281296
}
282297

283-
func (t cleTest) cancelController(name, namespace string) {
298+
func (t *cleTest) cancelController(name, namespace string) {
299+
t.mu.Lock()
300+
defer t.mu.Unlock()
284301
t.ctxList[name+"/"+namespace].cancel()
285302
delete(t.ctxList, name+"/"+namespace)
286303
}
287304

288-
func (t cleTest) cleanup() {
305+
func (t *cleTest) cleanup() {
306+
t.mu.Lock()
307+
defer t.mu.Unlock()
308+
for _, c := range t.ctxList {
309+
c.cancel()
310+
}
289311
err := t.clientset.CoordinationV1().Leases("kube-system").Delete(context.TODO(), "leader-election-controller", metav1.DeleteOptions{})
290312
if err != nil && !apierrors.IsNotFound(err) {
291313
t.t.Error(err)
292314
}
293-
for _, c := range t.ctxList {
294-
c.cancel()
295-
}
296315
}
297316

298-
func setupCLE(config *rest.Config, ctx context.Context, cancel func(), t *testing.T) cleTest {
317+
func setupCLE(config *rest.Config, ctx context.Context, cancel func(), t *testing.T) *cleTest {
299318
clientset, err := kubernetes.NewForConfig(config)
300319
if err != nil {
301320
t.Fatal(err)
302321
}
303322

304323
a := ctxCancelPair{ctx, cancel}
305-
return cleTest{
324+
return &cleTest{
306325
config: config,
307326
clientset: clientset,
308327
ctxList: map[string]ctxCancelPair{"main": a},

0 commit comments

Comments
 (0)