mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Merge pull request #86177 from deads2k/configure-test
make test framework easier to re-use
This commit is contained in:
commit
5b77616374
@ -30,6 +30,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -71,6 +73,7 @@ type Framework struct {
|
|||||||
// test multiple times in parallel.
|
// test multiple times in parallel.
|
||||||
UniqueName string
|
UniqueName string
|
||||||
|
|
||||||
|
clientConfig *rest.Config
|
||||||
ClientSet clientset.Interface
|
ClientSet clientset.Interface
|
||||||
KubemarkExternalClusterClientSet clientset.Interface
|
KubemarkExternalClusterClientSet clientset.Interface
|
||||||
|
|
||||||
@ -102,6 +105,11 @@ type Framework struct {
|
|||||||
// should abort, the AfterSuite hook should run all Cleanup actions.
|
// should abort, the AfterSuite hook should run all Cleanup actions.
|
||||||
cleanupHandle CleanupActionHandle
|
cleanupHandle CleanupActionHandle
|
||||||
|
|
||||||
|
// afterEaches is a map of name to function to be called after each test. These are not
|
||||||
|
// cleared. The call order is randomized so that no dependencies can grow between
|
||||||
|
// the various afterEaches
|
||||||
|
afterEaches map[string]AfterEachActionFunc
|
||||||
|
|
||||||
// configuration for framework's client
|
// configuration for framework's client
|
||||||
Options Options
|
Options Options
|
||||||
|
|
||||||
@ -113,6 +121,9 @@ type Framework struct {
|
|||||||
clusterAutoscalerMetricsBeforeTest e2emetrics.Collection
|
clusterAutoscalerMetricsBeforeTest e2emetrics.Collection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AfterEachActionFunc is a function that can be called after each test
|
||||||
|
type AfterEachActionFunc func(f *Framework, failed bool)
|
||||||
|
|
||||||
// TestDataSummary is an interface for managing test data.
|
// TestDataSummary is an interface for managing test data.
|
||||||
type TestDataSummary interface {
|
type TestDataSummary interface {
|
||||||
SummaryKind() string
|
SummaryKind() string
|
||||||
@ -146,6 +157,20 @@ func NewFramework(baseName string, options Options, client clientset.Interface)
|
|||||||
ClientSet: client,
|
ClientSet: client,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.AddAfterEach("dumpNamespaceInfo", func(f *Framework, failed bool) {
|
||||||
|
if !failed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !TestContext.DumpLogsOnFailure {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !f.SkipNamespaceCreation {
|
||||||
|
for _, ns := range f.namespacesToDelete {
|
||||||
|
DumpAllNamespaceInfo(f.ClientSet, ns.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
ginkgo.BeforeEach(f.BeforeEach)
|
ginkgo.BeforeEach(f.BeforeEach)
|
||||||
ginkgo.AfterEach(f.AfterEach)
|
ginkgo.AfterEach(f.AfterEach)
|
||||||
|
|
||||||
@ -170,6 +195,7 @@ func (f *Framework) BeforeEach() {
|
|||||||
if TestContext.KubeAPIContentType != "" {
|
if TestContext.KubeAPIContentType != "" {
|
||||||
config.ContentType = TestContext.KubeAPIContentType
|
config.ContentType = TestContext.KubeAPIContentType
|
||||||
}
|
}
|
||||||
|
f.clientConfig = rest.CopyConfig(config)
|
||||||
f.ClientSet, err = clientset.NewForConfig(config)
|
f.ClientSet, err = clientset.NewForConfig(config)
|
||||||
ExpectNoError(err)
|
ExpectNoError(err)
|
||||||
f.DynamicClient, err = dynamic.NewForConfig(config)
|
f.DynamicClient, err = dynamic.NewForConfig(config)
|
||||||
@ -315,6 +341,19 @@ func printSummaries(summaries []TestDataSummary, testBaseName string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddAfterEach is a way to add a function to be called after every test. The execution order is intentionally random
|
||||||
|
// to avoid growing dependencies. If you register the same name twice, it is a coding error and will panic.
|
||||||
|
func (f *Framework) AddAfterEach(name string, fn AfterEachActionFunc) {
|
||||||
|
if _, ok := f.afterEaches[name]; ok {
|
||||||
|
panic(fmt.Sprintf("%q is already registered", name))
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.afterEaches == nil {
|
||||||
|
f.afterEaches = map[string]AfterEachActionFunc{}
|
||||||
|
}
|
||||||
|
f.afterEaches[name] = fn
|
||||||
|
}
|
||||||
|
|
||||||
// AfterEach deletes the namespace, after reading its events.
|
// AfterEach deletes the namespace, after reading its events.
|
||||||
func (f *Framework) AfterEach() {
|
func (f *Framework) AfterEach() {
|
||||||
RemoveCleanupAction(f.cleanupHandle)
|
RemoveCleanupAction(f.cleanupHandle)
|
||||||
@ -352,6 +391,7 @@ func (f *Framework) AfterEach() {
|
|||||||
|
|
||||||
// Paranoia-- prevent reuse!
|
// Paranoia-- prevent reuse!
|
||||||
f.Namespace = nil
|
f.Namespace = nil
|
||||||
|
f.clientConfig = nil
|
||||||
f.ClientSet = nil
|
f.ClientSet = nil
|
||||||
f.namespacesToDelete = nil
|
f.namespacesToDelete = nil
|
||||||
|
|
||||||
@ -365,12 +405,9 @@ func (f *Framework) AfterEach() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Print events if the test failed.
|
// run all aftereach functions in random order to ensure no dependencies grow
|
||||||
if ginkgo.CurrentGinkgoTestDescription().Failed && TestContext.DumpLogsOnFailure {
|
for _, afterEachFn := range f.afterEaches {
|
||||||
// Pass both unversioned client and versioned clientset, till we have removed all uses of the unversioned client.
|
afterEachFn(f, ginkgo.CurrentGinkgoTestDescription().Failed)
|
||||||
if !f.SkipNamespaceCreation {
|
|
||||||
DumpAllNamespaceInfo(f.ClientSet, f.Namespace.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if TestContext.GatherKubeSystemResourceUsageData != "false" && TestContext.GatherKubeSystemResourceUsageData != "none" && f.gatherer != nil {
|
if TestContext.GatherKubeSystemResourceUsageData != "false" && TestContext.GatherKubeSystemResourceUsageData != "none" && f.gatherer != nil {
|
||||||
@ -490,6 +527,15 @@ func (f *Framework) WaitForPodNoLongerRunning(podName string) error {
|
|||||||
return e2epod.WaitForPodNoLongerRunningInNamespace(f.ClientSet, podName, f.Namespace.Name)
|
return e2epod.WaitForPodNoLongerRunningInNamespace(f.ClientSet, podName, f.Namespace.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientConfig an externally accessible method for reading the kube client config.
|
||||||
|
func (f *Framework) ClientConfig() *rest.Config {
|
||||||
|
ret := rest.CopyConfig(f.clientConfig)
|
||||||
|
// json is least common denominator
|
||||||
|
ret.ContentType = runtime.ContentTypeJSON
|
||||||
|
ret.AcceptContentTypes = runtime.ContentTypeJSON
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
// TestContainerOutput runs the given pod in the given namespace and waits
|
// TestContainerOutput runs the given pod in the given namespace and waits
|
||||||
// for all of the containers in the podSpec to move into the 'Success' status, and tests
|
// for all of the containers in the podSpec to move into the 'Success' status, and tests
|
||||||
// the specified container log against the given expected output using a substring matcher.
|
// the specified container log against the given expected output using a substring matcher.
|
||||||
|
Loading…
Reference in New Issue
Block a user