Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component filtering e2e test #328

Merged
merged 2 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion config/crd/bases/core.spinoperator.dev_spinapps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ spec:
type: object
type: object
components:
description: Components to be executed in this group.
description: |-
Components of the app to execute.


If this is not provided all components are executed.
calebschoepp marked this conversation as resolved.
Show resolved Hide resolved
items:
type: string
minItems: 1
Expand Down
10 changes: 7 additions & 3 deletions e2e/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestDefaultSetup(t *testing.T) {
Setup(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
client = cfg.Client()

testSpinApp := newSpinAppCR(testSpinAppName, helloWorldImage, "containerd-shim-spin")
testSpinApp := newSpinAppCR(testSpinAppName, helloWorldImage, "containerd-shim-spin", nil)
if err := client.Resources().Create(ctx, testSpinApp); err != nil {
t.Fatalf("Failed to create spinapp: %s", err)
}
Expand Down Expand Up @@ -69,8 +69,8 @@ func TestDefaultSetup(t *testing.T) {
testEnv.Test(t, defaultTest)
}

func newSpinAppCR(name, image, executor string) *spinapps_v1alpha1.SpinApp {
return &spinapps_v1alpha1.SpinApp{
func newSpinAppCR(name, image, executor string, components []string) *spinapps_v1alpha1.SpinApp {
app := spinapps_v1alpha1.SpinApp{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: testNamespace,
Expand All @@ -81,4 +81,8 @@ func newSpinAppCR(name, image, executor string) *spinapps_v1alpha1.SpinApp {
Executor: executor,
},
}
if components != nil {
app.Spec.Components = components
}
return &app
}
12 changes: 7 additions & 5 deletions e2e/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ func EnsureDebugContainer(t *testing.T, ctx context.Context, cfg *envconf.Config
}
}

// PostToSpinApp is a crude function for using the debug pod to post to a spin app
// within the cluster. It allows customization of the route, but all requests
// are currently `POST`.
func PostToSpinApp(t *testing.T, ctx context.Context, cfg *envconf.Config, namespace, spinAppName, route, body string) (string, int, error) {
// CurlSpinApp is a crude function for using the debug pod to send a HTTP request to a spin app
// within the cluster. It allows customization of the route, and all requests are GET requests unless a non-empty body is provided.
func CurlSpinApp(t *testing.T, ctx context.Context, cfg *envconf.Config, namespace, spinAppName, route, body string) (string, int, error) {
t.Helper()

client, err := cfg.NewClient()
Expand All @@ -71,7 +70,10 @@ func PostToSpinApp(t *testing.T, ctx context.Context, cfg *envconf.Config, names

podName := debugPod.Name

command := []string{"curl", "-s", "-m", "5", "-w", "\n%{http_code}\n", "http://" + spinAppName + "." + namespace + route, "--data", body, "-o", "-"}
command := []string{"curl", "--silent", "--max-time", "5", "--write-out", "\n%{http_code}\n", "http://" + spinAppName + "." + namespace + route, "--output", "-"}
if body != "" {
command = append(command, "--data", body)
}

var stdout, stderr bytes.Buffer
if err := client.Resources().ExecInPod(ctx, namespace, podName, debugDeploymentName, command, &stdout, &stderr); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion e2e/k3d_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"sigs.k8s.io/e2e-framework/support/utils"
)

const k3dImage = "ghcr.io/spinkube/containerd-shim-spin/k3d:v0.13.1"
const k3dImage = "ghcr.io/spinkube/containerd-shim-spin/k3d:20241015-215845-g71c8351"
calebschoepp marked this conversation as resolved.
Show resolved Hide resolved

var k3dBin = "k3d"

Expand Down
4 changes: 2 additions & 2 deletions e2e/redis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func TestShimRedis(t *testing.T) {
Assess("spin app is using redis", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
helper.EnsureDebugContainer(t, ctx, cfg, testNamespace)

_, status, err := helper.PostToSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/api", "{\"key\": \"foo\", \"value\": \"bar\"}")
_, status, err := helper.CurlSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/api", "{\"key\": \"foo\", \"value\": \"bar\"}")

require.NoError(t, err)
require.Equal(t, 200, status)
Expand Down Expand Up @@ -194,7 +194,7 @@ func TestSpintainerRedis(t *testing.T) {
Assess("spin app is using redis", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
helper.EnsureDebugContainer(t, ctx, cfg, testNamespace)

_, status, err := helper.PostToSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/api", "{\"key\": \"foo\", \"value\": \"bar\"}")
_, status, err := helper.CurlSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/api", "{\"key\": \"foo\", \"value\": \"bar\"}")

require.NoError(t, err)
require.Equal(t, 200, status)
Expand Down
90 changes: 90 additions & 0 deletions e2e/selective_deployment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package e2e

import (
"context"
"testing"
"time"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/e2e-framework/klient"
"sigs.k8s.io/e2e-framework/klient/wait"
"sigs.k8s.io/e2e-framework/klient/wait/conditions"
"sigs.k8s.io/e2e-framework/pkg/envconf"
"sigs.k8s.io/e2e-framework/pkg/features"

spinapps_v1alpha1 "github.com/spinkube/spin-operator/api/v1alpha1"
"github.com/spinkube/spin-operator/e2e/helper"
"github.com/stretchr/testify/require"
)

// TestSelectiveDeployment checks that the operator and shim have support for running a subset of a Spin app's components
func TestSelectiveDeployment(t *testing.T) {
var client klient.Client

// TODO: Use an image from a sample app in this repository
appImage := "ghcr.io/kate-goldenring/spin-operator/examples/spin-salutations:20241022-144454"
testSpinAppName := "test-component-filtering"

defaultTest := features.New("default and most minimal setup").
Setup(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {

client = cfg.Client()

if err := spinapps_v1alpha1.AddToScheme(client.Resources(testNamespace).GetScheme()); err != nil {
t.Fatalf("failed to register the spinapps_v1alpha1 types with Kubernetes scheme: %s", err)
}

return ctx
}).
Assess("spin app custom resource is created", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
testSpinApp := newSpinAppCR(testSpinAppName, appImage, "containerd-shim-spin", []string{"hello"})

if err := client.Resources().Create(ctx, testSpinApp); err != nil {
t.Fatalf("Failed to create spinapp: %s", err)
}
return ctx
}).
Assess("spin app deployment and service are available", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
// wait for deployment to be ready
if err := wait.For(
conditions.New(client.Resources()).DeploymentAvailable(testSpinAppName, testNamespace),
wait.WithTimeout(3*time.Minute),
wait.WithInterval(time.Second),
); err != nil {
t.Fatal(err)
}

svc := &v1.ServiceList{
Items: []v1.Service{
{ObjectMeta: metav1.ObjectMeta{Name: testSpinAppName, Namespace: testNamespace}},
},
}

if err := wait.For(
conditions.New(client.Resources()).ResourcesFound(svc),
wait.WithTimeout(3*time.Minute),
wait.WithInterval(500*time.Millisecond),
); err != nil {
t.Fatal(err)
}
return ctx
}).
Assess("spin app is only serving hello component", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
helper.EnsureDebugContainer(t, ctx, cfg, testNamespace)

_, status, err := helper.CurlSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/hi", "")

require.NoError(t, err)
require.Equal(t, 200, status)

_, status, err = helper.CurlSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/bye", "")

require.NoError(t, err)
require.Equal(t, 404, status)

return ctx
}).
Feature()
testEnv.Test(t, defaultTest)
}
2 changes: 1 addition & 1 deletion e2e/spintainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestSpintainer(t *testing.T) {
return ctx
}).
Assess("spin app custom resource is created", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
testSpinApp := newSpinAppCR(testSpinAppName, helloWorldImage, "spintainer")
testSpinApp := newSpinAppCR(testSpinAppName, helloWorldImage, "spintainer", nil)

if err := client.Resources().Create(ctx, newSpintainerExecutor(testNamespace)); controllerruntimeclient.IgnoreAlreadyExists(err) != nil {
t.Fatalf("Failed to create spinappexecutor: %s", err)
Expand Down
Loading