From d141ada0f7e613ff3c4821a925a5f160a0a5901b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Reyes?= Date: Fri, 21 Jul 2023 20:35:04 -0400 Subject: [PATCH] add test cases for parallel creation of service deps --- .../resource_pagerduty_service_dependency.go | 10 +- ...ource_pagerduty_service_dependency_test.go | 249 +++++++++++++++++- 2 files changed, 253 insertions(+), 6 deletions(-) diff --git a/pagerduty/resource_pagerduty_service_dependency.go b/pagerduty/resource_pagerduty_service_dependency.go index 4412e92a4..1ea1fc0ee 100644 --- a/pagerduty/resource_pagerduty_service_dependency.go +++ b/pagerduty/resource_pagerduty_service_dependency.go @@ -147,21 +147,23 @@ func resourcePagerDutyServiceDependencyAssociate(d *schema.ResourceData, meta in var dependencies *pagerduty.ListServiceDependencies retryErr := resource.Retry(5*time.Minute, func() *resource.RetryError { - // Lock the mutex to ensure only one API call to `service_dependencies/associate` is created or updated at a time + // Lock the mutex to ensure only one API call to + // `service_dependencies/associate` is done at a time dependencyAssociationMutex.Lock() - defer dependencyAssociationMutex.Unlock() + dependencies, _, err = client.ServiceDependencies.AssociateServiceDependencies(&input) + dependencyAssociationMutex.Unlock() - if dependencies, _, err = client.ServiceDependencies.AssociateServiceDependencies(&input); err != nil { + if err != nil { if isErrCode(err, 404) { return resource.RetryableError(err) } return resource.NonRetryableError(err) } else { for _, r := range dependencies.Relationships { - d.SetId(r.ID) if err := d.Set("dependency", flattenRelationship(r)); err != nil { return resource.NonRetryableError(err) } + d.SetId(r.ID) } } return nil diff --git a/pagerduty/resource_pagerduty_service_dependency_test.go b/pagerduty/resource_pagerduty_service_dependency_test.go index 11a02ec08..b63cf393e 100644 --- a/pagerduty/resource_pagerduty_service_dependency_test.go +++ b/pagerduty/resource_pagerduty_service_dependency_test.go @@ -38,6 +38,30 @@ func TestAccPagerDutyBusinessServiceDependency_Basic(t *testing.T) { }, }) } + +// Testing Parallel creation of Business Service Dependencies +func TestAccPagerDutyBusinessServiceDependency_Parallel(t *testing.T) { + service := fmt.Sprintf("tf-%s", acctest.RandString(5)) + businessService := fmt.Sprintf("tf-%s", acctest.RandString(5)) + username := fmt.Sprintf("tf-%s", acctest.RandString(5)) + email := fmt.Sprintf("%s@foo.test", username) + escalationPolicy := fmt.Sprintf("tf-%s", acctest.RandString(5)) + resCount := 30 + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyBusinessServiceDependencyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckPagerDutyBusinessServiceDependencyParallelConfig(service, businessService, username, email, escalationPolicy, resCount), + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyBusinessServiceDependencyParallelExists("pagerduty_service_dependency.foo", resCount), + ), + }, + }, + }) +} func testAccCheckPagerDutyBusinessServiceDependencyExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -72,6 +96,50 @@ func testAccCheckPagerDutyBusinessServiceDependencyExists(n string) resource.Tes return nil } } +func testAccCheckPagerDutyBusinessServiceDependencyParallelExists(n string, resCount int) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs := []*terraform.ResourceState{} + for i := 0; i < resCount; i++ { + resName := fmt.Sprintf("%s.%d", n, i) + r, ok := s.RootModule().Resources[resName] + if !ok { + return fmt.Errorf("Not found: %s", resName) + } + rs = append(rs, r) + } + + for _, r := range rs { + if r.Primary.ID == "" { + return fmt.Errorf("No Service Relationship ID is set") + } + } + + for i := 0; i < resCount; i++ { + businessService, _ := s.RootModule().Resources["pagerduty_business_service.foo"] + + client, _ := testAccProvider.Meta().(*Config).Client() + + depResp, _, err := client.ServiceDependencies.GetServiceDependenciesForType(businessService.Primary.ID, "business_service") + if err != nil { + return fmt.Errorf("Business Service not found: %v", err) + } + var foundRel *pagerduty.ServiceDependency + + // loop serviceRelationships until relationship.IDs match + for _, rel := range depResp.Relationships { + if rel.ID == rs[i].Primary.ID { + foundRel = rel + break + } + } + if foundRel == nil { + return fmt.Errorf("Service Dependency not found: %v", rs[i].Primary.ID) + } + } + + return nil + } +} func testAccCheckPagerDutyBusinessServiceDependencyDestroy(s *terraform.State) error { client, _ := testAccProvider.Meta().(*Config).Client() @@ -97,6 +165,57 @@ func testAccCheckPagerDutyBusinessServiceDependencyDestroy(s *terraform.State) e } return nil } +func testAccCheckPagerDutyBusinessServiceDependencyParallelConfig(service, businessService, username, email, escalationPolicy string, resCount int) string { + return fmt.Sprintf(` +resource "pagerduty_business_service" "foo" { + name = "%[1]s" +} + +resource "pagerduty_user" "foo" { + name = "%[2]s" + email = "%[3]s" + color = "green" + role = "user" + job_title = "foo" + description = "foo" +} + +resource "pagerduty_escalation_policy" "foo" { + name = "%[4]s" + description = "bar" + num_loops = 2 + rule { + escalation_delay_in_minutes = 10 + target { + type = "user_reference" + id = pagerduty_user.foo.id + } + } +} +resource "pagerduty_service" "supportBar" { + count = %[6]d + name = "%[5]s-${count.index}" + description = "foo" + auto_resolve_timeout = 1800 + acknowledgement_timeout = 1800 + escalation_policy = pagerduty_escalation_policy.foo.id + alert_creation = "create_incidents" +} +resource "pagerduty_service_dependency" "foo" { + count = %[6]d + dependency { + dependent_service { + id = pagerduty_business_service.foo.id + type = "business_service" + } + supporting_service { + id = pagerduty_service.supportBar[count.index].id + type = "service" + } + } +} +`, businessService, username, email, escalationPolicy, service, resCount) +} func testAccCheckPagerDutyBusinessServiceDependencyConfig(service, businessService, username, email, escalationPolicy string) string { return fmt.Sprintf(` resource "pagerduty_business_service" "foo" { @@ -175,6 +294,30 @@ func TestAccPagerDutyTechnicalServiceDependency_Basic(t *testing.T) { }, }) } + +// Testing Parallel creation of Technical Service Dependencies +func TestAccPagerDutyTechnicalServiceDependency_Parallel(t *testing.T) { + dependentService := fmt.Sprintf("tf-%s", acctest.RandString(5)) + supportingService := fmt.Sprintf("tf-%s", acctest.RandString(5)) + username := fmt.Sprintf("tf-%s", acctest.RandString(5)) + email := fmt.Sprintf("%s@foo.test", username) + escalationPolicy := fmt.Sprintf("tf-%s", acctest.RandString(5)) + resCount := 30 + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyTechnicalServiceDependencyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckPagerDutyTechnicalServiceDependencyParallelConfig(dependentService, supportingService, username, email, escalationPolicy, resCount), + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyTechnicalServiceDependencyParallelExists("pagerduty_service_dependency.bar", resCount), + ), + }, + }, + }) +} func testAccCheckPagerDutyTechnicalServiceDependencyExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -185,7 +328,7 @@ func testAccCheckPagerDutyTechnicalServiceDependencyExists(n string) resource.Te if rs.Primary.ID == "" { return fmt.Errorf("No Service Relationship ID is set") } - supportService, _ := s.RootModule().Resources["pagerduty_service.supportBar"] + supportService, _ := s.RootModule().Resources["pagerduty_service.supportBar.1"] client, _ := testAccProvider.Meta().(*Config).Client() @@ -210,13 +353,59 @@ func testAccCheckPagerDutyTechnicalServiceDependencyExists(n string) resource.Te } } +func testAccCheckPagerDutyTechnicalServiceDependencyParallelExists(n string, resCount int) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs := []*terraform.ResourceState{} + for i := 0; i < resCount; i++ { + resName := fmt.Sprintf("%s.%d", n, i) + r, ok := s.RootModule().Resources[resName] + if !ok { + return fmt.Errorf("Not found: %s", resName) + } + rs = append(rs, r) + } + + for _, r := range rs { + if r.Primary.ID == "" { + return fmt.Errorf("No Service Relationship ID is set") + } + } + + for i := 0; i < resCount; i++ { + resName := fmt.Sprintf("pagerduty_service.supportBar.%d", i) + supportService, _ := s.RootModule().Resources[resName] + + client, _ := testAccProvider.Meta().(*Config).Client() + + depResp, _, err := client.ServiceDependencies.GetServiceDependenciesForType(supportService.Primary.ID, "service") + if err != nil { + return fmt.Errorf("Technical Service not found: %v", err) + } + var foundRel *pagerduty.ServiceDependency + + // loop serviceRelationships until relationship.IDs match + for _, rel := range depResp.Relationships { + if rel.ID == rs[i].Primary.ID { + foundRel = rel + break + } + } + if foundRel == nil { + return fmt.Errorf("Service Dependency not found: %v", rs[i].Primary.ID) + } + } + + return nil + } +} + func testAccCheckPagerDutyTechnicalServiceDependencyDestroy(s *terraform.State) error { client, _ := testAccProvider.Meta().(*Config).Client() for _, r := range s.RootModule().Resources { if r.Type != "pagerduty_service_dependency" { continue } - supportService, _ := s.RootModule().Resources["pagerduty_service.supportBar"] + supportService, _ := s.RootModule().Resources["pagerduty_service.supportBar.1"] // get service dependencies dependencies, _, err := client.ServiceDependencies.GetServiceDependenciesForType(supportService.Primary.ID, "service") @@ -289,3 +478,59 @@ resource "pagerduty_service_dependency" "bar" { } `, username, email, escalationPolicy, supportingService, dependentService) } + +func testAccCheckPagerDutyTechnicalServiceDependencyParallelConfig(dependentService, supportingService, username, email, escalationPolicy string, resCount int) string { + return fmt.Sprintf(` +resource "pagerduty_user" "bar" { + name = "%[1]s" + email = "%[2]s" + color = "green" + role = "user" + job_title = "foo" + description = "foo" +} + +resource "pagerduty_escalation_policy" "bar" { + name = "%[3]s" + description = "bar-desc" + num_loops = 2 + rule { + escalation_delay_in_minutes = 10 + target { + type = "user_reference" + id = pagerduty_user.bar.id + } + } +} +resource "pagerduty_service" "supportBar" { + count = %[6]d + name = "%[4]s-${count.index}" + description = "supportBarDesc" + auto_resolve_timeout = 1800 + acknowledgement_timeout = 1800 + escalation_policy = pagerduty_escalation_policy.bar.id + alert_creation = "create_incidents" +} +resource "pagerduty_service" "dependBar" { + name = "%[5]s" + description = "dependBarDesc" + auto_resolve_timeout = 1800 + acknowledgement_timeout = 1800 + escalation_policy = pagerduty_escalation_policy.bar.id + alert_creation = "create_incidents" +} +resource "pagerduty_service_dependency" "bar" { + count = %[6]d + dependency { + dependent_service { + id = pagerduty_service.dependBar.id + type = "service" + } + supporting_service { + id = pagerduty_service.supportBar[count.index].id + type = "service" + } + } +} +`, username, email, escalationPolicy, supportingService, dependentService, resCount) +}