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

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"testing"
     8  	"time"
     9  
    10  	expect "github.com/Netflix/go-expect"
    11  	tfe "github.com/hashicorp/go-tfe"
    12  	"github.com/hashicorp/go-uuid"
    13  	goversion "github.com/hashicorp/go-version"
    14  	tfversion "github.com/hugorut/terraform/version"
    15  )
    16  
    17  const (
    18  	expectConsoleTimeout = 15 * time.Second
    19  )
    20  
    21  type tfCommand struct {
    22  	command           []string
    23  	expectedCmdOutput string
    24  	expectError       bool
    25  	userInput         []string
    26  	postInputOutput   []string
    27  }
    28  
    29  type operationSets struct {
    30  	commands []tfCommand
    31  	prep     func(t *testing.T, orgName, dir string)
    32  }
    33  
    34  type testCases map[string]struct {
    35  	operations  []operationSets
    36  	validations func(t *testing.T, orgName string)
    37  }
    38  
    39  func defaultOpts() []expect.ConsoleOpt {
    40  	opts := []expect.ConsoleOpt{
    41  		expect.WithDefaultTimeout(expectConsoleTimeout),
    42  	}
    43  	if verboseMode {
    44  		opts = append(opts, expect.WithStdout(os.Stdout))
    45  	}
    46  	return opts
    47  }
    48  
    49  func createOrganization(t *testing.T) (*tfe.Organization, func()) {
    50  	ctx := context.Background()
    51  	org, err := tfeClient.Organizations.Create(ctx, tfe.OrganizationCreateOptions{
    52  		Name:                  tfe.String("tst-" + randomString(t)),
    53  		Email:                 tfe.String(fmt.Sprintf("%s@tfe.local", randomString(t))),
    54  		CostEstimationEnabled: tfe.Bool(false),
    55  	})
    56  	if err != nil {
    57  		t.Fatal(err)
    58  	}
    59  
    60  	_, err = tfeClient.Admin.Organizations.Update(ctx, org.Name, tfe.AdminOrganizationUpdateOptions{
    61  		AccessBetaTools: tfe.Bool(true),
    62  	})
    63  	if err != nil {
    64  		t.Fatal(err)
    65  	}
    66  
    67  	return org, func() {
    68  		if err := tfeClient.Organizations.Delete(ctx, org.Name); err != nil {
    69  			t.Errorf("Error destroying organization! WARNING: Dangling resources\n"+
    70  				"may exist! The full error is shown below.\n\n"+
    71  				"Organization: %s\nError: %s", org.Name, err)
    72  		}
    73  	}
    74  }
    75  
    76  func createWorkspace(t *testing.T, orgName string, wOpts tfe.WorkspaceCreateOptions) *tfe.Workspace {
    77  	ctx := context.Background()
    78  	w, err := tfeClient.Workspaces.Create(ctx, orgName, wOpts)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  
    83  	return w
    84  }
    85  
    86  func getWorkspace(workspaces []*tfe.Workspace, workspace string) (*tfe.Workspace, bool) {
    87  	for _, ws := range workspaces {
    88  		if ws.Name == workspace {
    89  			return ws, false
    90  		}
    91  	}
    92  	return nil, true
    93  }
    94  
    95  func randomString(t *testing.T) string {
    96  	v, err := uuid.GenerateUUID()
    97  	if err != nil {
    98  		t.Fatal(err)
    99  	}
   100  	return v
   101  }
   102  
   103  func terraformConfigLocalBackend() string {
   104  	return `
   105  terraform {
   106    backend "local" {
   107    }
   108  }
   109  
   110  output "val" {
   111    value = "${terraform.workspace}"
   112  }
   113  `
   114  }
   115  
   116  func terraformConfigRemoteBackendName(org, name string) string {
   117  	return fmt.Sprintf(`
   118  terraform {
   119    backend "remote" {
   120      hostname = "%s"
   121      organization = "%s"
   122  
   123      workspaces {
   124        name = "%s"
   125      }
   126    }
   127  }
   128  
   129  output "val" {
   130    value = "${terraform.workspace}"
   131  }
   132  `, tfeHostname, org, name)
   133  }
   134  
   135  func terraformConfigRemoteBackendPrefix(org, prefix string) string {
   136  	return fmt.Sprintf(`
   137  terraform {
   138    backend "remote" {
   139      hostname = "%s"
   140      organization = "%s"
   141  
   142      workspaces {
   143        prefix = "%s"
   144      }
   145    }
   146  }
   147  
   148  output "val" {
   149    value = "${terraform.workspace}"
   150  }
   151  `, tfeHostname, org, prefix)
   152  }
   153  
   154  func terraformConfigCloudBackendTags(org, tag string) string {
   155  	return fmt.Sprintf(`
   156  terraform {
   157    cloud {
   158      hostname = "%s"
   159      organization = "%s"
   160  
   161      workspaces {
   162        tags = ["%s"]
   163      }
   164    }
   165  }
   166  
   167  output "tag_val" {
   168    value = "%s"
   169  }
   170  `, tfeHostname, org, tag, tag)
   171  }
   172  
   173  func terraformConfigCloudBackendName(org, name string) string {
   174  	return fmt.Sprintf(`
   175  terraform {
   176    cloud {
   177      hostname = "%s"
   178      organization = "%s"
   179  
   180      workspaces {
   181        name = "%s"
   182      }
   183    }
   184  }
   185  
   186  output "val" {
   187    value = "${terraform.workspace}"
   188  }
   189  `, tfeHostname, org, name)
   190  }
   191  
   192  func writeMainTF(t *testing.T, block string, dir string) {
   193  	f, err := os.Create(fmt.Sprintf("%s/main.tf", dir))
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  	_, err = f.WriteString(block)
   198  	if err != nil {
   199  		t.Fatal(err)
   200  	}
   201  	f.Close()
   202  }
   203  
   204  // The e2e tests rely on the fact that the terraform version in TFC/E is able to
   205  // run the `cloud` configuration block, which is available in 1.1 and will
   206  // continue to be available in later versions. So this function checks that
   207  // there is a version that is >= 1.1.
   208  func skipWithoutRemoteTerraformVersion(t *testing.T) {
   209  	version := tfversion.Version
   210  	baseVersion, err := goversion.NewVersion(version)
   211  	if err != nil {
   212  		t.Fatalf(fmt.Sprintf("Error instantiating go-version for %s", version))
   213  	}
   214  	opts := tfe.AdminTerraformVersionsListOptions{
   215  		ListOptions: tfe.ListOptions{
   216  			PageNumber: 1,
   217  			PageSize:   100,
   218  		},
   219  	}
   220  	hasVersion := false
   221  
   222  findTfVersion:
   223  	for {
   224  		// TODO: update go-tfe Read() to retrieve a terraform version by name.
   225  		// Currently you can only retrieve by ID.
   226  		tfVersionList, err := tfeClient.Admin.TerraformVersions.List(context.Background(), opts)
   227  		if err != nil {
   228  			t.Fatalf("Could not retrieve list of terraform versions: %v", err)
   229  		}
   230  		for _, item := range tfVersionList.Items {
   231  			availableVersion, err := goversion.NewVersion(item.Version)
   232  			if err != nil {
   233  				t.Logf("Error instantiating go-version for %s", item.Version)
   234  				continue
   235  			}
   236  			if availableVersion.Core().GreaterThanOrEqual(baseVersion.Core()) {
   237  				hasVersion = true
   238  				break findTfVersion
   239  			}
   240  		}
   241  
   242  		// Exit the loop when we've seen all pages.
   243  		if tfVersionList.CurrentPage >= tfVersionList.TotalPages {
   244  			break
   245  		}
   246  
   247  		// Update the page number to get the next page.
   248  		opts.PageNumber = tfVersionList.NextPage
   249  	}
   250  
   251  	if !hasVersion {
   252  		t.Skip(fmt.Sprintf("Skipping test because TFC/E does not have current Terraform version to test with (%s)", version))
   253  	}
   254  }