Skip to content

Commit cf494ff

Browse files
authored
Merge pull request #90 from harshanarayana/feature/git-83/enable-helm-support
GIT-83: enable helm support for test workflow
2 parents 7c2fa1b + 0c8ca84 commit cf494ff

File tree

13 files changed

+601
-2
lines changed

13 files changed

+601
-2
lines changed

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,12 @@ update-deps-go: ## Update all golang dependencies for this repo
5555

5656
##@ Tests
5757

58-
.PHONY: test
59-
test: ## Runs golang unit tests
58+
.PHONY: install-helm test
59+
60+
install-helm: ## Install Helm toolchain for 3rd party integration
61+
./hack/install-helm.sh
62+
63+
test: install-helm ## Runs golang unit tests
6064
./hack/test-go.sh
6165

6266
##@ Helpers
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Third Party Integration
2+
3+
This section of the repository contains the example of how the third party tooling are integrated into the
4+
`e2e-framework`
5+
6+
1. [Helm](./helm)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Helm Integration
2+
3+
This section of the document gives you an example of how to integrate the helm chart related workflow
4+
into the `e2e-framework` while writing your tests.
5+
6+
## Pre-Requisites
7+
8+
1. `Helm3` Installed on your system where the tests are being run
9+
10+
## How does `TestLocalHelmChartWorkflow` test work ?
11+
12+
1. It creates a Kind Cluster with `third-party` prefix
13+
2. Creates a new namespace with `third-party` prefix
14+
3. Deploys the local helm chart under [example_chart](testdata/example_chart) with a name `example` to namespace created in Step #2
15+
5. Run `helm test example` command to run a test on the Helm chart deployed in step #3
16+
17+
## How does `TestHelmChartRepoWorkflow` test work?
18+
19+
1. It creates a Kind Cluster with `third-party` prefix
20+
2. Creates a new namespace with `third-party` prefix
21+
3. Adds the `nginx-stable` helm repo and triggers a repo update workflow
22+
4. Installs the helm chart using `nginx-stable/nginx-ingress` (without Wait mode) with name `nginx`
23+
6. Waits for the Deployment to be up and running
24+
7. Runs the `helm test nginx` command to run a basic helm test
25+
26+
27+
## How to Run the Tests
28+
29+
```bash
30+
go test -c -o helm.test .
31+
32+
./helm.test --v 4
33+
```
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package helm
18+
19+
import (
20+
"context"
21+
"os"
22+
"path/filepath"
23+
"testing"
24+
25+
appsv1 "k8s.io/api/apps/v1"
26+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
28+
"sigs.k8s.io/e2e-framework/klient/k8s"
29+
"sigs.k8s.io/e2e-framework/klient/wait"
30+
"sigs.k8s.io/e2e-framework/klient/wait/conditions"
31+
"sigs.k8s.io/e2e-framework/pkg/envconf"
32+
"sigs.k8s.io/e2e-framework/pkg/features"
33+
"sigs.k8s.io/e2e-framework/third_party/helm"
34+
)
35+
36+
var curDir, _ = os.Getwd()
37+
38+
func TestHelmChartRepoWorkflow(t *testing.T) {
39+
feature := features.New("Repo based helm chart workflow").
40+
Setup(func(ctx context.Context, t *testing.T, config *envconf.Config) context.Context {
41+
manager := helm.New(config.KubeconfigFile())
42+
err := manager.RunRepo(helm.WithArgs("add", "nginx-stable", "https://helm.nginx.com/stable"))
43+
if err != nil {
44+
t.Fatal("failed to add nginx helm chart repo")
45+
}
46+
err = manager.RunRepo(helm.WithArgs("update"))
47+
if err != nil {
48+
t.Fatal("failed to upgrade helm repo")
49+
}
50+
err = manager.RunInstall(helm.WithName("nginx"), helm.WithNamespace(namespace), helm.WithReleaseName("nginx-stable/nginx-ingress"))
51+
if err != nil {
52+
t.Fatal("failed to install nginx Helm chart")
53+
}
54+
return ctx
55+
}).
56+
Assess("Deployment is running successfully", func(ctx context.Context, t *testing.T, config *envconf.Config) context.Context {
57+
deployment := &appsv1.Deployment{
58+
ObjectMeta: v1.ObjectMeta{
59+
Name: "nginx-nginx-ingress",
60+
Namespace: namespace,
61+
},
62+
Spec: appsv1.DeploymentSpec{},
63+
}
64+
err := wait.For(conditions.New(config.Client().Resources()).ResourceScaled(deployment, func(object k8s.Object) int32 {
65+
return object.(*appsv1.Deployment).Status.ReadyReplicas
66+
}, 1))
67+
if err != nil {
68+
t.Fatal("failed waiting for the Deployment to reach a ready state")
69+
}
70+
return ctx
71+
}).
72+
Assess("run Chart Tests", func(ctx context.Context, t *testing.T, config *envconf.Config) context.Context {
73+
manager := helm.New(config.KubeconfigFile())
74+
err := manager.RunTest(helm.WithArgs("nginx"), helm.WithNamespace(namespace))
75+
if err != nil {
76+
t.Fatal("failed waiting for the Deployment to reach a ready state")
77+
}
78+
return ctx
79+
}).
80+
Teardown(func(ctx context.Context, t *testing.T, config *envconf.Config) context.Context {
81+
manager := helm.New(config.KubeconfigFile())
82+
err := manager.RunRepo(helm.WithArgs("remove", "nginx-stable"))
83+
if err != nil {
84+
t.Fatal("cleanup of the helm repo failed")
85+
}
86+
return ctx
87+
}).Feature()
88+
89+
testEnv.Test(t, feature)
90+
}
91+
92+
func TestLocalHelmChartWorkflow(t *testing.T) {
93+
feature := features.New("Local Helm chart workflow").
94+
Setup(func(ctx context.Context, t *testing.T, config *envconf.Config) context.Context {
95+
manager := helm.New(config.KubeconfigFile())
96+
err := manager.RunInstall(helm.WithName("example"), helm.WithNamespace(namespace), helm.WithChart(filepath.Join(curDir, "testdata", "example_chart")), helm.WithWait(), helm.WithTimeout("10m"))
97+
if err != nil {
98+
t.Fatal("failed to invoke helm install operation due to an error", err)
99+
}
100+
return ctx
101+
}).
102+
Assess("Deployment Is Running Successfully", func(ctx context.Context, t *testing.T, config *envconf.Config) context.Context {
103+
deployment := &appsv1.Deployment{
104+
ObjectMeta: v1.ObjectMeta{
105+
Name: "example",
106+
Namespace: namespace,
107+
},
108+
Spec: appsv1.DeploymentSpec{},
109+
}
110+
err := wait.For(conditions.New(config.Client().Resources()).ResourceScaled(deployment, func(object k8s.Object) int32 {
111+
return object.(*appsv1.Deployment).Status.ReadyReplicas
112+
}, 1))
113+
if err != nil {
114+
t.Fatal("failed waiting for the Deployment to reach a ready state")
115+
}
116+
return ctx
117+
}).
118+
Assess("run Helm Test Workflow", func(ctx context.Context, t *testing.T, config *envconf.Config) context.Context {
119+
manager := helm.New(config.KubeconfigFile())
120+
err := manager.RunTest(helm.WithName("example"), helm.WithNamespace(namespace))
121+
if err != nil {
122+
t.Fatal("failed to perform helm test operation to check if the chart deployment is good")
123+
}
124+
return ctx
125+
}).Feature()
126+
127+
testEnv.Test(t, feature)
128+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package helm
18+
19+
import (
20+
"os"
21+
"testing"
22+
23+
"sigs.k8s.io/e2e-framework/pkg/env"
24+
"sigs.k8s.io/e2e-framework/pkg/envconf"
25+
"sigs.k8s.io/e2e-framework/pkg/envfuncs"
26+
)
27+
28+
var (
29+
testEnv env.Environment
30+
namespace string
31+
kindClusterName string
32+
)
33+
34+
func TestMain(m *testing.M) {
35+
cfg, _ := envconf.NewFromFlags()
36+
testEnv = env.NewWithConfig(cfg)
37+
kindClusterName = envconf.RandomName("third-party", 16)
38+
namespace = envconf.RandomName("third-party", 16)
39+
40+
testEnv.Setup(
41+
envfuncs.CreateKindCluster(kindClusterName),
42+
envfuncs.CreateNamespace(namespace),
43+
)
44+
45+
testEnv.Finish(
46+
envfuncs.DeleteNamespace(namespace),
47+
envfuncs.DestroyKindCluster(kindClusterName),
48+
)
49+
os.Exit(testEnv.Run(m))
50+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v2
2+
name: example
3+
description: An example Helm chart for Kubernetes e2e-framework
4+
type: application
5+
version: 0.1.0
6+
appVersion: "1.16.0"
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ .Release.Name }}
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
app: {{ .Release.Name }}
8+
spec:
9+
replicas: {{ .Values.replicaCount }}
10+
selector:
11+
matchLabels:
12+
app: {{ .Release.Name }}
13+
template:
14+
metadata:
15+
labels:
16+
app: {{ .Release.Name }}
17+
spec:
18+
automountServiceAccountToken: true
19+
containers:
20+
- name: {{ .Chart.Name }}
21+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
22+
imagePullPolicy: {{ .Values.image.pullPolicy }}
23+
ports:
24+
- name: http
25+
containerPort: {{ .Values.service.port }}
26+
protocol: TCP
27+
livenessProbe:
28+
httpGet:
29+
path: /
30+
port: http
31+
readinessProbe:
32+
httpGet:
33+
path: /
34+
port: http
35+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: {{ .Release.Name }}
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
app: {{ .Release.Name }}
8+
spec:
9+
type: {{ .Values.service.type }}
10+
ports:
11+
- port: {{ .Values.service.port }}
12+
targetPort: http
13+
protocol: TCP
14+
name: http
15+
selector:
16+
app: {{ .Release.Name }}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: "{{ .Release.Name }}-test-connection"
5+
namespace: {{ .Release.Namespace }}
6+
annotations:
7+
"helm.sh/hook": test
8+
spec:
9+
containers:
10+
- name: wget
11+
image: busybox
12+
command: ['wget']
13+
args: ['{{ .Release.Name }}:{{ .Values.service.port }}']
14+
restartPolicy: Never

0 commit comments

Comments
 (0)