apiserver testing: fix support for pre-created TContext

When StartTestServer is called with a TContext by the caller, tearing down the
apiserver via its tear-down function would also cancel the context for everyone
else using it, which is unexpected and not intended.

Accidentally, scheduler_perf and scheduler/batch relied on this behavior:
- The apiserver clients waited on a context that got its cancellation
  from the root context and thus gets canceled last.
- The apiserver was told to stop earlier, but then waited because
  it still had active clients.
- Shutdown gets slowed down enough that integration testing times out.

The fix is to explicitly cancel the clients before the apiserver. Long-term
ktesting should be changed to do the same as the new testing.T.Context: cancel
the context *before* cleaning up, not *after* it.
This commit is contained in:
Patrick Ohly
2026-03-12 09:52:42 +01:00
parent 76f0bd54b8
commit e04d25c222
3 changed files with 13 additions and 3 deletions

View File

@@ -156,7 +156,11 @@ func NewDefaultTestServerOptions() *TestServerInstanceOptions {
func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions, customFlags []string, storageConfig *storagebackend.Config) (result TestServer, err error) {
// Some callers may have initialize ktesting already.
tCtx, ok := t.(ktesting.TContext)
if !ok {
if ok {
// tCtx.Cancel below must not cancel whatever else might be using
// this existing TContext.
tCtx = tCtx.WithCancel()
} else {
tCtx = ktesting.Init(t)
}

View File

@@ -597,9 +597,12 @@ func mustSetupCluster(tCtx ktesting.TContext, config *config.KubeSchedulerConfig
tCtx.Fatalf("start apiserver: %v", err)
}
// Cleanup will be in reverse order: first the clients by canceling the
// child context (happens automatically), then the server.
// child context, then the server.
tCtx.Cleanup(server.TearDownFn)
tCtx = tCtx.WithCancel()
tCtx.Cleanup(func() {
tCtx.Cancel("test is done")
})
// TODO: client connection configuration, such as QPS or Burst is configurable in theory, this could be derived from the `config`, need to
// support this when there is any testcase that depends on such configuration.

View File

@@ -112,9 +112,12 @@ func mustSetupCluster(tCtx ktesting.TContext, config *config.KubeSchedulerConfig
tCtx.Fatalf("start apiserver: %v", err)
}
// Cleanup will be in reverse order: first the clients by canceling the
// child context (happens automatically), then the server.
// child context, then the server.
tCtx.Cleanup(server.TearDownFn)
tCtx = tCtx.WithCancel()
tCtx.Cleanup(func() {
tCtx.Cancel("test is done")
})
// TODO: client connection configuration, such as QPS or Burst is configurable in theory, this could be derived from the `config`, need to
// support this when there is any testcase that depends on such configuration.