kubernetes/test/e2e/framework
Sotiris Salloumis 5486715fbf Move kubeletHealthCheck from e2enode to node
To reduce duplication of code and overcome import cycle
not allowed error during compile time, when used in non
e2e_node packages.
2026-05-05 20:39:07 +02:00
..
auth
autoscaling Merge pull request #137612 from bishal7679/fix/hpa-configurable-tolerance-e2e-deterministic-cpu-load 2026-03-21 23:28:17 +05:30
config
conformance ktesting: move format package 2026-04-24 21:54:19 +02:00
daemonset ktesting: move format package 2026-04-24 21:54:19 +02:00
debug Lint: Use modernize/rangeint in test/{e2e,e2e_node,images,soak} 2026-03-07 10:17:31 +01:00
deployment
endpointslice
events
gpu
internal Merge pull request #138258 from pohly/ktesting-cgo 2026-04-27 06:48:46 +05:30
job ktesting: move format package 2026-04-24 21:54:19 +02:00
kubectl Lint: Use modernize/rangeint in test/{e2e,e2e_node,images,soak} 2026-03-07 10:17:31 +01:00
kubelet
kubesystem
manifest
metrics
network Lint: Use modernize/rangeint in test/{e2e,e2e_node,images,soak} 2026-03-07 10:17:31 +01:00
node Move kubeletHealthCheck from e2enode to node 2026-05-05 20:39:07 +02:00
perf
pod ktesting: move format package 2026-04-24 21:54:19 +02:00
providers
pv ktesting: move format package 2026-04-24 21:54:19 +02:00
rc
registry Add the fake registry server functionality to agnhost windows 2026-02-02 19:00:29 +00:00
replicaset
resource
security
service Merge pull request #137535 from danwinship/nodeip-e2e-cleanups 2026-03-10 02:59:19 +05:30
skipper
ssh Fix the semantics of e2essh.NodeSSHHosts on error 2026-03-07 10:52:48 -05:00
statefulset Remove unneeded use of fmt.Sprintf in test/{integration,e2e} 2026-02-08 14:34:13 +01:00
testfiles
timer
volume Lint: Use modernize/rangeint in test/{e2e,e2e_node,images,soak} 2026-03-07 10:17:31 +01:00
websocket
.import-restrictions
bugs.go
expect.go
expect_test.go
flake_reporting_util.go
framework.go ktesting: create client-go/ktesting 2026-04-24 21:54:19 +02:00
get.go
ginkgologger.go e2e framework: fix inconsistency in log output 2026-01-05 13:45:03 +01:00
ginkgowrapper.go E2E framework: avoid duplicate FeatureGate tags 2026-04-28 11:15:20 +02:00
ginkgowrapper_test.go
gomega.go
log.go
log_test.go
namespacedname.go
nodes_util.go
OWNERS
ports.go
provider.go
README.md
size.go
test_context.go Fix vet error 2026-03-05 18:11:02 -05:00
timeouts.go
util.go

Overview

The Kubernetes E2E framework simplifies writing Ginkgo tests suites. It's main usage is for these tests suites in the Kubernetes repository itself:

  • test/e2e: runs as client for a Kubernetes cluster. The e2e.test binary is used for conformance testing.
  • test/e2e_node: runs on the same node as a kubelet instance. Used for testing kubelet.
  • test/e2e_kubeadm: test suite for kubeadm.

Usage of the framework outside of Kubernetes is possible, but not encouraged. Downstream users have to be prepared to deal with API changes.

Code Organization

The core framework is the k8s.io/kubernetes/test/e2e/framework package. It contains functionality that all E2E suites are expected to need:

  • connecting to the apiserver
  • managing per-test namespaces
  • logging (Logf)
  • failure handling (Fail, Failf)
  • writing concise JUnit test results

It also contains a TestContext with settings that can be controlled via command line flags. For historic reasons, this also contains settings for individual tests or packages that are not part of the core framework.

Optional functionality is placed in sub packages like test/e2e/framework/pod. The core framework does not depend on those. Sub packages may depend on the core framework.

The advantages of splitting the code like this are:

  • leaner go doc packages by grouping related functions together
  • not forcing all E2E suites to import all functionality
  • avoiding import cycles

Execution Flow

When a test suite gets invoked, the top-level Describe calls register the callbacks that define individual tests, but does not invoke them yet. After that init phase, command line flags are parsed and the Describe callbacks are invoked. Those then define the actual tests for the test suite. Command line flags can be used to influence the test definitions.

Now Context/BeforeEach/AfterEach/It define code that will be called later when executing a specific test. During this setup phase, f := framework.NewDefaultFramework("some tests") creates a Framework instance for one or more tests. NewDefaultFramework initializes that instance anew for each test with a BeforeEach callback. Starting with Kubernetes 1.26, that instance gets cleaned up after all other code for a test has been invoked, so the following code is correct:

f := framework.NewDefaultFramework("some tests")

ginkgo.AfterEach(func() {
    # Do something with f.ClientSet.
}

ginkgo.It("test something", func(ctx context.Context) {
    # The actual test.
})

Optional functionality can be injected into each test by adding a callback to NewFrameworkExtensions in an init function. NewDefaultFramework will invoke those callbacks as if the corresponding code had been added to each test like this:

f := framework.NewDefaultFramework("some tests")

optional.SomeCallback(f)

SomeCallback then can register additional BeforeEach or AfterEach callbacks that use the test's Framework instance.

When a test runs, callbacks defined for it with BeforeEach and AfterEach are called in first-in-first-out order. Since the migration to ginkgo v2 in Kubernetes 1.25, the AfterEach callback is called also when there has been a test failure. This can be used to run cleanup code for a test reliably. However, ginkgo.DeferCleanup is often a better alternative. Its callbacks are executed in first-in-last-out order.

test/e2e/framework/internal/unittests/cleanup/cleanup.go shows how these different callbacks can be used and in which order they are going to run.