@@ -23,27 +23,47 @@ import (
23
23
"testing"
24
24
"time"
25
25
26
- . "github.com/onsi/ginkgo/v2"
27
- . "github.com/onsi/gomega"
26
+ corev1 "k8s.io/api/core/v1"
28
27
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
+ "k8s.io/apimachinery/pkg/types"
29
29
"k8s.io/client-go/kubernetes/scheme"
30
30
"sigs.k8s.io/controller-runtime/pkg/client"
31
31
"sigs.k8s.io/controller-runtime/pkg/envtest"
32
32
logf "sigs.k8s.io/controller-runtime/pkg/log"
33
33
"sigs.k8s.io/controller-runtime/pkg/log/zap"
34
34
35
+ "github.com/docker/go-connections/nat"
35
36
"github.com/grafana/grafana-operator/v5/api/v1beta1"
36
37
"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"
37
43
//+kubebuilder:scaffold:imports
38
44
)
39
45
40
46
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
41
47
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
42
48
49
+ const (
50
+ grafanaName = "external-grafana"
51
+ grafanaUser = "root"
52
+ grafanaPass = "secret"
53
+ )
54
+
43
55
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
+ }
47
67
)
48
68
49
69
func TestAPIs (t * testing.T ) {
@@ -78,20 +98,71 @@ var _ = BeforeSuite(func() {
78
98
79
99
//+kubebuilder:scaffold:scheme
80
100
101
+ By ("Instantiating k8sClient" )
81
102
k8sClient , err = client .New (cfg , client.Options {Scheme : scheme .Scheme })
82
103
Expect (err ).NotTo (HaveOccurred ())
83
104
Expect (k8sClient ).NotTo (BeNil ())
84
105
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 ())
88
127
89
- By ("Create a dummy 'invalid' instance to provoke conditions" )
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
+ secretCR := & corev1.Secret {
142
+ ObjectMeta : metav1.ObjectMeta {
143
+ Namespace : "default" ,
144
+ Name : "external-credentials" ,
145
+ },
146
+ StringData : grafanaCredentials ,
147
+ }
148
+ Expect (k8sClient .Create (testCtx , secretCR )).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 ())
159
+
160
+ By ("Creating Grafana CRs. One Fake and one External" )
90
161
intP := 1
91
- grafanaCr := & v1beta1.Grafana {
162
+ dummy := & v1beta1.Grafana {
92
163
ObjectMeta : metav1.ObjectMeta {
93
- Name : "dummy" ,
94
164
Namespace : "default" ,
165
+ Name : "dummy" ,
95
166
Labels : map [string ]string {
96
167
"apply-failed" : "test" ,
97
168
"invalid-spec" : "test" ,
@@ -100,40 +171,61 @@ var _ = BeforeSuite(func() {
100
171
},
101
172
Spec : v1beta1.GrafanaSpec {
102
173
Client : & v1beta1.GrafanaClient {TimeoutSeconds : & intP },
103
- Config : map [string ]map [string ]string {
104
- "security" : {
105
- "admin_user" : "root" ,
106
- "admin_password" : "secret" ,
174
+ },
175
+ }
176
+ external := & v1beta1.Grafana {
177
+ ObjectMeta : metav1.ObjectMeta {
178
+ Namespace : "default" ,
179
+ Name : grafanaName ,
180
+ Labels : map [string ]string {
181
+ "synchronized" : "test" ,
182
+ "dashboards" : "grafana" ,
183
+ },
184
+ },
185
+ Spec : v1beta1.GrafanaSpec {
186
+ External : & v1beta1.External {
187
+ URL : fmt .Sprintf ("http://localhost:%s" , port ),
188
+ AdminUser : & corev1.SecretKeySelector {
189
+ Key : "GF_SECURITY_ADMIN_USER" ,
190
+ LocalObjectReference : corev1.LocalObjectReference {
191
+ Name : secretCR .Name ,
192
+ },
193
+ },
194
+ AdminPassword : & corev1.SecretKeySelector {
195
+ Key : "GF_SECURITY_ADMIN_PASSWORD" ,
196
+ LocalObjectReference : corev1.LocalObjectReference {
197
+ Name : secretCR .Name ,
198
+ },
107
199
},
108
200
},
201
+ Client : & v1beta1.GrafanaClient {TimeoutSeconds : & intP },
109
202
},
110
203
}
111
- Expect (k8sClient .Create (testCtx , grafanaCr )).NotTo (HaveOccurred ())
204
+ Expect (k8sClient .Create (testCtx , dummy )).Should (Succeed ())
205
+ Expect (k8sClient .Create (testCtx , external )).Should (Succeed ())
112
206
113
- grafanaCr .Status = v1beta1.GrafanaStatus {
207
+ dummy .Status = v1beta1.GrafanaStatus {
114
208
Stage : v1beta1 .OperatorStageComplete ,
115
209
StageStatus : v1beta1 .OperatorStageResultSuccess ,
116
210
AdminURL : fmt .Sprintf ("http://%s-service" , "invalid" ),
117
211
Version : config .GrafanaVersion ,
118
212
}
119
- Expect (k8sClient .Status ().Update (testCtx , grafanaCr )).ToNot (HaveOccurred ())
213
+ Expect (k8sClient .Status ().Update (testCtx , dummy )).ToNot (HaveOccurred ())
120
214
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
- },
215
+ By ("Reconciling External Grafana" )
216
+ r := GrafanaReconciler {
217
+ Client : k8sClient ,
218
+ Scheme : k8sClient .Scheme (),
219
+ IsOpenShift : false ,
131
220
}
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
- })
221
+ reg := requestFromMeta (external .ObjectMeta )
222
+ _ , err := r .Reconcile (testCtx , reg )
223
+ Expect (err ).ToNot (HaveOccurred ())
224
+
225
+ By ("Get External Grafana" )
226
+ externalGrafanaCr = & v1beta1.Grafana {}
227
+ Expect (k8sClient .Get (testCtx , types.NamespacedName {
228
+ Namespace : external .Namespace ,
229
+ Name : external .Name ,
230
+ }, externalGrafanaCr )).Should (Succeed ())
231
+ }
0 commit comments