@@ -18,6 +18,7 @@ import (
1818{{- end }}
1919 "github.com/hashicorp/terraform-plugin-testing/terraform"
2020 sqladmin "google.golang.org/api/sqladmin/v1beta4"
21+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
2122)
2223
2324// Fields that should be ignored in import tests because they aren't returned
@@ -3925,6 +3926,262 @@ func TestAccSqlDatabaseInstance_DiskSizeAutoResizeWithDiskSize(t *testing.T) {
39253926 })
39263927}
39273928
3929+ func TestEnhancedBackupManagerDiffSuppressFunc(t *testing.T) {
3930+ cases := map[string]struct {
3931+ key string
3932+ old string
3933+ new string
3934+ backupTier string
3935+ expectSuppress bool
3936+ description string
3937+ }{
3938+ "suppress enabled diff when backup tier is enhanced": {
3939+ key: "settings.0.backup_configuration.0.enabled",
3940+ old: "true",
3941+ new: "false",
3942+ backupTier: "ENHANCED",
3943+ expectSuppress: true,
3944+ description: "enabled should be suppressed when ENHANCED",
3945+ },
3946+ "suppress start_time diff when backup tier is enhanced": {
3947+ key: "settings.0.backup_configuration.0.start_time",
3948+ old: "03:00",
3949+ new: "05:00",
3950+ backupTier: "ENHANCED",
3951+ expectSuppress: true,
3952+ description: "start_time should be suppressed when ENHANCED",
3953+ },
3954+ "suppress binary_log_enabled diff when backup tier is enhanced": {
3955+ key: "settings.0.backup_configuration.0.binary_log_enabled",
3956+ old: "true",
3957+ new: "false",
3958+ backupTier: "ENHANCED",
3959+ expectSuppress: true,
3960+ description: "binary_log_enabled should be suppressed when ENHANCED",
3961+ },
3962+ "suppress point_in_time_recovery_enabled diff when backup tier is enhanced": {
3963+ key: "settings.0.backup_configuration.0.point_in_time_recovery_enabled",
3964+ old: "false",
3965+ new: "true",
3966+ backupTier: "ENHANCED",
3967+ expectSuppress: true,
3968+ description: "point_in_time_recovery_enabled should be suppressed when ENHANCED",
3969+ },
3970+ "suppress transaction_log_retention_days diff when backup tier is enhanced": {
3971+ key: "settings.0.backup_configuration.0.transaction_log_retention_days",
3972+ old: "7",
3973+ new: "14",
3974+ backupTier: "ENHANCED",
3975+ expectSuppress: true,
3976+ description: "transaction_log_retention_days should be suppressed when ENHANCED",
3977+ },
3978+ "suppress retained_backups diff when backup tier is enhanced": {
3979+ key: "settings.0.backup_configuration.0.backup_retention_settings.0.retained_backups",
3980+ old: "7",
3981+ new: "14",
3982+ backupTier: "ENHANCED",
3983+ expectSuppress: true,
3984+ description: "retained_backups should be suppressed when ENHANCED",
3985+ },
3986+ "do not suppress diff when backup tier is standard": {
3987+ key: "settings.0.backup_configuration.0.enabled",
3988+ old: "true",
3989+ new: "false",
3990+ backupTier: "STANDARD",
3991+ expectSuppress: false,
3992+ description: "enabled should NOT be suppressed when STANDARD",
3993+ },
3994+ "do not suppress diff when backup tier is empty": {
3995+ key: "settings.0.backup_configuration.0.enabled",
3996+ old: "true",
3997+ new: "false",
3998+ backupTier: "",
3999+ expectSuppress: false,
4000+ description: "enabled should NOT be suppressed when backup_tier is empty",
4001+ },
4002+ "do not suppress when old and new are same": {
4003+ key: "settings.0.backup_configuration.0.enabled",
4004+ old: "true",
4005+ new: "true",
4006+ backupTier: "ENHANCED",
4007+ expectSuppress: true,
4008+ description: "no diff to suppress when old and new are same",
4009+ },
4010+ }
4011+
4012+ for name, tc := range cases {
4013+ t.Run(name, func(t *testing.T) {
4014+ // Build real *schema.ResourceData using the resource schema and TestResourceDataRaw
4015+ // Put backup_tier into the nested settings->backup_configuration block (state)
4016+ rd := schema.TestResourceDataRaw(t, sql.ResourceSqlDatabaseInstance().Schema, map[string]interface{}{
4017+ "name": "test-instance",
4018+ "settings": []interface{}{
4019+ map[string]interface{}{
4020+ "backup_configuration": []interface{}{
4021+ map[string]interface{}{
4022+ "backup_tier": tc.backupTier,
4023+ },
4024+ },
4025+ },
4026+ },
4027+ })
4028+
4029+ suppressed := sql.EnhancedBackupManagerDiffSuppressFunc(tc.key, tc.old, tc.new, rd)
4030+
4031+ if suppressed != tc.expectSuppress {
4032+ t.Errorf("expected suppressed to be %v but got %v. Desc: %s", tc.expectSuppress, suppressed, tc.description)
4033+ }
4034+ })
4035+ }
4036+ }
4037+
4038+ func TestAccSqlDatabaseInstance_updateInstanceTierForEnhancedBackupTierInstance(t *testing.T) {
4039+ t.Parallel()
4040+
4041+ backupVaultID := "bv-test"
4042+ location := "us-central1"
4043+ project := envvar.GetTestProjectFromEnv()
4044+ backupVault := acctest.BootstrapBackupDRVault(t, backupVaultID, location)
4045+
4046+ context := map[string]interface{}{
4047+ "random_suffix": acctest.RandString(t, 10),
4048+ "project": project,
4049+ "backup_vault_id": backupVaultID,
4050+ "backup_vault": backupVault,
4051+ "db_version": "MYSQL_8_0_41",
4052+ }
4053+
4054+ acctest.VcrTest(t, resource.TestCase{
4055+ PreCheck: func() { acctest.AccTestPreCheck(t) },
4056+ ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
4057+ CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
4058+ Steps: []resource.TestStep{
4059+ {
4060+ // Create backup plan and associate with instance
4061+ Config: testGoogleSqlDatabaseInstance_attachGCBDR(context),
4062+ Check: resource.ComposeAggregateTestCheckFunc(
4063+ resource.TestCheckResourceAttrSet("google_backup_dr_backup_plan_association.backup_association", "id"),
4064+ ),
4065+ },
4066+ {
4067+ // Update instance backup tier to ENHANCED, which should ignore backup_configuration settings
4068+ Config: testGoogleSqlDatabaseInstance_updateTierForGcbdrManagedInstance(context),
4069+ Check: resource.ComposeAggregateTestCheckFunc(
4070+ resource.TestCheckResourceAttr("google_sql_database_instance.instance", "settings.0.tier", "db-g1-small"),
4071+ ),
4072+ },
4073+ },
4074+ })
4075+ }
4076+
4077+ func testGoogleSqlDatabaseInstance_attachGCBDR(context map[string]interface{}) string {
4078+ return acctest.Nprintf(`
4079+ data "google_project" "project" {}
4080+
4081+ resource "google_sql_database_instance" "instance" {
4082+ name = "tf-test-instance-%{random_suffix}"
4083+ database_version = "%{db_version}"
4084+ region = "us-central1"
4085+
4086+ settings {
4087+ tier = "db-f1-micro"
4088+ }
4089+ deletion_protection = false
4090+ }
4091+
4092+ resource "google_backup_dr_backup_plan" "plan" {
4093+ location = "us-central1"
4094+ backup_plan_id = "tf-test-bp-test-%{random_suffix}"
4095+ resource_type = "sqladmin.googleapis.com/Instance"
4096+ backup_vault = "%{backup_vault}"
4097+
4098+ backup_rules {
4099+ rule_id = "rule-1"
4100+ backup_retention_days = 7
4101+
4102+ standard_schedule {
4103+ recurrence_type = "DAILY"
4104+ hourly_frequency = 6
4105+ time_zone = "UTC"
4106+
4107+ backup_window {
4108+ start_hour_of_day = 0
4109+ end_hour_of_day = 23
4110+ }
4111+ }
4112+ }
4113+ }
4114+
4115+ resource "google_backup_dr_backup_plan_association" "backup_association" {
4116+ location = "us-central1"
4117+ backup_plan_association_id = "tf-test-bpa-test-%{random_suffix}"
4118+ resource = "projects/${data.google_project.project.project_id}/instances/${google_sql_database_instance.instance.name}"
4119+ resource_type = "sqladmin.googleapis.com/Instance"
4120+ backup_plan = google_backup_dr_backup_plan.plan.name
4121+ }
4122+ `, context)
4123+ }
4124+
4125+ func testGoogleSqlDatabaseInstance_updateTierForGcbdrManagedInstance(context map[string]interface{}) string {
4126+ return acctest.Nprintf(`
4127+ data "google_project" "project" {}
4128+
4129+ resource "google_sql_database_instance" "instance" {
4130+ name = "tf-test-instance-%{random_suffix}"
4131+ database_version = "%{db_version}"
4132+ region = "us-central1"
4133+
4134+ settings {
4135+ tier = "db-g1-small"
4136+
4137+ backup_configuration {
4138+ enabled = false
4139+ binary_log_enabled = false
4140+ start_time = "05:00"
4141+
4142+ backup_retention_settings {
4143+ retained_backups = 8
4144+ retention_unit = "COUNT"
4145+ }
4146+ }
4147+ }
4148+ deletion_protection = false
4149+ }
4150+
4151+ resource "google_backup_dr_backup_plan" "plan" {
4152+ location = "us-central1"
4153+ backup_plan_id = "tf-test-bp-test-%{random_suffix}"
4154+ resource_type = "sqladmin.googleapis.com/Instance"
4155+ backup_vault = "%{backup_vault}"
4156+
4157+ backup_rules {
4158+ rule_id = "rule-1"
4159+ backup_retention_days = 7
4160+
4161+ standard_schedule {
4162+ recurrence_type = "DAILY"
4163+ hourly_frequency = 6
4164+ time_zone = "UTC"
4165+
4166+ backup_window {
4167+ start_hour_of_day = 0
4168+ end_hour_of_day = 23
4169+ }
4170+ }
4171+ }
4172+ }
4173+
4174+ resource "google_backup_dr_backup_plan_association" "backup_association" {
4175+ location = "us-central1"
4176+ backup_plan_association_id = "tf-test-bpa-test-%{random_suffix}"
4177+ resource = "projects/${data.google_project.project.project_id}/instances/${google_sql_database_instance.instance.name}"
4178+ resource_type = "sqladmin.googleapis.com/Instance"
4179+ backup_plan = google_backup_dr_backup_plan.plan.name
4180+ }
4181+ `, context)
4182+ }
4183+
4184+
39284185func testGoogleSqlDatabaseInstance_setCustomSubjectAlternateName(context map[string]interface{}) string {
39294186 return acctest.Nprintf(`
39304187data "google_project" "project" {
0 commit comments