2
2
package test
3
3
4
4
import (
5
- "bytes"
6
5
"fmt"
7
6
"log"
8
7
"os"
9
- "os/exec"
10
- "path/filepath"
11
- "regexp"
12
8
"sort"
13
- "strconv"
14
9
"strings"
15
10
"testing"
16
11
17
- "github.com/gruntwork-io/terratest/modules/files"
18
- "github.com/gruntwork-io/terratest/modules/logger"
19
12
"github.com/gruntwork-io/terratest/modules/random"
20
- "github.com/gruntwork-io/terratest/modules/terraform"
21
13
"github.com/stretchr/testify/assert"
22
14
"github.com/stretchr/testify/require"
23
15
"github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/common"
@@ -221,178 +213,105 @@ func TestUpgradeCEProjectDA(t *testing.T) {
221
213
func TestDeployCEProjectDA (t * testing.T ) {
222
214
t .Parallel ()
223
215
224
- // Provision watsonx Assistant instance
225
- prefix := fmt .Sprintf ("ce-data-%s" , strings .ToLower (random .UniqueId ()))
226
- realTerraformDir := ".."
227
- tempTerraformDir , _ := files .CopyTerraformFolderToTemp (realTerraformDir , fmt .Sprintf (prefix + "-%s" , strings .ToLower (random .UniqueId ())))
228
- // tags := common.GetTagsFromTravis()
229
-
230
216
// Verify ibmcloud_api_key variable is set
231
217
checkVariable := "TF_VAR_ibmcloud_api_key"
232
218
val , present := os .LookupEnv (checkVariable )
233
219
require .True (t , present , checkVariable + " environment variable not set" )
234
220
require .NotEqual (t , "" , val , checkVariable + " environment variable is empty" )
235
221
236
- logger .Log (t , "Tempdir: " , tempTerraformDir )
237
- existingTerraformOptions := terraform .WithDefaultRetryableErrors (t , & terraform.Options {
238
- TerraformDir : tempTerraformDir + "/tests/resources" ,
239
- Vars : map [string ]interface {}{
240
- "resource_group" : resourceGroup ,
241
- "prefix" : prefix ,
222
+ prefix := fmt .Sprintf ("ce-data-%s" , strings .ToLower (random .UniqueId ()))
223
+ // set up the options for existing resource deployment
224
+ // needed by solution
225
+ existingResourceOptions := testhelper .TestOptionsDefault (& testhelper.TestOptions {
226
+ Testing : t ,
227
+ TerraformDir : "tests/resources" ,
228
+ Prefix : prefix ,
229
+ ResourceGroup : resourceGroup ,
230
+ TerraformVars : map [string ]interface {}{
242
231
"existing_sm_instance_guid" : permanentResources ["secretsManagerGuid" ],
243
232
"existing_sm_instance_region" : permanentResources ["secretsManagerRegion" ],
244
233
"existing_cert_secret_id" : permanentResources ["cePublicCertId" ],
234
+ "resource_group" : resourceGroup ,
235
+ "prefix" : prefix ,
245
236
},
246
- // Set Upgrade to true to ensure latest version of providers and modules are used by terratest.
247
- // This is the same as setting the -upgrade=true flag with terraform.
248
- Upgrade : true ,
249
237
})
238
+ // Creates temp dirs and runs InitAndApply for existing resources
239
+ // outputs will be in options after apply
240
+ existingResourceOptions .SkipTestTearDown = true
241
+ _ , existDeployErr := existingResourceOptions .RunTest ()
250
242
251
- terraform .WorkspaceSelectOrNew (t , existingTerraformOptions , prefix )
252
- _ , existErr := terraform .InitAndApplyE (t , existingTerraformOptions )
253
- if existErr != nil {
254
- assert .True (t , existErr == nil , "Init and Apply of temp existing resource failed" )
255
- } else {
256
-
257
- cr_name , _ := getTerraformOutput (tempTerraformDir + "/tests/resources" , "cr_name" )
258
- tls_cert , _ := getTerraformOutput (tempTerraformDir + "/tests/resources" , "tls_cert" )
259
- tls_key , _ := getTerraformOutput (tempTerraformDir + "/tests/resources" , "tls_key" )
260
-
261
- tfVars := map [string ]interface {}{
262
- "prefix" : prefix ,
263
- "provider_visibility" : "public" ,
264
- "project_name" : prefix ,
265
- "existing_resource_group_name" : resourceGroup ,
266
- "container_registry_namespace" : cr_name ,
267
- "builds" : map [string ]interface {}{
268
- fmt .Sprintf ("%s-build" , prefix ): map [string ]interface {}{
269
- "output_image" : fmt .Sprintf ("private.us.icr.io/%s/%s" , cr_name , prefix ),
270
- "output_secret" : fmt .Sprintf ("%s-registry" , prefix ), // pragma: allowlist secret
271
- "source_url" : "https://github.com/IBM/CodeEngine" ,
272
- "strategy_type" : "dockerfile" ,
273
- },
274
- fmt .Sprintf ("%s-build-2" , prefix ): map [string ]interface {}{
275
- "output_secret" : fmt .Sprintf ("%s-registry" , prefix ), // pragma: allowlist secret
276
- "source_url" : "https://github.com/IBM/CodeEngine" ,
277
- "strategy_type" : "dockerfile" ,
278
- "source_context_dir" : "hello" ,
279
- },
243
+ defer existingResourceOptions .TestTearDown () // public function ignores skip above
244
+
245
+ require .NoError (t , existDeployErr , "error creating needed existing VPC resources" )
246
+
247
+ tfVars := map [string ]interface {}{
248
+ "prefix" : prefix ,
249
+ "provider_visibility" : "public" ,
250
+ "project_name" : prefix ,
251
+ "existing_resource_group_name" : resourceGroup ,
252
+ "container_registry_namespace" : fmt .Sprintf ("test_%s_ns" , prefix ),
253
+ "builds" : map [string ]interface {}{
254
+ fmt .Sprintf ("%s-build" , prefix ): map [string ]interface {}{
255
+ "output_image" : fmt .Sprintf ("private.us.icr.io/%s/%s" , existingResourceOptions .LastTestTerraformOutputs ["cr_name" ].(string ), prefix ),
256
+ "output_secret" : fmt .Sprintf ("%s-registry" , prefix ), // pragma: allowlist secret
257
+ "source_url" : "https://github.com/IBM/CodeEngine" ,
258
+ "strategy_type" : "dockerfile" ,
280
259
},
281
- "config_maps" : map [string ]interface {}{
282
- fmt .Sprintf ("%s-cm" , prefix ): map [string ]interface {}{
283
- "data" : map [string ]interface {}{
284
- "key_1" : "value_1" ,
285
- "key_2" : "value_2" ,
286
- },
260
+ fmt .Sprintf ("%s-build-2" , prefix ): map [string ]interface {}{
261
+ "output_secret" : fmt .Sprintf ("%s-registry" , prefix ), // pragma: allowlist secret
262
+ "source_url" : "https://github.com/IBM/CodeEngine" ,
263
+ "strategy_type" : "dockerfile" ,
264
+ "source_context_dir" : "hello" ,
265
+ },
266
+ },
267
+ "config_maps" : map [string ]interface {}{
268
+ fmt .Sprintf ("%s-cm" , prefix ): map [string ]interface {}{
269
+ "data" : map [string ]interface {}{
270
+ "key_1" : "value_1" ,
271
+ "key_2" : "value_2" ,
287
272
},
288
273
},
289
- "secrets" : map [ string ] interface {}{
290
- fmt . Sprintf ( "%s-tls" , prefix ) : map [string ]interface {}{
291
- "format" : " tls" ,
292
- "data " : map [ string ] string {
293
- "tls_cert " : strings . ReplaceAll ( tls_cert , " \n " , `\n` ),
294
- "tls_key " : strings .ReplaceAll (tls_key , "\n " , `\n` ),
295
- } ,
274
+ },
275
+ "secrets" : map [string ]interface {}{
276
+ fmt . Sprintf ( "%s- tls" , prefix ): map [ string ] interface {}{
277
+ "format " : "tls" ,
278
+ "data " : map [ string ] string {
279
+ "tls_cert " : strings .ReplaceAll (existingResourceOptions . LastTestTerraformOutputs [ "tls_cert" ].( string ) , "\n " , `\n` ),
280
+ "tls_key" : strings . ReplaceAll ( existingResourceOptions . LastTestTerraformOutputs [ "tls_key" ].( string ), " \n " , `\n` ) ,
296
281
},
297
- fmt . Sprintf ( "%s-registry" , prefix ): map [ string ] interface {}{
298
- "format" : " registry" ,
299
- "data " : map [ string ] string {
300
- "server " : "private.us.icr.io" ,
301
- "username " : "iamapikey " ,
302
- "password " : val , // pragma: allowlist secret
303
- },
282
+ },
283
+ fmt . Sprintf ( "%s- registry" , prefix ): map [ string ] interface {}{
284
+ "format " : "registry" ,
285
+ "data " : map [ string ] string {
286
+ "server " : "private.us.icr.io " ,
287
+ "username " : "iamapikey" ,
288
+ "password" : val , // pragma: allowlist secret
304
289
},
305
290
},
306
- }
307
-
308
- tfvarsPath := tempTerraformDir + "/solutions/project/terraform.auto.tfvars"
309
- writeTfvarsFile (t , tfvarsPath , tfVars )
310
- defer func () {
311
- if err := os .Remove (tfvarsPath ); err != nil {
312
- fmt .Printf ("Warning: failed to remove %s: %v\n " , tfvarsPath , err )
313
- }
314
- }()
315
-
316
- options := terraform .WithDefaultRetryableErrors (t , & terraform.Options {
317
- TerraformDir : tempTerraformDir + "/solutions/project" ,
318
- })
319
-
320
- cleanTerraformCache (tempTerraformDir + "/solutions/project" )
321
- terraform .WorkspaceSelectOrNew (t , options , prefix )
322
- output , existErr := terraform .InitAndApplyE (t , options )
323
- if existErr != nil {
324
- assert .True (t , existErr == nil , "Init and Apply of temp existing resource failed" )
325
- }
326
-
327
- assert .Nil (t , existErr , "This should not have errored" )
328
- assert .NotNil (t , output , "Expected some output" )
329
- }
330
-
331
- // Check if "DO_NOT_DESTROY_ON_FAILURE" is set
332
- envVal , _ := os .LookupEnv ("DO_NOT_DESTROY_ON_FAILURE" )
333
- // Destroy the temporary existing resources if required
334
- if t .Failed () && strings .ToLower (envVal ) == "true" {
335
- fmt .Println ("Terratest failed. Debug the test and delete resources manually." )
336
- } else {
337
- logger .Log (t , "START: Destroy (existing resources)" )
338
- terraform .Destroy (t , existingTerraformOptions )
339
- terraform .WorkspaceDelete (t , existingTerraformOptions , prefix )
340
- logger .Log (t , "END: Destroy (existing resources)" )
341
- }
342
- }
343
-
344
- func getTerraformOutput (dir , name string ) (string , error ) {
345
- cmd := exec .Command ("terraform" , "output" , "-no-color" , name )
346
- cmd .Dir = dir
347
-
348
- var out bytes.Buffer
349
- cmd .Stdout = & out
350
- cmd .Stderr = & out
351
-
352
- err := cmd .Run ()
353
- if err != nil {
354
- return "" , err
355
- }
356
-
357
- // Trim and unquote if needed
358
- raw := strings .TrimSpace (out .String ())
359
-
360
- // If heredoc-style, strip the surrounding <<EOT ... EOT markers
361
- heredocPattern := regexp .MustCompile (`(?s)^<<EOT\n(.*)\nEOT$` )
362
- if matches := heredocPattern .FindStringSubmatch (raw ); matches != nil {
363
- return matches [1 ], nil // only return the actual content
364
- }
365
-
366
- unquoted , err := strconv .Unquote (raw )
367
- if err != nil {
368
- // If unquoting fails (e.g. already unquoted), just return raw
369
- return raw , nil
291
+ },
370
292
}
371
- return unquoted , nil
372
- }
373
293
374
- func cleanTerraformCache (dir string ) {
375
- terraformFilesAndDirectories := []string {
376
- ".terraform" ,
377
- ".terraform.lock.hcl" ,
378
- "terraform.tfstate" ,
379
- "terraform.tfstate.backup" ,
380
- }
381
- for _ , fileName := range terraformFilesAndDirectories {
382
- fullPath := filepath .Join (dir , fileName )
383
- if _ , err := os .Stat (fullPath ); err == nil {
384
- // Path exists → remove (dir or file)
385
- if err := os .RemoveAll (fullPath ); err != nil {
386
- // Ignore errors, just log them
387
- log .Printf ("Error removing file %s: %s" , fileName , err )
294
+ options := testhelper .TestOptionsDefault (& testhelper.TestOptions {
295
+ Testing : t ,
296
+ TerraformDir : projectSolutionsDir ,
297
+ Prefix : prefix ,
298
+ ResourceGroup : resourceGroup ,
299
+ PreApplyHook : func (options * testhelper.TestOptions ) error {
300
+ // create tfvar file from tfVars variable
301
+ tfvarFileName := fmt .Sprintf ("%s/%s-terraform.tfvars" , options .TerraformDir , prefix )
302
+ err := writeTfvarsFile (t , tfvarFileName , tfVars )
303
+ if err == nil {
304
+ options .TerraformOptions .VarFiles = []string {tfvarFileName }
388
305
}
389
- } else if ! os .IsNotExist (err ) {
390
- // Ignore errors, just log them
391
- log .Printf ("Error removing file %s: %s" , fileName , err )
392
- }
393
- }
306
+ return err
307
+ },
308
+ })
309
+
310
+ _ , err := options .RunTestConsistency ()
311
+ assert .Nil (t , err , "This should not have errored" )
394
312
}
395
313
314
+ // function to convert map into HCL format (needed for tfvar file)
396
315
func toHCL (value interface {}, indentLevel int ) string {
397
316
indent := strings .Repeat (" " , indentLevel )
398
317
@@ -434,7 +353,7 @@ func toHCL(value interface{}, indentLevel int) string {
434
353
}
435
354
}
436
355
437
- func writeTfvarsFile (t * testing.T , path string , vars map [string ]interface {}) {
356
+ func writeTfvarsFile (t * testing.T , path string , vars map [string ]interface {}) error {
438
357
var sb strings.Builder
439
358
for k , v := range vars {
440
359
sb .WriteString (fmt .Sprintf ("%s = %s\n " , k , toHCL (v , 0 )))
@@ -444,4 +363,5 @@ func writeTfvarsFile(t *testing.T, path string, vars map[string]interface{}) {
444
363
if err != nil {
445
364
t .Fatalf ("Failed to write tfvars file: %v" , err )
446
365
}
366
+ return err
447
367
}
0 commit comments