kubernetes/test/e2e/framework
Patrick Ohly 3e2b26ce52 e2e: revise complete report creation
The previous approach was based on the observation that some Prow jobs use the
--report-dir parameter instead of the E2E_REPORT_DIR env variable. Parsing the
command line was necessary to use the --json-report and --junit-report
parameters.

But that is complex and can be avoided by triggering the creation of complete
reports in the E2E test suite. The paths are hard-coded and relative to the
report directory to keep the code simple.

There was a report that k8s-triage started processing more data after
6db4b741dd was merged. It's unclear whether
that was because of the new <report-dir>/ginkgo_report.xml file. To avoid
this potential problem, the reports are now in a "ginkgo" sub-directory.

While at it, error checking gets enhanced:
- Create directories at the start of
  the suite and bail out early if that fails.
- *All* e2e suites using the framework do this, not just test/e2e.
- Added missing error checking of truncated JUnit report writing.
2023-02-10 10:20:20 +01:00
..
auth e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
autoscaling Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
config Generate and format files 2022-07-26 13:14:05 -04:00
daemonset e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
debug e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
deployment Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
endpoints Fix review comments. Implement endpoint port validation that verifies the protocol, too. 2022-11-03 10:54:14 +02:00
endpointslice Fix review comments. Implement endpoint port validation that verifies the protocol, too. 2022-11-03 10:54:14 +02:00
events Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
gpu hack/update-bazel.sh 2021-02-28 15:17:29 -08:00
ingress Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
internal e2e: revise complete report creation 2023-02-10 10:20:20 +01:00
job e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
kubectl e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
kubelet e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
kubesystem Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
manifest Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
metrics Enable ComponentSLIs as beta feature 2023-01-26 17:46:21 -08:00
network Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
node Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
perf various corrections in test/e2e package 2022-09-16 18:59:30 +05:30
pod Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
providers Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
pv Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
rc e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
replicaset e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
resource Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
security e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
service Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
skipper Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
ssh Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
statefulset Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
testfiles Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
timer e2e: adapt to moved code 2022-10-06 08:19:47 +02:00
volume Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
websocket Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
.import-restrictions remove psp in extensions api/apis 2023-01-06 17:07:02 +08:00
expect.go Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
flake_reporting_util.go fix pass []any as any in variadic function 2022-07-09 18:53:54 +08:00
framework.go Merge pull request #114580 from pohly/e2e-ginkgo-timeout-fixes 2023-01-30 13:48:48 -08:00
get.go Revert "e2e: wait for pods with gomega" 2023-02-06 12:08:22 +01:00
ginkgowrapper.go e2e framework: support Ginkgo decorators for framework.ConformanceIt 2022-12-19 13:53:08 +01:00
log_test.go e2e framework: verify JUnit result, not the in-memory structs 2022-12-21 07:55:07 +01:00
log.go e2e framework: remove injection of failures and skips into GinkgoWriter 2022-12-21 07:55:07 +01:00
namespacedname.go e2e framework: add NamespacedName 2023-01-16 09:05:37 +01:00
nodes_util.go e2e framework: move NodeKiller into framework/node 2022-10-06 08:16:47 +02:00
OWNERS OWNERS: remove sig-testing-approvers 2023-01-09 09:54:10 +01:00
ports.go refactor(e2e): grab metrics from controller-manager via nginx 2021-05-03 00:12:06 +08:00
provider.go e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00
README.md e2e: accept context from Ginkgo 2022-12-10 19:50:18 +01:00
size.go
test_context.go e2e: revise complete report creation 2023-02-10 10:20:20 +01:00
timeouts.go e2e framework: configure poll interval+duration for gomega 2023-01-09 17:29:35 +01:00
util.go e2e: use Ginkgo context 2022-12-16 20:14:04 +01:00

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 kublet 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.