github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/google/resource_google_project_services_test.go (about) 1 package google 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "reflect" 8 "sort" 9 "testing" 10 11 "github.com/hashicorp/terraform/helper/acctest" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/terraform" 14 "google.golang.org/api/servicemanagement/v1" 15 ) 16 17 // Test that services can be enabled and disabled on a project 18 func TestAccGoogleProjectServices_basic(t *testing.T) { 19 pid := "terraform-" + acctest.RandString(10) 20 services1 := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"} 21 services2 := []string{"cloudresourcemanager.googleapis.com"} 22 oobService := "iam.googleapis.com" 23 resource.Test(t, resource.TestCase{ 24 PreCheck: func() { testAccPreCheck(t) }, 25 Providers: testAccProviders, 26 Steps: []resource.TestStep{ 27 // Create a new project with some services 28 resource.TestStep{ 29 Config: testAccGoogleProjectAssociateServicesBasic(services1, pid, pname, org), 30 Check: resource.ComposeTestCheckFunc( 31 testProjectServicesMatch(services1, pid), 32 ), 33 }, 34 // Update services to remove one 35 resource.TestStep{ 36 Config: testAccGoogleProjectAssociateServicesBasic(services2, pid, pname, org), 37 Check: resource.ComposeTestCheckFunc( 38 testProjectServicesMatch(services2, pid), 39 ), 40 }, 41 // Add a service out-of-band and ensure it is removed 42 resource.TestStep{ 43 PreConfig: func() { 44 config := testAccProvider.Meta().(*Config) 45 enableService(oobService, pid, config) 46 }, 47 Config: testAccGoogleProjectAssociateServicesBasic(services2, pid, pname, org), 48 Check: resource.ComposeTestCheckFunc( 49 testProjectServicesMatch(services2, pid), 50 ), 51 }, 52 }, 53 }) 54 } 55 56 // Test that services are authoritative when a project has existing 57 // sevices not represented in config 58 func TestAccGoogleProjectServices_authoritative(t *testing.T) { 59 pid := "terraform-" + acctest.RandString(10) 60 services := []string{"cloudresourcemanager.googleapis.com"} 61 oobService := "iam.googleapis.com" 62 resource.Test(t, resource.TestCase{ 63 PreCheck: func() { testAccPreCheck(t) }, 64 Providers: testAccProviders, 65 Steps: []resource.TestStep{ 66 // Create a new project with no services 67 resource.TestStep{ 68 Config: testAccGoogleProject_create(pid, pname, org), 69 Check: resource.ComposeTestCheckFunc( 70 testAccCheckGoogleProjectExists("google_project.acceptance", pid), 71 ), 72 }, 73 // Add a service out-of-band, then apply a config that creates a service. 74 // It should remove the out-of-band service. 75 resource.TestStep{ 76 PreConfig: func() { 77 config := testAccProvider.Meta().(*Config) 78 enableService(oobService, pid, config) 79 }, 80 Config: testAccGoogleProjectAssociateServicesBasic(services, pid, pname, org), 81 Check: resource.ComposeTestCheckFunc( 82 testProjectServicesMatch(services, pid), 83 ), 84 }, 85 }, 86 }) 87 } 88 89 // Test that services are authoritative when a project has existing 90 // sevices, some which are represented in the config and others 91 // that are not 92 func TestAccGoogleProjectServices_authoritative2(t *testing.T) { 93 pid := "terraform-" + acctest.RandString(10) 94 oobServices := []string{"iam.googleapis.com", "cloudresourcemanager.googleapis.com"} 95 services := []string{"iam.googleapis.com"} 96 97 resource.Test(t, resource.TestCase{ 98 PreCheck: func() { testAccPreCheck(t) }, 99 Providers: testAccProviders, 100 Steps: []resource.TestStep{ 101 // Create a new project with no services 102 resource.TestStep{ 103 Config: testAccGoogleProject_create(pid, pname, org), 104 Check: resource.ComposeTestCheckFunc( 105 testAccCheckGoogleProjectExists("google_project.acceptance", pid), 106 ), 107 }, 108 // Add a service out-of-band, then apply a config that creates a service. 109 // It should remove the out-of-band service. 110 resource.TestStep{ 111 PreConfig: func() { 112 config := testAccProvider.Meta().(*Config) 113 for _, s := range oobServices { 114 enableService(s, pid, config) 115 } 116 }, 117 Config: testAccGoogleProjectAssociateServicesBasic(services, pid, pname, org), 118 Check: resource.ComposeTestCheckFunc( 119 testProjectServicesMatch(services, pid), 120 ), 121 }, 122 }, 123 }) 124 } 125 126 func testAccGoogleProjectAssociateServicesBasic(services []string, pid, name, org string) string { 127 return fmt.Sprintf(` 128 resource "google_project" "acceptance" { 129 project_id = "%s" 130 name = "%s" 131 org_id = "%s" 132 } 133 resource "google_project_services" "acceptance" { 134 project = "${google_project.acceptance.project_id}" 135 services = [%s] 136 } 137 `, pid, name, org, testStringsToString(services)) 138 } 139 140 func testProjectServicesMatch(services []string, pid string) resource.TestCheckFunc { 141 return func(s *terraform.State) error { 142 config := testAccProvider.Meta().(*Config) 143 144 apiServices, err := getApiServices(pid, config) 145 if err != nil { 146 return fmt.Errorf("Error listing services for project %q: %v", pid, err) 147 } 148 149 sort.Strings(services) 150 sort.Strings(apiServices) 151 if !reflect.DeepEqual(services, apiServices) { 152 return fmt.Errorf("Services in config (%v) do not exactly match services returned by API (%v)", services, apiServices) 153 } 154 155 return nil 156 } 157 } 158 159 func testStringsToString(s []string) string { 160 var b bytes.Buffer 161 for i, v := range s { 162 b.WriteString(fmt.Sprintf("\"%s\"", v)) 163 if i < len(s)-1 { 164 b.WriteString(",") 165 } 166 } 167 r := b.String() 168 log.Printf("[DEBUG]: Converted list of strings to %s", r) 169 return b.String() 170 } 171 172 func testManagedServicesToString(svcs []*servicemanagement.ManagedService) string { 173 var b bytes.Buffer 174 for _, s := range svcs { 175 b.WriteString(s.ServiceName) 176 } 177 return b.String() 178 }