@@ -89,6 +89,23 @@ func TestTerraformVersions(t *testing.T) {
8989 }
9090}
9191
92+ /*
93+ * Test for end-to-end Terraform import
94+ * The acceptance import tests have a test gap, because they do not cover Terraform's resource state to state file
95+ * normalization logic. Import tests only verify that in-memory state is correct.
96+ */
97+ func TestTerraformImport (t * testing.T ) {
98+ if httpreplay .ModeRecordReplay () {
99+ t .Skip ("Skipping TestTerraformImport" )
100+ }
101+ if strings .Contains (getEnvSettingWithBlankDefault ("suppressed_tests" ), "TestTerraformImport" ) {
102+ t .Skip ("Skipping TestTerraformImport" )
103+ }
104+ if RunConfigAndImport (t ) {
105+ log .Printf ("Successfully ran all Terraform import tests" )
106+ }
107+ }
108+
92109func RunExamples (t * testing.T , planOnly bool ) {
93110 rootPath := getEnvSettingWithDefault ("examples_root" , "../examples" )
94111 log .Printf ("Testing examples under %v" , rootPath )
@@ -106,7 +123,7 @@ func RunExamples(t *testing.T, planOnly bool) {
106123 }
107124}
108125
109- func GetTerraformBinaries (binPath string ) ([]string , error ) {
126+ func GetTerraformBinaries (binPath string , targetPrefixes [] string ) ([]string , error ) {
110127 results := []string {}
111128
112129 entries , err := ioutil .ReadDir (binPath )
@@ -117,7 +134,16 @@ func GetTerraformBinaries(binPath string) ([]string, error) {
117134 for _ , entry := range entries {
118135 // Include any binaries that start with "terraform" prefix
119136 if name := entry .Name (); ! entry .IsDir () && strings .HasPrefix (name , defaultTerraformBinary ) {
120- results = append (results , name )
137+ if len (targetPrefixes ) == 0 {
138+ results = append (results , name )
139+ } else {
140+ for _ , prefix := range targetPrefixes {
141+ if strings .HasPrefix (name , prefix ) {
142+ results = append (results , name )
143+ break
144+ }
145+ }
146+ }
121147 }
122148 }
123149
@@ -185,7 +211,7 @@ func shouldSkip(dir string) bool {
185211}
186212
187213func RunConfigOnAllTerraformVersions (t * testing.T , path string , planOnly bool ) bool {
188- terraformBinaries , err := GetTerraformBinaries (localBinPath )
214+ terraformBinaries , err := GetTerraformBinaries (localBinPath , [] string {} )
189215 if err != nil {
190216 t .Errorf ("Error retrieving terraform binaries: %v" , err )
191217 return false
@@ -199,9 +225,8 @@ func RunConfigOnAllTerraformVersions(t *testing.T, path string, planOnly bool) b
199225 result := true
200226 for _ , tfBin := range terraformBinaries {
201227 log .Printf ("=== Terraform Version ('%s'), Config Path ('%s') ===\n " , tfBin , path )
202- if ! runCommandWithOutputOptions (t , path , fmt .Sprintf ("%s version" , tfBin ), true ) {
228+ if _ , result = runCommandWithOutputOptions (t , path , fmt .Sprintf ("%s version" , tfBin ), true ); ! result {
203229 log .Printf ("Unable to run version command. Skipping test for %s.\n " , tfBin )
204- result = false
205230 continue
206231 }
207232
@@ -249,11 +274,84 @@ func RunConfig(t *testing.T, path string, planOnly bool, terraformBinary string)
249274 }
250275}
251276
277+ func RunConfigAndImport (t * testing.T ) bool {
278+ path := vcnExamplePath
279+ terraformBinaries , err := GetTerraformBinaries (localBinPath , []string {"terraform-0.11" , "terraform-0.12" })
280+ if err != nil {
281+ t .Errorf ("Error retrieving terraform binaries: %v" , err )
282+ return false
283+ }
284+
285+ if len (terraformBinaries ) == 0 {
286+ t .Errorf ("Did not find any terraform binaries" )
287+ return false
288+ }
289+
290+ result := true
291+ for _ , tfBin := range terraformBinaries {
292+ var output []byte
293+ var vcnId string
294+ log .Printf ("=== Terraform Version ('%s'), Config Path ('%s') ===\n " , tfBin , path )
295+ if _ , result := runCommandWithOutputOptions (t , path , fmt .Sprintf ("%s version" , tfBin ), true ); ! result {
296+ log .Printf ("Unable to run version command. Skipping test for %s.\n " , tfBin )
297+ continue
298+ }
299+
300+ if ! RunCommand (t , path , fmt .Sprintf ("%s init" , tfBin )) {
301+ log .Printf ("Unable to init terraform. Skipping test for %s.\n " , tfBin )
302+ return false
303+ }
304+
305+ // Create a VCN resource
306+ if result = RunCommand (t , path , fmt .Sprintf ("%s apply -auto-approve -state=%v" , tfBin , examplesTestStateFile )); ! result {
307+ goto cleanup
308+ }
309+
310+ // Get the ID of the VCN
311+ if output , result = runCommandWithOutputOptions (t , path , fmt .Sprintf ("%s output -state=%v vcn_id" , tfBin , examplesTestStateFile ), true ); ! result {
312+ goto cleanup
313+ }
314+ vcnId = string (output )
315+
316+ // Remove VCN from state file
317+ if result = RunCommand (t , path , fmt .Sprintf ("%s state rm -state=%v oci_core_vcn.vcn1" , tfBin , examplesTestStateFile )); ! result {
318+ goto cleanup
319+ }
320+
321+ // Import the VCN
322+ if result = RunCommand (t , path , fmt .Sprintf ("%s import -state=%v oci_core_vcn.vcn1 %v" , tfBin , examplesTestStateFile , vcnId )); ! result {
323+ goto cleanup
324+ }
325+
326+ // Plan should show no differences.
327+ if result = RunCommand (t , path , fmt .Sprintf ("%s plan -detailed-exitcode -state=%v" , tfBin , examplesTestStateFile )); ! result {
328+ goto cleanup
329+ }
330+
331+ cleanup:
332+ // Regardless of the result, attempt to destroy.
333+ if RunCommand (t , path , fmt .Sprintf ("%s destroy -force -state=%v" , tfBin , examplesTestStateFile )) {
334+ // Only remove the state file if destroy was successful. Otherwise, leave it in place so that further
335+ // cleanup can be done manually.
336+ result = RunCommand (t , path , fmt .Sprintf ("rm %v*" , examplesTestStateFile )) && result
337+ } else {
338+ result = false
339+ }
340+
341+ if ! result {
342+ break
343+ }
344+ }
345+
346+ return result
347+ }
348+
252349func RunCommand (t * testing.T , path , command string ) bool {
253- return runCommandWithOutputOptions (t , path , command , false )
350+ _ , result := runCommandWithOutputOptions (t , path , command , false )
351+ return result
254352}
255353
256- func runCommandWithOutputOptions (t * testing.T , path , command string , displayOutputOnSuccess bool ) bool {
354+ func runCommandWithOutputOptions (t * testing.T , path , command string , displayOutputOnSuccess bool ) ([] byte , bool ) {
257355 log .Printf ("Running command '%v' at %v" , command , path )
258356
259357 env := make ([]string , len (examplesTestAllowedEnvironmentVariables ))
@@ -269,12 +367,12 @@ func runCommandWithOutputOptions(t *testing.T, path, command string, displayOutp
269367 if err != nil {
270368 log .Printf ("Error: Command Failed. Output: %s" , output )
271369 t .Errorf ("Error running command %v at %v: %v" , command , path , err )
272- return false
370+ return output , false
273371 }
274372
275373 if displayOutputOnSuccess {
276374 log .Printf ("Output: %s" , output )
277375 }
278376
279- return true
377+ return output , true
280378}
0 commit comments