66 "fmt"
77 "sort"
88 "strings"
9+ "sync"
10+ "time"
911
1012 "github.com/go-logr/logr"
1113 "github.com/google/uuid"
@@ -32,10 +34,10 @@ const (
3234 deadMansSnitchUrlValue = "https://example.com/test-snitch-url"
3335 pagerDutyKeyValue = "1234567890ABCDEF"
3436
35- // source: https://github.com/kostola/package-operator-packages/tree/v3 .0/openshift/addon-operator/apnp-test-optional-params
36- pkoImageOptionalParams = "quay.io/alcosta/package-operator-packages/openshift/addon-operator/apnp-test-optional-params:v3 .0"
37- // source: https://github.com/kostola/package-operator-packages/tree/v3 .0/openshift/addon-operator/apnp-test-required-params
38- pkoImageRequiredParams = "quay.io/alcosta/package-operator-packages/openshift/addon-operator/apnp-test-required-params:v3 .0"
37+ // source: https://github.com/kostola/package-operator-packages/tree/v4 .0/openshift/addon-operator/apnp-test-optional-params
38+ pkoImageOptionalParams = "quay.io/alcosta/package-operator-packages/openshift/addon-operator/apnp-test-optional-params:v4 .0"
39+ // source: https://github.com/kostola/package-operator-packages/tree/v4 .0/openshift/addon-operator/apnp-test-required-params
40+ pkoImageRequiredParams = "quay.io/alcosta/package-operator-packages/openshift/addon-operator/apnp-test-required-params:v4 .0"
3941)
4042
4143func (s * integrationTestSuite ) TestPackageOperatorReconcilerStatusPropagatedToAddon () {
@@ -136,6 +138,7 @@ type TestPKOSourcesData struct {
136138 deployAddonParametersSecret bool
137139 deployDeadMansSnitchSecret bool
138140 deployPagerDutySecret bool
141+ deploySendGridSecret bool
139142 clusterPackageStatus string
140143}
141144
@@ -160,70 +163,114 @@ func (s *integrationTestSuite) TestPackageOperatorReconcilerSourceParameterInjec
160163 "PdN" : false ,
161164 "PdY" : true ,
162165 }
166+ sgValues := map [string ]bool {
167+ "SgN" : false ,
168+ "SgY" : true ,
169+ }
163170
164171 // create all combinations
165172 var tests []TestPKOSourcesData
166173 for parK , parV := range parValues {
167174 for apK , apV := range apValues {
168175 for dsK , dsV := range dsValues {
169176 for pdK , pdV := range pdValues {
170- pkoImage := pkoImageOptionalParams
171- if parV {
172- pkoImage = pkoImageRequiredParams
173- }
174-
175- status := v1alpha1 .PackageAvailable
176- if parV && (! apV || ! dsV || ! pdV ) {
177- status = pkov1alpha1 .PackageInvalid
177+ for sgK , sgV := range sgValues {
178+ pkoImage := pkoImageOptionalParams
179+ if parV {
180+ pkoImage = pkoImageRequiredParams
181+ }
182+
183+ status := v1alpha1 .PackageAvailable
184+ if parV && (! apV || ! dsV || ! pdV || ! sgV ) {
185+ status = pkov1alpha1 .PackageInvalid
186+ }
187+
188+ tests = append (tests , TestPKOSourcesData {
189+ fmt .Sprintf ("%s%s%s%s%s" , parK , apK , dsK , pdK , sgK ),
190+ fmt .Sprintf ("%s-%s-%s-%s-%s" , strings .ToLower (parK ), strings .ToLower (apK ), strings .ToLower (dsK ), strings .ToLower (pdK ), strings .ToLower (sgK )),
191+ parV , pkoImage ,
192+ apV , dsV , pdV , sgV ,
193+ status ,
194+ })
178195 }
179-
180- tests = append (tests , TestPKOSourcesData {
181- fmt .Sprintf ("%s%s%s%s" , parK , apK , dsK , pdK ),
182- fmt .Sprintf ("%s-%s-%s-%s" , strings .ToLower (parK ), strings .ToLower (apK ), strings .ToLower (dsK ), strings .ToLower (pdK )),
183- parV , pkoImage ,
184- apV , dsV , pdV ,
185- status ,
186- })
187196 }
188197 }
189198 }
190199 }
191-
192200 sort .Slice (tests , func (i , j int ) bool {
193201 return tests [i ].name < tests [j ].name
194202 })
195203
196- for index , test := range tests {
197- s .Run (test .name , func () {
198- testAddonName := fmt .Sprintf ("%s-%02d-%s" , addonName , index , test .resourceSuffix )
199- testAddonNamespace := fmt .Sprintf ("%s-%02d-%s" , addonNamespace , index , test .resourceSuffix )
200- ctx := context .Background ()
204+ // number of parallel workers
205+ numWorkers := 8
206+ // create a WaitGroup to wait for all jobs to finish
207+ var wg sync.WaitGroup
208+ // set the WaitGroup counter to the total number of jobs
209+ wg .Add (len (tests ))
210+ // launch workers
211+ for i := 0 ; i < numWorkers ; i ++ {
212+ go testWorker (s , i , numWorkers , & wg , tests )
213+ }
214+ // wait for all jobs to finish
215+ timedOut := waitTimeout (& wg , 15 * time .Minute )
216+ // check that the timeout didn't trigger
217+ s .Require ().False (timedOut )
218+ }
201219
202- addon := s . createAddon ( ctx , testAddonName , testAddonNamespace , test . pkoImage )
203- s . waitForNamespace ( ctx , testAddonNamespace )
220+ func testWorker ( s * integrationTestSuite , workerID int , numWorkers int , wg * sync. WaitGroup , testSources [] TestPKOSourcesData ) {
221+ testIdx := workerID
204222
205- if test .deployAddonParametersSecret {
206- s .createAddonParametersSecret (ctx , testAddonName , testAddonNamespace )
207- }
208- if test .deployDeadMansSnitchSecret {
209- s .createDeadMansSnitchSecret (ctx , testAddonName , testAddonNamespace )
210- }
211- if test .deployPagerDutySecret {
212- s .createPagerDutySecret (ctx , testAddonName , testAddonNamespace )
213- }
223+ for counter := 1 ; testIdx < len (testSources ); counter ++ {
224+ testSource := testSources [testIdx ]
214225
215- s .waitForClusterPackage (
216- ctx ,
217- testAddonName ,
218- testAddonNamespace ,
219- test .clusterPackageStatus ,
220- test .deployAddonParametersSecret ,
221- test .deployDeadMansSnitchSecret ,
222- test .deployPagerDutySecret ,
223- )
224-
225- s .T ().Cleanup (func () { s .addonCleanup (addon , ctx ) })
226- })
226+ testAddonName := fmt .Sprintf ("%s-%02d-%s" , addonName , testIdx , testSource .resourceSuffix )
227+ testAddonNamespace := fmt .Sprintf ("%s-%02d-%s" , addonNamespace , testIdx , testSource .resourceSuffix )
228+ ctx := context .Background ()
229+
230+ addon := s .createAddon (ctx , testAddonName , testAddonNamespace , testSource .pkoImage )
231+ s .waitForNamespace (ctx , testAddonNamespace )
232+
233+ if testSource .deployAddonParametersSecret {
234+ s .createAddonParametersSecret (ctx , testAddonName , testAddonNamespace )
235+ }
236+ if testSource .deployDeadMansSnitchSecret {
237+ s .createDeadMansSnitchSecret (ctx , testAddonName , testAddonNamespace )
238+ }
239+ if testSource .deployPagerDutySecret {
240+ s .createPagerDutySecret (ctx , testAddonName , testAddonNamespace )
241+ }
242+ if testSource .deploySendGridSecret {
243+ s .createSendGridSecret (ctx , testAddonName , testAddonNamespace )
244+ }
245+
246+ s .waitForClusterPackage (
247+ ctx ,
248+ testAddonName ,
249+ testAddonNamespace ,
250+ testSource .clusterPackageStatus ,
251+ testSource .deployAddonParametersSecret ,
252+ testSource .deployDeadMansSnitchSecret ,
253+ testSource .deployPagerDutySecret ,
254+ testSource .deploySendGridSecret ,
255+ )
256+
257+ s .addonCleanup (addon , ctx )
258+ wg .Done ()
259+ testIdx = workerID + counter * numWorkers
260+ }
261+ }
262+
263+ func waitTimeout (wg * sync.WaitGroup , timeout time.Duration ) bool {
264+ c := make (chan struct {})
265+ go func () {
266+ defer close (c )
267+ wg .Wait ()
268+ }()
269+ select {
270+ case <- c :
271+ return false // completed normally
272+ case <- time .After (timeout ):
273+ return true // timed out
227274 }
228275}
229276
@@ -282,6 +329,12 @@ func (s *integrationTestSuite) createPagerDutySecret(ctx context.Context, addonN
282329 s .createSecret (ctx , addonName + "-pagerduty" , addonNamespace , map [string ][]byte {"PAGERDUTY_KEY" : []byte (pagerDutyKeyValue )})
283330}
284331
332+ // create the Secret resource for SendGrid as defined here:
333+ // - https://mt-sre.github.io/docs/creating-addons/monitoring/ocm_sendgrid_service_integration/
334+ func (s * integrationTestSuite ) createSendGridSecret (ctx context.Context , addonName string , addonNamespace string ) {
335+ s .createSecret (ctx , addonName + "-smtp" , addonNamespace , map [string ][]byte {"host" : []byte ("clusterID" ), "password" : []byte ("pwd" ), "port" : []byte ("1111" ), "tls" : []byte ("true" ), "username" : []byte ("user" )})
336+ }
337+
285338func (s * integrationTestSuite ) createSecret (ctx context.Context , name string , namespace string , data map [string ][]byte ) {
286339 secret := & v1.Secret {
287340 ObjectMeta : metav1.ObjectMeta {Name : name , Namespace : namespace },
@@ -294,13 +347,13 @@ func (s *integrationTestSuite) createSecret(ctx context.Context, name string, na
294347// wait until all the replicas in the Deployment inside the ClusterPackage are ready
295348// and check if their env variables corresponds to the secrets
296349func (s * integrationTestSuite ) waitForClusterPackage (ctx context.Context , addonName string , addonNamespace string , conditionType string ,
297- addonParametersValuePresent bool , deadMansSnitchUrlValuePresent bool , pagerDutyValuePresent bool ,
350+ addonParametersValuePresent bool , deadMansSnitchUrlValuePresent bool , pagerDutyValuePresent bool , sendGridValuePresent bool ,
298351) {
299352 logger := testutil .NewLogger (s .T ())
300353 cp := & v1alpha1.ClusterPackage {ObjectMeta : metav1.ObjectMeta {Name : addonName }}
301- err := integration .WaitForObject (ctx , s .T (),
354+ err := integration .WaitForObjectWithInterval (ctx , s .T (), 20 * time . Second ,
302355 defaultAddonAvailabilityTimeout , cp , "to be " + conditionType ,
303- clusterPackageChecker (& logger , addonNamespace , conditionType , addonParametersValuePresent , deadMansSnitchUrlValuePresent , pagerDutyValuePresent ))
356+ clusterPackageChecker (& logger , addonNamespace , conditionType , addonParametersValuePresent , deadMansSnitchUrlValuePresent , pagerDutyValuePresent , sendGridValuePresent ))
304357 s .Require ().NoError (err )
305358}
306359
@@ -311,6 +364,7 @@ func clusterPackageChecker(
311364 addonParametersValuePresent bool ,
312365 deadMansSnitchUrlValuePresent bool ,
313366 pagerDutyValuePresent bool ,
367+ sendGridValuePresent bool ,
314368) func (client.Object ) (done bool , err error ) {
315369 if conditionType == v1alpha1 .PackageInvalid {
316370 return func (obj client.Object ) (done bool , err error ) {
@@ -361,7 +415,7 @@ func clusterPackageChecker(
361415 ocmClusterName , present := addonsv1 [addon .OcmClusterNameConfigKey ]
362416 ocmClusterNameValueOk := present && len (fmt .Sprintf ("%v" , ocmClusterName )) > 0
363417
364- addonParametersValueOk , deadMansSnitchUrlValueOk , pagerDutyValueOk := false , false , false
418+ addonParametersValueOk , deadMansSnitchUrlValueOk , pagerDutyValueOk , sendGridValueOk := false , false , false , false
365419 if addonParametersValuePresent {
366420 value , present := addonsv1 [addon .ParametersConfigKey ]
367421 if present {
@@ -388,23 +442,37 @@ func clusterPackageChecker(
388442 _ , present := addonsv1 [addon .PagerDutyKeyConfigKey ]
389443 pagerDutyValueOk = ! present
390444 }
445+ if sendGridValuePresent {
446+ value , present := addonsv1 [addon .SendGridConfigKey ]
447+ if present {
448+ jsonValue , err := json .Marshal (value )
449+ if err == nil {
450+ sendGridValueOk = string (jsonValue ) == "{\" host\" :\" clusterID\" ,\" password\" :\" pwd\" ,\" port\" :\" 1111\" ,\" tls\" :\" true\" ,\" username\" :\" user\" }"
451+ }
452+ }
453+ } else {
454+ _ , present := addonsv1 [addon .SendGridConfigKey ]
455+ sendGridValueOk = ! present
456+ }
391457
392- logger .Info (fmt .Sprintf ("targetNamespace=%t, clusterID=%t, ocmClusterID=%t, ocmClusterName=%t, addonParameters=%t, deadMansSnitchUrl=%t, pagerDutyKey=%t" ,
458+ logger .Info (fmt .Sprintf ("targetNamespace=%t, clusterID=%t, ocmClusterID=%t, ocmClusterName=%t, addonParameters=%t, deadMansSnitchUrl=%t, pagerDutyKey=%t, sendGrid=%t " ,
393459 targetNamespaceValueOk ,
394460 clusterIDValueOk ,
395461 ocmClusterIDValueOk ,
396462 ocmClusterNameValueOk ,
397463 addonParametersValueOk ,
398464 deadMansSnitchUrlValueOk ,
399- pagerDutyValueOk ))
465+ pagerDutyValueOk ,
466+ sendGridValueOk ))
400467
401468 result := targetNamespaceValueOk &&
402469 clusterIDValueOk &&
403470 ocmClusterIDValueOk &&
404471 ocmClusterNameValueOk &&
405472 addonParametersValueOk &&
406473 deadMansSnitchUrlValueOk &&
407- pagerDutyValueOk
474+ pagerDutyValueOk &&
475+ sendGridValueOk
408476
409477 logger .Info (fmt .Sprintf ("result: %t" , result ))
410478 return result , nil
0 commit comments