Skip to content

Releases: kubernetes-sigs/e2e-framework

v0.0.3

26 Aug 16:22
63fa8b0
Compare
Choose a tag to compare

v0.0.3

This release continues to make progress in making the framework usable in many real scenarios.

  • Rename project default branch to main
  • Ability to use start, create, and destroy kind clusters during tests
  • Clear way to inject klient.Client into environment config using a kubeconfig file
  • Additional resource helper function to Patch resource objects
  • Ability to test multiple features using env.Test(feat1, feat2, ...)
  • New pre-defined functions for launching kind clusters and automatically create Namespaces for tests
  • Updated examples and documentations

Example

See how the pre-defined enviroment functions can be used to create kind clusters and generate a namespace to be used for all tests in the package.

See full example here

TestMain

func TestMain(m *testing.M) {
	testenv = env.New()
	kindClusterName := envconf.RandomName("my-cluster", 16)
	namespace := envconf.RandomName("myns", 16)

	testenv.Setup(
		envfuncs.CreateKindCluster(kindClusterName),
		envfuncs.CreateNamespace(namespace),
	)

	testenv.Finish(
		envfuncs.DeleteNamespace(namespace),
		envfuncs.DestroyKindCluster(kindClusterName),
	)

	os.Exit(testenv.Run(m))
}

TestKubernetes

Note accessing the current namespace using cfg.Namespace():

func TestKubernetes(t *testing.T) {

	// feature uses pre-generated namespace (see TestMain)
	depFeature := features.New("appsv1/deployment").
		Setup(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
			// insert a deployment
			deployment := newDeployment(cfg.Namespace(), "test-deployment", 1)
			if err := cfg.Client().Resources().Create(ctx, deployment); err != nil {
				t.Fatal(err)
			}
			time.Sleep(2 * time.Second)
			return ctx
		}).
		Assess("deployment creation", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
			var dep appsv1.Deployment
			if err := cfg.Client().Resources().Get(ctx, "test-deployment", cfg.Namespace(), &dep); err != nil {
				t.Fatal(err)
			}
			if &dep != nil {
				t.Logf("deployment found: %s", dep.Name)
			}
			return context.WithValue(ctx, "test-deployment", &dep)
		}).
		Teardown(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
			dep := ctx.Value("test-deployment").(*appsv1.Deployment)
			if err := cfg.Client().Resources().Delete(ctx, dep); err != nil {
				t.Fatal(err)
			}
			return ctx
		}).Feature()

	testenv.Test(t, podFeature, depFeature)
}
...

v0.0.2

28 Jul 16:07
0402e81
Compare
Choose a tag to compare

This release introduces many necessary changes in the way that the works including:

  • Support for klieint.Client to provide centralized access to the klient types used to interact with Kubernetes
  • Introduction of package envconf to encapsulates types for environment configurations
  • Refactor of the env.Environment type to capture a context.Context value early during value construction
  • Refactor of signatures for EnvFunc and StepFunc operation types to properly propagate context values
  • Step functions and environment functions now receive envconf.Config to access environment runtime configuration
  • Updated and new examples showing how to use these changes
  • Updated documentation

Tests with value propagation using context.Context

The changes above allow test writers to construct tests using simpler abstractions. For example, the following snippet starts a kind cluster and uses context to propagate the name of the kubeconfig file and the cluster name:

var testenv = env.New()
func TestMain(m *testing.M) {
	testenv.Setup(
		func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
			cluster := envconf.RandomName("my-cluster", 16)
			kubecfg, err := createKindCluster(cluster)
			if err != nil {
				return ctx, err
			}
			return context.WithValue(context.WithValue(ctx, 1, kubecfg), 2, cluster), nil
		},
		func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
			kubecfg := ctx.Value(1).(string)
			client, err := klient.NewWithKubeConfigFile(kubecfg)
			if err != nil {
				return ctx, fmt.Errorf("create klient.Client: %w", err)
			}
			cfg.WithClient(client) // set client in envconfig
			return ctx, nil
		},
	)
...
    os.Exit(testenv.Run(m))
}

In the test function, test writers can access the environment configuration to use the klient.Client to interact with the API server as shown:

func TestListPods(t *testing.T) {
	f := features.New("example with klient package").
		Assess("get pods from kube-system", 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)
			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")
			}
			return ctx
		})

	testenv.Test(t, f.Feature())
}

See the full example here.

v0.0.1

07 Jul 18:38
f8800ea
Compare
Choose a tag to compare
v0.0.1 Pre-release
Pre-release

Initial release

This is the initial release which contains code that demonstrate the viability of this project. It includes

  • Code to help create tests using a test-harness framework to craft test code
  • A helper package (klient) to abstract the complexities of using the client-go package

The shape of the API is expected to change as we work through future release and adjust the design.