Skip to content

Commit e7ad502

Browse files
authored
Add github integration tests (#19)
Signed-off-by: Nitish Tiwari <[email protected]>
1 parent fc1c9e1 commit e7ad502

File tree

4 files changed

+268
-3
lines changed

4 files changed

+268
-3
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,12 @@ test-unit: $(SETUP_ENVTEST) $(GOTESTSUM) $(HELM) ## Run unit
325325
KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" $(GOTESTSUM) --junitfile=.coverage/junit.xml --format testname -- -mod=vendor \
326326
-covermode=atomic -coverprofile=.coverage/cover.out -p=4 ./internal/controller/...
327327

328+
.PHONY: test-integration-github
329+
test-integration-github: $(SETUP_ENVTEST) $(GOTESTSUM)
330+
@mkdir -p $(shell pwd)/.coverage
331+
KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" $(GOTESTSUM) --junitfile=../.coverage/junit.xml --format testname -- -mod=vendor \
332+
-covermode=atomic -coverprofile=../.coverage/cover.out -p=1 ./internal/test/integration/github/...
333+
328334
##@ Verify
329335
##########
330336
# Verify #
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
package github
16+
17+
import (
18+
"testing"
19+
"time"
20+
21+
"github.com/SovereignCloudStack/cluster-stack-operator/internal/controller"
22+
"github.com/SovereignCloudStack/cluster-stack-operator/internal/test/helpers"
23+
githubclient "github.com/SovereignCloudStack/cluster-stack-operator/pkg/github/client"
24+
"github.com/SovereignCloudStack/cluster-stack-operator/pkg/kube"
25+
. "github.com/onsi/ginkgo/v2"
26+
. "github.com/onsi/gomega"
27+
ctrl "sigs.k8s.io/controller-runtime"
28+
controllerruntimecontroller "sigs.k8s.io/controller-runtime/pkg/controller"
29+
)
30+
31+
const (
32+
timeout = time.Second * 20
33+
interval = 1000 * time.Millisecond
34+
)
35+
36+
func TestControllers(t *testing.T) {
37+
RegisterFailHandler(Fail)
38+
RunSpecs(t, "Controller Suite")
39+
}
40+
41+
var (
42+
ctx = ctrl.SetupSignalHandler()
43+
testEnv *helpers.TestEnvironment
44+
)
45+
46+
var _ = BeforeSuite(func() {
47+
testEnv = helpers.NewTestEnvironment()
48+
Expect((&controller.ClusterStackReconciler{
49+
Client: testEnv.Manager.GetClient(),
50+
GitHubClientFactory: githubclient.NewFactory(),
51+
ReleaseDirectory: "/tmp/downloads",
52+
}).SetupWithManager(ctx, testEnv.Manager, controllerruntimecontroller.Options{})).To(Succeed())
53+
Expect((&controller.ClusterStackReleaseReconciler{
54+
Client: testEnv.Manager.GetClient(),
55+
RESTConfig: testEnv.Manager.GetConfig(),
56+
KubeClientFactory: kube.NewFactory(),
57+
GitHubClientFactory: githubclient.NewFactory(),
58+
ReleaseDirectory: "/tmp/downloads",
59+
}).SetupWithManager(ctx, testEnv.Manager, controllerruntimecontroller.Options{})).To(Succeed())
60+
61+
go func() {
62+
defer GinkgoRecover()
63+
Expect(testEnv.StartManager(ctx)).To(Succeed())
64+
}()
65+
<-testEnv.Manager.Elected()
66+
})
67+
68+
var _ = AfterSuite(func() {
69+
Expect(testEnv.Stop()).To(Succeed())
70+
})
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package github
15+
16+
import (
17+
csov1alpha1 "github.com/SovereignCloudStack/cluster-stack-operator/api/v1alpha1"
18+
"github.com/SovereignCloudStack/cluster-stack-operator/pkg/clusterstack"
19+
"github.com/SovereignCloudStack/cluster-stack-operator/pkg/test/utils"
20+
csv "github.com/SovereignCloudStack/cluster-stack-operator/pkg/version"
21+
. "github.com/onsi/ginkgo/v2"
22+
. "github.com/onsi/gomega"
23+
corev1 "k8s.io/api/core/v1"
24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
"k8s.io/apimachinery/pkg/types"
26+
"sigs.k8s.io/controller-runtime/pkg/client"
27+
)
28+
29+
const (
30+
provider = "docker"
31+
name = "ferrol"
32+
kubernetesVersion = "1.27"
33+
version = "v1"
34+
)
35+
36+
var _ = Describe("ClusterStackReconciler", func() {
37+
Context("auto subscribe false", func() {
38+
var (
39+
clusterStack *csov1alpha1.ClusterStack
40+
testNs *corev1.Namespace
41+
clusterStackReleaseKey types.NamespacedName
42+
)
43+
44+
BeforeEach(func() {
45+
var err error
46+
testNs, err = testEnv.CreateNamespace(ctx, "clusterstack-integration")
47+
Expect(err).NotTo(HaveOccurred())
48+
49+
clusterStack = &csov1alpha1.ClusterStack{
50+
ObjectMeta: metav1.ObjectMeta{
51+
Name: "test1",
52+
Namespace: testNs.Name,
53+
},
54+
Spec: csov1alpha1.ClusterStackSpec{
55+
Provider: provider,
56+
Name: name,
57+
KubernetesVersion: kubernetesVersion,
58+
Versions: []string{version},
59+
AutoSubscribe: false,
60+
NoProvider: true,
61+
},
62+
}
63+
Expect(testEnv.Create(ctx, clusterStack)).To(Succeed())
64+
65+
cs, err := clusterstack.New(clusterStack.Spec.Provider, clusterStack.Spec.Name, clusterStack.Spec.KubernetesVersion, version)
66+
Expect(err).To(BeNil())
67+
68+
clusterStackReleaseKey = types.NamespacedName{Name: cs.String(), Namespace: testNs.Name}
69+
})
70+
71+
AfterEach(func() {
72+
Expect(testEnv.Cleanup(ctx, testNs, clusterStack)).To(Succeed())
73+
})
74+
75+
It("creates the cluster stack release object", func() {
76+
Eventually(func() error {
77+
var clusterStackRelease csov1alpha1.ClusterStackRelease
78+
return testEnv.Get(ctx, clusterStackReleaseKey, &clusterStackRelease)
79+
}, timeout, interval).Should(BeNil())
80+
})
81+
82+
It("sets ClusterStackReleaseDownloaded condition once ClusterStackRelease object is created", func() {
83+
Eventually(func() bool {
84+
var clusterStackRelease csov1alpha1.ClusterStackRelease
85+
return utils.IsPresentAndTrue(ctx, testEnv.Client, clusterStackReleaseKey, &clusterStackRelease, csov1alpha1.ClusterStackReleaseAssetsReadyCondition)
86+
}, timeout, interval).Should(BeTrue())
87+
})
88+
89+
It("sets ClusterStackRelease Status ready after ClusterStackRelease object is created", func() {
90+
Eventually(func() bool {
91+
var foundClusterStackRelease csov1alpha1.ClusterStackRelease
92+
if err := testEnv.Get(ctx, clusterStackReleaseKey, &foundClusterStackRelease); err == nil {
93+
return foundClusterStackRelease.Status.Ready
94+
}
95+
return false
96+
}, timeout, interval).Should(BeTrue())
97+
})
98+
})
99+
100+
Context("auto subscribe true", func() {
101+
var (
102+
clusterStack *csov1alpha1.ClusterStack
103+
testNs *corev1.Namespace
104+
clusterStackKey types.NamespacedName
105+
clusterStackReleaseKey types.NamespacedName
106+
)
107+
108+
BeforeEach(func() {
109+
var err error
110+
testNs, err = testEnv.CreateNamespace(ctx, "clusterstack-integration")
111+
Expect(err).NotTo(HaveOccurred())
112+
113+
clusterStack = &csov1alpha1.ClusterStack{
114+
ObjectMeta: metav1.ObjectMeta{
115+
Name: "test2",
116+
Namespace: testNs.Name,
117+
},
118+
Spec: csov1alpha1.ClusterStackSpec{
119+
Provider: provider,
120+
Name: name,
121+
KubernetesVersion: kubernetesVersion,
122+
Versions: []string{},
123+
AutoSubscribe: true,
124+
NoProvider: true,
125+
ProviderRef: nil,
126+
},
127+
}
128+
Expect(testEnv.Create(ctx, clusterStack)).To(Succeed())
129+
130+
clusterStackKey = types.NamespacedName{Name: clusterStack.Name, Namespace: testNs.Name}
131+
132+
cs, err := clusterstack.New(clusterStack.Spec.Provider, clusterStack.Spec.Name, clusterStack.Spec.KubernetesVersion, version)
133+
Expect(err).To(BeNil())
134+
135+
clusterStackReleaseKey = types.NamespacedName{Name: cs.String(), Namespace: testNs.Name}
136+
})
137+
138+
AfterEach(func() {
139+
Expect(testEnv.Cleanup(ctx, testNs, clusterStack)).To(Succeed())
140+
})
141+
142+
It("finds the new cluster stack release", func() {
143+
Eventually(func() bool {
144+
var clusterStackReleaseList csov1alpha1.ClusterStackReleaseList
145+
if err := testEnv.List(ctx, &clusterStackReleaseList, &client.ListOptions{Namespace: testNs.Name}); err != nil {
146+
testEnv.GetLogger().Error(err, "failed to get clusterStackList")
147+
return false
148+
}
149+
150+
var clusterStack csov1alpha1.ClusterStack
151+
if err := testEnv.Get(ctx, clusterStackKey, &clusterStack); err != nil {
152+
testEnv.GetLogger().Error(err, "failed to get clusterStack", "key", clusterStackKey)
153+
return false
154+
}
155+
156+
for _, csrSummary := range clusterStack.Status.Summary {
157+
v, err := csv.New(csrSummary.Name)
158+
Expect(err).To(BeNil())
159+
160+
oldVersion, err := csv.New(version)
161+
Expect(err).To(BeNil())
162+
163+
cmp, err := v.Compare(oldVersion)
164+
Expect(err).To(BeNil())
165+
166+
if cmp >= 0 {
167+
return true
168+
}
169+
}
170+
return false
171+
}, timeout, interval).Should(BeTrue())
172+
})
173+
174+
It("creates the new cluster stack release", func() {
175+
Eventually(func() bool {
176+
var clusterStackRelease csov1alpha1.ClusterStackRelease
177+
if err := testEnv.Get(ctx, clusterStackReleaseKey, &clusterStackRelease); err != nil {
178+
testEnv.GetLogger().Error(err, "failed to get clusterStackRelease", "key", clusterStackReleaseKey)
179+
return false
180+
}
181+
182+
return true
183+
}, timeout, interval).Should(BeTrue())
184+
})
185+
})
186+
})

pkg/test/utils/conditions.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package utils
1919
import (
2020
"context"
2121

22-
. "github.com/onsi/gomega"
2322
corev1 "k8s.io/api/core/v1"
2423
"k8s.io/apimachinery/pkg/types"
2524
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
@@ -29,7 +28,9 @@ import (
2928

3029
// IsPresentAndFalseWithReason returns if condition is present in the object status with false and a reason or not.
3130
func IsPresentAndFalseWithReason(ctx context.Context, c client.Client, key types.NamespacedName, getter conditions.Getter, condition clusterv1.ConditionType, reason string) bool {
32-
ExpectWithOffset(1, c.Get(ctx, key, getter)).To(Succeed())
31+
if err := c.Get(ctx, key, getter); err != nil {
32+
return false
33+
}
3334
if !conditions.Has(getter, condition) {
3435
return false
3536
}
@@ -40,7 +41,9 @@ func IsPresentAndFalseWithReason(ctx context.Context, c client.Client, key types
4041

4142
// IsPresentAndTrue returns if condition is present in the object status with true or not.
4243
func IsPresentAndTrue(ctx context.Context, c client.Client, key types.NamespacedName, getter conditions.Getter, condition clusterv1.ConditionType) bool {
43-
ExpectWithOffset(1, c.Get(ctx, key, getter)).To(Succeed())
44+
if err := c.Get(ctx, key, getter); err != nil {
45+
return false
46+
}
4447
if !conditions.Has(getter, condition) {
4548
return false
4649
}

0 commit comments

Comments
 (0)