Skip to content

Commit ffe4e66

Browse files
Add e2e test for component filtering
Signed-off-by: Kate Goldenring <[email protected]>
1 parent 9668cab commit ffe4e66

File tree

8 files changed

+120
-14
lines changed

8 files changed

+120
-14
lines changed

config/crd/bases/core.spinoperator.dev_spinapps.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ spec:
189189
type: object
190190
type: object
191191
components:
192-
description: Components to be executed in this group.
192+
description: |-
193+
Components of the app to execute.
194+
195+
196+
If this is not provided all components are executed.
193197
items:
194198
type: string
195199
minItems: 1

config/manager/kustomization.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
resources:
2-
- manager.yaml
2+
- manager.yaml
3+
apiVersion: kustomize.config.k8s.io/v1beta1
4+
kind: Kustomization
5+
images:
6+
- name: ghcr.io/spinkube/spin-operator
7+
newName: ghcr.io/spinkube/spin-operator
8+
newTag: dev

e2e/component_filtering_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package e2e
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
v1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"sigs.k8s.io/e2e-framework/klient"
11+
"sigs.k8s.io/e2e-framework/klient/wait"
12+
"sigs.k8s.io/e2e-framework/klient/wait/conditions"
13+
"sigs.k8s.io/e2e-framework/pkg/envconf"
14+
"sigs.k8s.io/e2e-framework/pkg/features"
15+
16+
spinapps_v1alpha1 "github.com/spinkube/spin-operator/api/v1alpha1"
17+
"github.com/spinkube/spin-operator/e2e/helper"
18+
"github.com/stretchr/testify/require"
19+
)
20+
21+
// TestComponentFiltering checks that the operator and shim have support for running a subset of a Spin app's components
22+
func TestComponentFiltering(t *testing.T) {
23+
var client klient.Client
24+
25+
// TODO: Use an image from a sample app in this repository
26+
appImage := "ghcr.io/kate-goldenring/spin-operator/examples/spin-salutations:20241022-144454"
27+
testSpinAppName := "test-component-filtering"
28+
29+
defaultTest := features.New("default and most minimal setup").
30+
Setup(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
31+
32+
client = cfg.Client()
33+
34+
if err := spinapps_v1alpha1.AddToScheme(client.Resources(testNamespace).GetScheme()); err != nil {
35+
t.Fatalf("failed to register the spinapps_v1alpha1 types with Kubernetes scheme: %s", err)
36+
}
37+
38+
return ctx
39+
}).
40+
Assess("spin app custom resource is created", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
41+
testSpinApp := newSpinAppCR(testSpinAppName, appImage, "containerd-shim-spin", []string{"hello"})
42+
43+
if err := client.Resources().Create(ctx, testSpinApp); err != nil {
44+
t.Fatalf("Failed to create spinapp: %s", err)
45+
}
46+
return ctx
47+
}).
48+
Assess("spin app deployment and service are available", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
49+
// wait for deployment to be ready
50+
if err := wait.For(
51+
conditions.New(client.Resources()).DeploymentAvailable(testSpinAppName, testNamespace),
52+
wait.WithTimeout(3*time.Minute),
53+
wait.WithInterval(time.Second),
54+
); err != nil {
55+
t.Fatal(err)
56+
}
57+
58+
svc := &v1.ServiceList{
59+
Items: []v1.Service{
60+
{ObjectMeta: metav1.ObjectMeta{Name: testSpinAppName, Namespace: testNamespace}},
61+
},
62+
}
63+
64+
if err := wait.For(
65+
conditions.New(client.Resources()).ResourcesFound(svc),
66+
wait.WithTimeout(3*time.Minute),
67+
wait.WithInterval(500*time.Millisecond),
68+
); err != nil {
69+
t.Fatal(err)
70+
}
71+
return ctx
72+
}).
73+
Assess("spin app is only serving hello component", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
74+
helper.EnsureDebugContainer(t, ctx, cfg, testNamespace)
75+
76+
_, status, err := helper.CurlSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/hi", "")
77+
78+
require.NoError(t, err)
79+
require.Equal(t, 200, status)
80+
81+
_, status, err = helper.CurlSpinApp(t, ctx, cfg, testNamespace, testSpinAppName, "/bye", "")
82+
83+
require.NoError(t, err)
84+
require.Equal(t, 404, status)
85+
86+
return ctx
87+
}).
88+
Feature()
89+
testEnv.Test(t, defaultTest)
90+
}

e2e/default_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestDefaultSetup(t *testing.T) {
3030
Setup(func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
3131
client = cfg.Client()
3232

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

72-
func newSpinAppCR(name, image, executor string) *spinapps_v1alpha1.SpinApp {
73-
return &spinapps_v1alpha1.SpinApp{
72+
func newSpinAppCR(name, image, executor string, components []string) *spinapps_v1alpha1.SpinApp {
73+
app := spinapps_v1alpha1.SpinApp{
7474
ObjectMeta: metav1.ObjectMeta{
7575
Name: name,
7676
Namespace: testNamespace,
@@ -81,4 +81,8 @@ func newSpinAppCR(name, image, executor string) *spinapps_v1alpha1.SpinApp {
8181
Executor: executor,
8282
},
8383
}
84+
if components != nil {
85+
app.Spec.Components = components
86+
}
87+
return &app
8488
}

e2e/helper/helper.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ func EnsureDebugContainer(t *testing.T, ctx context.Context, cfg *envconf.Config
4949
}
5050
}
5151

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

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

7271
podName := debugPod.Name
7372

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

7678
var stdout, stderr bytes.Buffer
7779
if err := client.Resources().ExecInPod(ctx, namespace, podName, debugDeploymentName, command, &stdout, &stderr); err != nil {

e2e/k3d_provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"sigs.k8s.io/e2e-framework/support/utils"
1515
)
1616

17-
const k3dImage = "ghcr.io/spinkube/containerd-shim-spin/k3d:v0.13.1"
17+
const k3dImage = "ghcr.io/spinkube/containerd-shim-spin/k3d:20241015-215845-g71c8351"
1818

1919
var k3dBin = "k3d"
2020

e2e/redis_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func TestShimRedis(t *testing.T) {
9292
Assess("spin app is using redis", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
9393
helper.EnsureDebugContainer(t, ctx, cfg, testNamespace)
9494

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

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

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

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

e2e/spintainer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestSpintainer(t *testing.T) {
3838
return ctx
3939
}).
4040
Assess("spin app custom resource is created", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
41-
testSpinApp := newSpinAppCR(testSpinAppName, helloWorldImage, "spintainer")
41+
testSpinApp := newSpinAppCR(testSpinAppName, helloWorldImage, "spintainer", nil)
4242

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

0 commit comments

Comments
 (0)