Skip to content

Commit 6af810d

Browse files
committed
chore(testcontainers): Prepare external Grafana instance
1 parent 90d958e commit 6af810d

File tree

2 files changed

+130
-37
lines changed

2 files changed

+130
-37
lines changed

controllers/controller_shared_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ var _ = Describe("GetMatchingInstances functions", Ordered, func() {
435435
It("Finds all ready instances when instanceSelector is empty", func() {
436436
instances, err := GetScopedMatchingInstances(ctx, k8sClient, matchAllFolder)
437437
Expect(err).ToNot(HaveOccurred())
438-
Expect(instances).To(HaveLen(3 + 1)) // +1 To account for instance created in suite_test.go to provoke ApplyFailed conditions
438+
Expect(instances).To(HaveLen(3 + 2)) // +2 To account for instances created in controllers/suite_test.go to provoke conditions
439439
})
440440
It("Finds all ready and Matching instances", func() {
441441
instances, err := GetScopedMatchingInstances(ctx, k8sClient, &allowFolder)

controllers/suite_test.go

Lines changed: 129 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,47 @@ import (
2323
"testing"
2424
"time"
2525

26-
. "github.com/onsi/ginkgo/v2"
27-
. "github.com/onsi/gomega"
26+
corev1 "k8s.io/api/core/v1"
2827
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/apimachinery/pkg/types"
2929
"k8s.io/client-go/kubernetes/scheme"
3030
"sigs.k8s.io/controller-runtime/pkg/client"
3131
"sigs.k8s.io/controller-runtime/pkg/envtest"
3232
logf "sigs.k8s.io/controller-runtime/pkg/log"
3333
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3434

35+
"github.com/docker/go-connections/nat"
3536
"github.com/grafana/grafana-operator/v5/api/v1beta1"
3637
"github.com/grafana/grafana-operator/v5/controllers/config"
38+
39+
. "github.com/onsi/ginkgo/v2"
40+
. "github.com/onsi/gomega"
41+
"github.com/testcontainers/testcontainers-go"
42+
"github.com/testcontainers/testcontainers-go/wait"
3743
//+kubebuilder:scaffold:imports
3844
)
3945

4046
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
4147
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
4248

49+
const (
50+
grafanaName = "external-grafana"
51+
grafanaUser = "root"
52+
grafanaPass = "secret"
53+
)
54+
4355
var (
44-
k8sClient client.Client
45-
testEnv *envtest.Environment
46-
testCtx context.Context
56+
k8sClient client.Client
57+
testEnv *envtest.Environment
58+
testCtx context.Context
59+
grafanaContainer testcontainers.Container
60+
externalGrafanaCr *v1beta1.Grafana
61+
62+
grafanaPort = nat.Port(fmt.Sprint(config.GrafanaHTTPPort)) //nolint
63+
grafanaCredentials = map[string]string{
64+
"GF_SECURITY_ADMIN_USER": grafanaUser,
65+
"GF_SECURITY_ADMIN_PASSWORD": grafanaPass,
66+
}
4767
)
4868

4969
func TestAPIs(t *testing.T) {
@@ -78,20 +98,72 @@ var _ = BeforeSuite(func() {
7898

7999
//+kubebuilder:scaffold:scheme
80100

101+
By("Instantiating k8sClient")
81102
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
82103
Expect(err).NotTo(HaveOccurred())
83104
Expect(k8sClient).NotTo(BeNil())
84105

85-
// NOTE(Baarsgaard) Ensure k8sClient is 100% ready
86-
// ENVTEST sometimes fail all tests with a 401 Unauthorized
87-
time.Sleep(100 * time.Millisecond)
106+
By("Starting Grafana TestContainer")
107+
grafanaContainer, err = testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
108+
Started: true,
109+
ContainerRequest: testcontainers.ContainerRequest{
110+
Name: fmt.Sprintf("%s-%d", grafanaName, GinkgoRandomSeed()),
111+
Image: fmt.Sprintf("%s:%s", config.GrafanaImage, config.GrafanaVersion),
112+
ExposedPorts: []string{grafanaPort.Port()},
113+
WaitingFor: wait.ForAll(
114+
wait.ForListeningPort(grafanaPort),
115+
wait.ForHTTP("/api/frontend/settings").
116+
WithPort(grafanaPort).
117+
WithBasicAuth(grafanaUser, grafanaPass).
118+
WithStartupTimeout(8*time.Second),
119+
),
120+
Env: grafanaCredentials,
121+
},
122+
})
123+
Expect(err).NotTo(HaveOccurred())
124+
125+
port, err := grafanaContainer.MappedPort(testCtx, grafanaPort)
126+
Expect(err).NotTo(HaveOccurred())
127+
128+
createSharedTestCRs(port.Port())
129+
})
130+
131+
var _ = AfterSuite(func() {
132+
By("tearing down the test environment")
133+
testcontainers.CleanupContainer(GinkgoTB(), grafanaContainer)
134+
Expect(testEnv.Stop()).To(Succeed())
135+
})
136+
137+
func createSharedTestCRs(port string) {
138+
GinkgoHelper()
139+
140+
By("Creating Configmaps and GrafanaFolder for testing")
141+
cmCr := &corev1.Secret{
142+
ObjectMeta: metav1.ObjectMeta{
143+
Namespace: "default",
144+
Name: "external-credentials",
145+
},
146+
StringData: grafanaCredentials,
147+
}
148+
Expect(k8sClient.Create(testCtx, cmCr)).ToNot(HaveOccurred())
149+
folderCr := &v1beta1.GrafanaFolder{
150+
ObjectMeta: metav1.ObjectMeta{
151+
Namespace: "default",
152+
Name: "apply-failed-helper",
153+
},
154+
Spec: v1beta1.GrafanaFolderSpec{
155+
GrafanaCommonSpec: commonSpecApplyFailed,
156+
},
157+
}
158+
Expect(k8sClient.Create(testCtx, folderCr)).ToNot(HaveOccurred())
88159

89-
By("Create a dummy 'invalid' instance to provoke conditions")
160+
By("Creating Grafana CRs. One Fake and one External")
90161
intP := 1
91-
grafanaCr := &v1beta1.Grafana{
162+
163+
dummy := &v1beta1.Grafana{
92164
ObjectMeta: metav1.ObjectMeta{
93-
Name: "dummy",
94165
Namespace: "default",
166+
Name: "dummy",
95167
Labels: map[string]string{
96168
"apply-failed": "test",
97169
"invalid-spec": "test",
@@ -100,40 +172,61 @@ var _ = BeforeSuite(func() {
100172
},
101173
Spec: v1beta1.GrafanaSpec{
102174
Client: &v1beta1.GrafanaClient{TimeoutSeconds: &intP},
103-
Config: map[string]map[string]string{
104-
"security": {
105-
"admin_user": "root",
106-
"admin_password": "secret",
175+
},
176+
}
177+
external := &v1beta1.Grafana{
178+
ObjectMeta: metav1.ObjectMeta{
179+
Namespace: "default",
180+
Name: grafanaName,
181+
Labels: map[string]string{
182+
"synchronized": "test",
183+
"dashboards": "grafana",
184+
},
185+
},
186+
Spec: v1beta1.GrafanaSpec{
187+
External: &v1beta1.External{
188+
URL: fmt.Sprintf("http://localhost:%s", port),
189+
AdminUser: &corev1.SecretKeySelector{
190+
Key: "GF_SECURITY_ADMIN_USER",
191+
LocalObjectReference: corev1.LocalObjectReference{
192+
Name: cmCr.Name,
193+
},
194+
},
195+
AdminPassword: &corev1.SecretKeySelector{
196+
Key: "GF_SECURITY_ADMIN_PASSWORD",
197+
LocalObjectReference: corev1.LocalObjectReference{
198+
Name: cmCr.Name,
199+
},
107200
},
108201
},
202+
Client: &v1beta1.GrafanaClient{TimeoutSeconds: &intP},
109203
},
110204
}
111-
Expect(k8sClient.Create(testCtx, grafanaCr)).NotTo(HaveOccurred())
205+
Expect(k8sClient.Create(testCtx, dummy)).Should(Succeed())
206+
Expect(k8sClient.Create(testCtx, external)).Should(Succeed())
112207

113-
grafanaCr.Status = v1beta1.GrafanaStatus{
208+
dummy.Status = v1beta1.GrafanaStatus{
114209
Stage: v1beta1.OperatorStageComplete,
115210
StageStatus: v1beta1.OperatorStageResultSuccess,
116211
AdminURL: fmt.Sprintf("http://%s-service", "invalid"),
117212
Version: config.GrafanaVersion,
118213
}
119-
Expect(k8sClient.Status().Update(testCtx, grafanaCr)).ToNot(HaveOccurred())
214+
Expect(k8sClient.Status().Update(testCtx, dummy)).ToNot(HaveOccurred())
120215

121-
// Should not be reconciled
122-
By("Creating folder to use when provoking ApplyFailed conditions")
123-
folderCr := &v1beta1.GrafanaFolder{
124-
ObjectMeta: metav1.ObjectMeta{
125-
Namespace: objectMetaApplyFailed.Namespace,
126-
Name: "apply-failed-helper",
127-
},
128-
Spec: v1beta1.GrafanaFolderSpec{
129-
GrafanaCommonSpec: commonSpecApplyFailed,
130-
},
216+
By("Reconciling External Grafana")
217+
r := GrafanaReconciler{
218+
Client: k8sClient,
219+
Scheme: k8sClient.Scheme(),
220+
IsOpenShift: false,
131221
}
132-
Expect(k8sClient.Create(testCtx, folderCr)).ToNot(HaveOccurred())
133-
})
134-
135-
var _ = AfterSuite(func() {
136-
By("tearing down the test environment")
137-
err := testEnv.Stop()
138-
Expect(err).NotTo(HaveOccurred())
139-
})
222+
reg := requestFromMeta(external.ObjectMeta)
223+
_, err := r.Reconcile(testCtx, reg)
224+
Expect(err).ToNot(HaveOccurred())
225+
226+
By("Get External Grafana")
227+
externalGrafanaCr = &v1beta1.Grafana{}
228+
Expect(k8sClient.Get(testCtx, types.NamespacedName{
229+
Namespace: external.Namespace,
230+
Name: external.Name,
231+
}, externalGrafanaCr)).Should(Succeed())
232+
}

0 commit comments

Comments
 (0)