github.com/hugorut/terraform@v1.1.3/src/cloud/e2e/migrate_state_single_to_tfc_test.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"os"
     7  	"testing"
     8  
     9  	expect "github.com/Netflix/go-expect"
    10  	tfe "github.com/hashicorp/go-tfe"
    11  	"github.com/hugorut/terraform/src/e2e"
    12  )
    13  
    14  func Test_migrate_single_to_tfc(t *testing.T) {
    15  	skipIfMissingEnvVar(t)
    16  	skipWithoutRemoteTerraformVersion(t)
    17  
    18  	ctx := context.Background()
    19  
    20  	cases := map[string]struct {
    21  		operations  []operationSets
    22  		validations func(t *testing.T, orgName string)
    23  	}{
    24  		"migrate using cloud workspace name strategy": {
    25  			operations: []operationSets{
    26  				{
    27  					prep: func(t *testing.T, orgName, dir string) {
    28  						tfBlock := terraformConfigLocalBackend()
    29  						writeMainTF(t, tfBlock, dir)
    30  					},
    31  					commands: []tfCommand{
    32  						{
    33  							command:           []string{"init"},
    34  							expectedCmdOutput: `Successfully configured the backend "local"!`,
    35  						},
    36  						{
    37  							command:         []string{"apply", "-auto-approve"},
    38  							postInputOutput: []string{`Apply complete!`},
    39  						},
    40  					},
    41  				},
    42  				{
    43  					prep: func(t *testing.T, orgName, dir string) {
    44  						wsName := "new-workspace"
    45  						tfBlock := terraformConfigCloudBackendName(orgName, wsName)
    46  						writeMainTF(t, tfBlock, dir)
    47  					},
    48  					commands: []tfCommand{
    49  						{
    50  							command:           []string{"init"},
    51  							expectedCmdOutput: `Migrating from backend "local" to Terraform Cloud.`,
    52  							userInput:         []string{"yes", "yes"},
    53  							postInputOutput: []string{
    54  								`Should Terraform migrate your existing state?`,
    55  								`Terraform Cloud has been successfully initialized!`},
    56  						},
    57  						{
    58  							command:           []string{"workspace", "list"},
    59  							expectedCmdOutput: `new-workspace`,
    60  						},
    61  					},
    62  				},
    63  			},
    64  			validations: func(t *testing.T, orgName string) {
    65  				wsList, err := tfeClient.Workspaces.List(ctx, orgName, tfe.WorkspaceListOptions{})
    66  				if err != nil {
    67  					t.Fatal(err)
    68  				}
    69  				ws := wsList.Items[0]
    70  				if ws.Name != "new-workspace" {
    71  					t.Fatalf("Expected workspace to be `new-workspace`, but is %s", ws.Name)
    72  				}
    73  			},
    74  		},
    75  		"migrate using cloud workspace tags strategy": {
    76  			operations: []operationSets{
    77  				{
    78  					prep: func(t *testing.T, orgName, dir string) {
    79  						tfBlock := terraformConfigLocalBackend()
    80  						writeMainTF(t, tfBlock, dir)
    81  					},
    82  					commands: []tfCommand{
    83  						{
    84  							command:           []string{"init"},
    85  							expectedCmdOutput: `Successfully configured the backend "local"!`,
    86  						},
    87  						{
    88  							command:         []string{"apply", "-auto-approve"},
    89  							postInputOutput: []string{`Apply complete!`},
    90  						},
    91  					},
    92  				},
    93  				{
    94  					prep: func(t *testing.T, orgName, dir string) {
    95  						tag := "app"
    96  						tfBlock := terraformConfigCloudBackendTags(orgName, tag)
    97  						writeMainTF(t, tfBlock, dir)
    98  					},
    99  					commands: []tfCommand{
   100  						{
   101  							command:           []string{"init"},
   102  							expectedCmdOutput: `Migrating from backend "local" to Terraform Cloud.`,
   103  							userInput:         []string{"yes", "new-workspace", "yes"},
   104  							postInputOutput: []string{
   105  								`Should Terraform migrate your existing state?`,
   106  								`Terraform Cloud requires all workspaces to be given an explicit name.`,
   107  								`Terraform Cloud has been successfully initialized!`},
   108  						},
   109  						{
   110  							command:           []string{"workspace", "list"},
   111  							expectedCmdOutput: `new-workspace`,
   112  						},
   113  					},
   114  				},
   115  			},
   116  			validations: func(t *testing.T, orgName string) {
   117  				wsList, err := tfeClient.Workspaces.List(ctx, orgName, tfe.WorkspaceListOptions{
   118  					Tags: tfe.String("app"),
   119  				})
   120  				if err != nil {
   121  					t.Fatal(err)
   122  				}
   123  				ws := wsList.Items[0]
   124  				if ws.Name != "new-workspace" {
   125  					t.Fatalf("Expected workspace to be `new-workspace`, but is %s", ws.Name)
   126  				}
   127  			},
   128  		},
   129  	}
   130  
   131  	for name, tc := range cases {
   132  		tc := tc
   133  		t.Run(name, func(t *testing.T) {
   134  			// t.Parallel()
   135  			organization, cleanup := createOrganization(t)
   136  			defer cleanup()
   137  			exp, err := expect.NewConsole(defaultOpts()...)
   138  			if err != nil {
   139  				t.Fatal(err)
   140  			}
   141  			defer exp.Close()
   142  
   143  			tmpDir, err := ioutil.TempDir("", "terraform-test")
   144  			if err != nil {
   145  				t.Fatal(err)
   146  			}
   147  			defer os.RemoveAll(tmpDir)
   148  
   149  			tf := e2e.NewBinary(terraformBin, tmpDir)
   150  			tf.AddEnv(cliConfigFileEnv)
   151  			defer tf.Close()
   152  
   153  			for _, op := range tc.operations {
   154  				op.prep(t, organization.Name, tf.WorkDir())
   155  				for _, tfCmd := range op.commands {
   156  					cmd := tf.Cmd(tfCmd.command...)
   157  					cmd.Stdin = exp.Tty()
   158  					cmd.Stdout = exp.Tty()
   159  					cmd.Stderr = exp.Tty()
   160  
   161  					err = cmd.Start()
   162  					if err != nil {
   163  						t.Fatal(err)
   164  					}
   165  
   166  					if tfCmd.expectedCmdOutput != "" {
   167  						got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
   168  						if err != nil {
   169  							t.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
   170  						}
   171  					}
   172  
   173  					lenInput := len(tfCmd.userInput)
   174  					lenInputOutput := len(tfCmd.postInputOutput)
   175  					if lenInput > 0 {
   176  						for i := 0; i < lenInput; i++ {
   177  							input := tfCmd.userInput[i]
   178  							exp.SendLine(input)
   179  							// use the index to find the corresponding
   180  							// output that matches the input.
   181  							if lenInputOutput-1 >= i {
   182  								output := tfCmd.postInputOutput[i]
   183  								_, err := exp.ExpectString(output)
   184  								if err != nil {
   185  									t.Fatal(err)
   186  								}
   187  							}
   188  						}
   189  					}
   190  
   191  					err = cmd.Wait()
   192  					if err != nil {
   193  						t.Fatal(err)
   194  					}
   195  				}
   196  			}
   197  
   198  			if tc.validations != nil {
   199  				tc.validations(t, organization.Name)
   200  			}
   201  		})
   202  	}
   203  }