5
5
"encoding/json"
6
6
"fmt"
7
7
"testing"
8
+ "time"
8
9
9
10
"cloud.google.com/go/bigtable"
10
11
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -29,7 +30,7 @@ func TestAccBigtableGCPolicy_basic(t *testing.T) {
29
30
Config : testAccBigtableGCPolicy (instanceName , tableName , familyName ),
30
31
Check : resource .ComposeTestCheckFunc (
31
32
testAccBigtableGCPolicyExists (
32
- t , "google_bigtable_gc_policy.policy" ),
33
+ t , "google_bigtable_gc_policy.policy" , false ),
33
34
),
34
35
},
35
36
},
@@ -54,7 +55,7 @@ func TestAccBigtableGCPolicy_swapOffDeprecated(t *testing.T) {
54
55
Config : testAccBigtableGCPolicy_days (instanceName , tableName , familyName ),
55
56
Check : resource .ComposeTestCheckFunc (
56
57
testAccBigtableGCPolicyExists (
57
- t , "google_bigtable_gc_policy.policy" ),
58
+ t , "google_bigtable_gc_policy.policy" , false ),
58
59
// Verify can write some data.
59
60
testAccBigtableCanWriteData (
60
61
t , "google_bigtable_gc_policy.policy" , 10 ),
@@ -64,7 +65,7 @@ func TestAccBigtableGCPolicy_swapOffDeprecated(t *testing.T) {
64
65
Config : testAccBigtableGCPolicy (instanceName , tableName , familyName ),
65
66
Check : resource .ComposeTestCheckFunc (
66
67
testAccBigtableGCPolicyExists (
67
- t , "google_bigtable_gc_policy.policy" ),
68
+ t , "google_bigtable_gc_policy.policy" , false ),
68
69
// Verify no data loss after the GC policy update.
69
70
testAccBigtableCanReadData (
70
71
t , "google_bigtable_gc_policy.policy" , 10 ),
@@ -92,7 +93,7 @@ func TestAccBigtableGCPolicy_union(t *testing.T) {
92
93
Config : testAccBigtableGCPolicyUnion (instanceName , tableName , familyName ),
93
94
Check : resource .ComposeTestCheckFunc (
94
95
testAccBigtableGCPolicyExists (
95
- t , "google_bigtable_gc_policy.policy" ),
96
+ t , "google_bigtable_gc_policy.policy" , false ),
96
97
),
97
98
},
98
99
},
@@ -118,11 +119,11 @@ func TestAccBigtableGCPolicy_multiplePolicies(t *testing.T) {
118
119
Config : testAccBigtableGCPolicy_multiplePolicies (instanceName , tableName , familyName ),
119
120
Check : resource .ComposeTestCheckFunc (
120
121
testAccBigtableGCPolicyExists (
121
- t , "google_bigtable_gc_policy.policyA" ),
122
+ t , "google_bigtable_gc_policy.policyA" , false ),
122
123
testAccBigtableGCPolicyExists (
123
- t , "google_bigtable_gc_policy.policyB" ),
124
+ t , "google_bigtable_gc_policy.policyB" , false ),
124
125
testAccBigtableGCPolicyExists (
125
- t , "google_bigtable_gc_policy.policyC" ),
126
+ t , "google_bigtable_gc_policy.policyC" , false ),
126
127
),
127
128
},
128
129
},
@@ -148,7 +149,7 @@ func TestAccBigtableGCPolicy_gcRulesPolicy(t *testing.T) {
148
149
{
149
150
Config : testAccBigtableGCPolicy_gcRulesCreate (instanceName , tableName , familyName ),
150
151
Check : resource .ComposeTestCheckFunc (
151
- testAccBigtableGCPolicyExists (t , "google_bigtable_gc_policy.policy" ),
152
+ testAccBigtableGCPolicyExists (t , "google_bigtable_gc_policy.policy" , true ),
152
153
resource .TestCheckResourceAttr ("google_bigtable_gc_policy.policy" , "gc_rules" , gcRulesOriginal ),
153
154
),
154
155
},
@@ -157,7 +158,7 @@ func TestAccBigtableGCPolicy_gcRulesPolicy(t *testing.T) {
157
158
{
158
159
Config : testAccBigtableGCPolicy_gcRulesUpdate (instanceName , tableName , familyName ),
159
160
Check : resource .ComposeTestCheckFunc (
160
- testAccBigtableGCPolicyExists (t , "google_bigtable_gc_policy.policy" ),
161
+ testAccBigtableGCPolicyExists (t , "google_bigtable_gc_policy.policy" , true ),
161
162
resource .TestCheckResourceAttr ("google_bigtable_gc_policy.policy" , "gc_rules" , gcRulesUpdate ),
162
163
),
163
164
},
@@ -293,7 +294,7 @@ func TestUnitBigtableGCPolicy_getGCPolicyFromJSON(t *testing.T) {
293
294
t .Fatalf ("unexpected error: %v" , err )
294
295
} else {
295
296
if got != nil && got .String () != tc .want {
296
- t .Errorf ("error getting policy from JSON, got: %v, want: %v" , tc .want , got )
297
+ t .Errorf ("error getting policy from JSON, got: %v, want: %v" , got , tc .want )
297
298
}
298
299
}
299
300
})
@@ -346,6 +347,96 @@ var testUnitBigtableGCPolicyCustomizeDiffTestcases = []testUnitBigtableGCPolicyC
346
347
},
347
348
}
348
349
350
+ type testUnitGcPolicyToGCRuleString struct {
351
+ name string
352
+ policy bigtable.GCPolicy
353
+ topLevel bool
354
+ want string
355
+ errorExpected bool
356
+ }
357
+
358
+ var testUnitGcPolicyToGCRuleStringTestCases = []testUnitGcPolicyToGCRuleString {
359
+ {
360
+ name : "NoGcPolicy" ,
361
+ policy : bigtable .NoGcPolicy (),
362
+ topLevel : true ,
363
+ want : `{"rules":[{"max_version":1}]}` ,
364
+ errorExpected : true ,
365
+ },
366
+ {
367
+ name : "MaxVersionPolicy" ,
368
+ policy : bigtable .MaxVersionsPolicy (1 ),
369
+ topLevel : true ,
370
+ want : `{"rules":[{"max_version":1}]}` ,
371
+ errorExpected : false ,
372
+ },
373
+ {
374
+ name : "MaxAgePolicy" ,
375
+ policy : bigtable .MaxAgePolicy (time .Hour ),
376
+ topLevel : true ,
377
+ want : `{"rules":[{"max_age":"1h"}]}` ,
378
+ errorExpected : false ,
379
+ },
380
+ {
381
+ name : "UnionPolicy" ,
382
+ policy : bigtable .UnionPolicy (bigtable .MaxVersionsPolicy (1 ), bigtable .MaxAgePolicy (time .Hour )),
383
+ topLevel : true ,
384
+ want : `{"mode":"union","rules":[{"max_version":1},{"max_age":"1h"}]}` ,
385
+ errorExpected : false ,
386
+ },
387
+ {
388
+ name : "IntersectionPolicy" ,
389
+ policy : bigtable .IntersectionPolicy (bigtable .MaxVersionsPolicy (1 ), bigtable .MaxAgePolicy (time .Hour )),
390
+ topLevel : true ,
391
+ want : `{"mode":"intersection","rules":[{"max_version":1},{"max_age":"1h"}]}` ,
392
+ errorExpected : false ,
393
+ },
394
+ {
395
+ name : "NestedPolicy" ,
396
+ policy : bigtable .UnionPolicy (bigtable .IntersectionPolicy (bigtable .MaxVersionsPolicy (1 ), bigtable .MaxAgePolicy (3 * time .Hour )), bigtable .MaxAgePolicy (time .Hour )),
397
+ topLevel : true ,
398
+ want : `{"mode":"union","rules":[{"mode":"intersection","rules":[{"max_version":1},{"max_age":"3h"}]},{"max_age":"1h"}]}` ,
399
+ errorExpected : false ,
400
+ },
401
+ {
402
+ name : "MaxVersionPolicyNotTopeLevel" ,
403
+ policy : bigtable .MaxVersionsPolicy (1 ),
404
+ topLevel : false ,
405
+ want : `{"max_version":1}` ,
406
+ errorExpected : false ,
407
+ },
408
+ {
409
+ name : "MaxAgePolicyNotTopeLevel" ,
410
+ policy : bigtable .MaxAgePolicy (time .Hour ),
411
+ topLevel : false ,
412
+ want : `{"max_age":"1h"}` ,
413
+ errorExpected : false ,
414
+ },
415
+ }
416
+
417
+ func TestUnitBigtableGCPolicy_gcPolicyToGCRuleString (t * testing.T ) {
418
+ for _ , tc := range testUnitGcPolicyToGCRuleStringTestCases {
419
+ t .Run (tc .name , func (t * testing.T ) {
420
+ got , err := gcPolicyToGCRuleString (tc .policy , tc .topLevel )
421
+ if tc .errorExpected && err == nil {
422
+ t .Fatal ("expect error, got nil" )
423
+ } else if ! tc .errorExpected && err != nil {
424
+ t .Fatalf ("unexpected error: %v" , err )
425
+ } else {
426
+ if got != nil {
427
+ gcRuleJsonString , err := json .Marshal (got )
428
+ if err != nil {
429
+ t .Fatalf ("Error marshaling GC policy to json: %s" , err )
430
+ }
431
+ if string (gcRuleJsonString ) != tc .want {
432
+ t .Errorf ("Unexpected GC policy, got: %v, want: %v" , string (gcRuleJsonString ), tc .want )
433
+ }
434
+ }
435
+ }
436
+ })
437
+ }
438
+ }
439
+
349
440
func testAccCheckBigtableGCPolicyDestroyProducer (t * testing.T ) func (s * terraform.State ) error {
350
441
return func (s * terraform.State ) error {
351
442
var ctx = context .Background ()
@@ -382,7 +473,7 @@ func testAccCheckBigtableGCPolicyDestroyProducer(t *testing.T) func(s *terraform
382
473
}
383
474
}
384
475
385
- func testAccBigtableGCPolicyExists (t * testing.T , n string ) resource.TestCheckFunc {
476
+ func testAccBigtableGCPolicyExists (t * testing.T , n string , compareGcRules bool ) resource.TestCheckFunc {
386
477
var ctx = context .Background ()
387
478
return func (s * terraform.State ) error {
388
479
rs , ok := s .RootModule ().Resources [n ]
@@ -406,9 +497,24 @@ func testAccBigtableGCPolicyExists(t *testing.T, n string) resource.TestCheckFun
406
497
return fmt .Errorf ("Error retrieving table. Could not find %s in %s." , rs .Primary .Attributes ["table" ], rs .Primary .Attributes ["instance_name" ])
407
498
}
408
499
409
- for _ , i := range table .FamilyInfos {
410
- if i .Name == rs .Primary .Attributes ["column_family" ] && i .GCPolicy == rs .Primary .ID {
411
- return nil
500
+ for _ , familyInfo := range table .FamilyInfos {
501
+ if familyInfo .Name == rs .Primary .Attributes ["column_family" ] && familyInfo .GCPolicy == rs .Primary .ID {
502
+ // Ensure the remote GC policy matches the local copy if `compareGcRules` is set to true.
503
+ if ! compareGcRules {
504
+ return nil
505
+ }
506
+ gcRuleString , err := gcPolicyToGCRuleString (familyInfo .FullGCPolicy /*isTopLevel=*/ , true )
507
+ if err != nil {
508
+ return fmt .Errorf ("Error converting GC policy to JSON string: %s" , err )
509
+ }
510
+ gcRuleJsonString , err := json .Marshal (gcRuleString )
511
+ if err != nil {
512
+ return fmt .Errorf ("Error marshaling GC Policy to JSON: %s" , err )
513
+ }
514
+ if string (gcRuleJsonString ) == rs .Primary .Attributes ["gc_rules" ] {
515
+ return nil
516
+ }
517
+ return fmt .Errorf ("Found differences in the local and the remote GC policies: %s vs %s" , rs .Primary .Attributes ["gc_rules" ], string (gcRuleJsonString ))
412
518
}
413
519
}
414
520
0 commit comments