From 75e43ce75dc811de8f699176f043e684cb1a7ead Mon Sep 17 00:00:00 2001 From: Matteo Ruina Date: Tue, 2 May 2023 17:18:25 +0200 Subject: [PATCH] Fix every_test_custom_ns test --- examples/every_test_custom_ns/README.md | 42 ++++++++++++++-------- examples/every_test_custom_ns/k8s_test.go | 10 +++--- examples/every_test_custom_ns/main_test.go | 26 ++++++++++---- 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/examples/every_test_custom_ns/README.md b/examples/every_test_custom_ns/README.md index 90d1baf5..f1069bc0 100644 --- a/examples/every_test_custom_ns/README.md +++ b/examples/every_test_custom_ns/README.md @@ -5,16 +5,19 @@ a custom namespace for every test. This could easily be done for every feature as well if that is your preference. First, you'll have to set up the env. In this example we assume an in-cluster configuration. + ```go var testenv env.Environment func TestMain(m *testing.M) { - testenv = env.New() - ... + testenv = env.New() + ... } ``` + Second, set the BeforeEachTest hook to create the namespace. We store it in the context so that it can be looked up on a per-test basis for deletion. + ```go testenv.BeforeEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing.T) (context.Context, error) { return createNSForTest(ctx,cfg,t,runID) @@ -23,7 +26,9 @@ testenv.BeforeEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing // The creation uses the typical c.Resources() object. cfg.Client().Resources().Create(ctx,&nsObj) ``` + Third, set the AfterEachTest hook to lookup and delete the namespace. + ```go testenv.AfterEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing.T) (context.Context, error) { return deleteNSForTest(ctx,cfg,t,runID) @@ -33,23 +38,30 @@ testenv.AfterEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing. cfg.Client().Resources().Delete(ctx,&nsObj) ``` +Forth, in your test you can lookup the namespace and casting to a string + +```go +namespace := ctx.Value(GetNamespaceKey(t)).(string) +``` + So, tying it all together, the `TestMain` looks like this: + ```go func TestMain(m *testing.M) { - testenv = env.New() + testenv = env.New() - // Specifying a run ID so that multiple runs wouldn't collide. - runID := envconf.RandomName("", 4) + // Specifying a run ID so that multiple runs wouldn't collide. + runID := envconf.RandomName("", 4) - /* Skipping cluster creation for brevity */ - - testenv.BeforeEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing.T) (context.Context, error) { - return createNSForTest(ctx, cfg, t, runID) - }) - testenv.AfterEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing.T) (context.Context, error) { - return deleteNSForTest(ctx, cfg, t, runID) - }) + /* Skipping cluster creation for brevity */ + + testenv.BeforeEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing.T) (context.Context, error) { + return createNSForTest(ctx, cfg, t, runID) + }) + testenv.AfterEachTest(func(ctx context.Context, cfg *envconf.Config, t *testing.T) (context.Context, error) { + return deleteNSForTest(ctx, cfg, t, runID) + }) - os.Exit(testenv.Run(m)) + os.Exit(testenv.Run(m)) } -``` \ No newline at end of file +``` diff --git a/examples/every_test_custom_ns/k8s_test.go b/examples/every_test_custom_ns/k8s_test.go index 103639f0..8636558f 100644 --- a/examples/every_test_custom_ns/k8s_test.go +++ b/examples/every_test_custom_ns/k8s_test.go @@ -27,16 +27,14 @@ import ( func TestListPods(t *testing.T) { f := features.New("pod list"). - Assess("pods from kube-system", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { + Assess("pods from namespace", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { var pods corev1.PodList - err := cfg.Client().Resources("kube-system").List(context.TODO(), &pods) + namespace := ctx.Value(GetNamespaceKey(t)).(string) + err := cfg.Client().Resources(namespace).List(context.TODO(), &pods) if err != nil { t.Fatal(err) } - t.Logf("found %d pods", len(pods.Items)) - if len(pods.Items) == 0 { - t.Fatal("no pods in namespace kube-system") - } + t.Logf("found %d pods in namespace %s", len(pods.Items), namespace) return ctx }) diff --git a/examples/every_test_custom_ns/main_test.go b/examples/every_test_custom_ns/main_test.go index f85a1d30..75ade69d 100644 --- a/examples/every_test_custom_ns/main_test.go +++ b/examples/every_test_custom_ns/main_test.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "os" + "strings" "testing" "time" @@ -29,6 +30,9 @@ import ( "sigs.k8s.io/e2e-framework/support/kind" ) +type NamespaceCtxKey string +type ClusterCtxKey string + var testenv env.Environment func TestMain(m *testing.M) { @@ -53,11 +57,14 @@ func TestMain(m *testing.M) { cfg.WithKubeconfigFile(kubeconfig) // propagate cluster value - return context.WithValue(ctx, "cluster", cluster), nil + return context.WithValue(ctx, ClusterCtxKey("cluster"), cluster), nil }).Finish( // Teardown func: delete kind cluster func(ctx context.Context, cfg *envconf.Config) (context.Context, error) { - cluster := ctx.Value("cluster").(*kind.Cluster) // nil should be tested + cluster := ctx.Value(ClusterCtxKey("cluster")).(*kind.Cluster) // nil should be tested + if cluster == nil { + return ctx, fmt.Errorf("error getting kind cluster from context") + } if err := cluster.Destroy(); err != nil { return ctx, err } @@ -79,7 +86,7 @@ func TestMain(m *testing.M) { // so that the deleteNSForTest routine can look it up and delete it. func createNSForTest(ctx context.Context, cfg *envconf.Config, t *testing.T, runID string) (context.Context, error) { ns := envconf.RandomName(runID, 10) - ctx = context.WithValue(ctx, nsKey(t), ns) + ctx = context.WithValue(ctx, GetNamespaceKey(t), ns) t.Logf("Creating NS %v for test %v", ns, t.Name()) nsObj := v1.Namespace{} @@ -89,7 +96,7 @@ func createNSForTest(ctx context.Context, cfg *envconf.Config, t *testing.T, run // DeleteNSForTest looks up the namespace corresponding to the given test and deletes it. func deleteNSForTest(ctx context.Context, cfg *envconf.Config, t *testing.T, runID string) (context.Context, error) { - ns := fmt.Sprint(ctx.Value(nsKey(t))) + ns := fmt.Sprint(ctx.Value(GetNamespaceKey(t))) t.Logf("Deleting NS %v for test %v", ns, t.Name()) nsObj := v1.Namespace{} @@ -97,6 +104,13 @@ func deleteNSForTest(ctx context.Context, cfg *envconf.Config, t *testing.T, run return ctx, cfg.Client().Resources().Delete(ctx, &nsObj) } -func nsKey(t *testing.T) string { - return "NS-for-%v" + t.Name() +// GetNamespaceKey returns the context key for a given test +func GetNamespaceKey(t *testing.T) NamespaceCtxKey { + // When we pass t.Name() from inside an `assess` step, the name is in the form TestName/Features/Assess + if strings.Contains(t.Name(), "/") { + return NamespaceCtxKey(strings.Split(t.Name(), "/")[0]) + } + + // When pass t.Name() from inside a `testenv.BeforeEachTest` function, the name is just TestName + return NamespaceCtxKey(t.Name()) }