66 "database/sql"
77 "fmt"
88 "net/http"
9- "runtime"
9+ "os"
10+ "os/exec"
11+ "path/filepath"
1012 "sync/atomic"
1113 "testing"
1214 "time"
@@ -1399,13 +1401,10 @@ func TestTemplateDoesNotAllowUserAutostop(t *testing.T) {
13991401// real Terraform provisioner and validate that the workspace is created
14001402// successfully. The workspace itself does not specify any resources, and
14011403// this is fine.
1402- // nolint:paralleltest // this test tends to time out on windows runners
1403- // when run in parallel
1404+ // To improve speed, we pre-download the providers and set a custom Terraform
1405+ // config file so that we only reference those
1406+ // nolint:paralleltest // t.Setenv
14041407func TestWorkspaceTagsTerraform (t * testing.T ) {
1405- if runtime .GOOS != "windows" {
1406- t .Parallel ()
1407- }
1408-
14091408 mainTfTemplate := `
14101409 terraform {
14111410 required_providers {
@@ -1424,6 +1423,8 @@ func TestWorkspaceTagsTerraform(t *testing.T) {
14241423 }
14251424 %s
14261425 `
1426+ tfCliConfigPath := downloadProviders (t , fmt .Sprintf (mainTfTemplate , "" ))
1427+ t .Setenv ("TF_CLI_CONFIG_FILE" , tfCliConfigPath )
14271428
14281429 for _ , tc := range []struct {
14291430 name string
@@ -1537,10 +1538,8 @@ func TestWorkspaceTagsTerraform(t *testing.T) {
15371538 } {
15381539 tc := tc
15391540 t .Run (tc .name , func (t * testing.T ) {
1540- if runtime .GOOS != "windows" {
1541- t .Parallel ()
1542- }
1543- ctx := testutil .Context (t , testutil .WaitSuperLong )
1541+ // This can take a while, so set a relatively long timeout.
1542+ ctx := testutil .Context (t , 2 * testutil .WaitSuperLong )
15441543
15451544 client , owner := coderdenttest .New (t , & coderdenttest.Options {
15461545 Options : & coderdtest.Options {
@@ -1587,6 +1586,55 @@ func TestWorkspaceTagsTerraform(t *testing.T) {
15871586 }
15881587}
15891588
1589+ // downloadProviders is a test helper that creates a temporary file and writes a
1590+ // terraform CLI config file with a provider_installation stanza for coder/coder
1591+ // using dev_overrides. It also fetches the latest provider release from GitHub
1592+ // and extracts the binary to the temporary dir. It is the responsibility of the
1593+ // caller to set TF_CLI_CONFIG_FILE.
1594+ func downloadProviders (t * testing.T , providersTf string ) string {
1595+ t .Helper ()
1596+ // We firstly write a Terraform CLI config file to a temporary directory:
1597+ var (
1598+ ctx , cancel = context .WithTimeout (context .Background (), testutil .WaitLong )
1599+ tempDir = t .TempDir ()
1600+ cacheDir = filepath .Join (tempDir , ".cache" )
1601+ providersTfPath = filepath .Join (tempDir , "providers.tf" )
1602+ cliConfigPath = filepath .Join (tempDir , "local.tfrc" )
1603+ )
1604+ defer cancel ()
1605+
1606+ // Write files to disk
1607+ require .NoError (t , os .MkdirAll (cacheDir , os .ModePerm | os .ModeDir ))
1608+ require .NoError (t , os .WriteFile (providersTfPath , []byte (providersTf ), os .ModePerm )) // nolint:gosec
1609+ cliConfigTemplate := `
1610+ provider_installation {
1611+ filesystem_mirror {
1612+ path = %q
1613+ include = ["*/*/*"]
1614+ }
1615+ direct {
1616+ exclude = ["*/*/*"]
1617+ }
1618+ }`
1619+ err := os .WriteFile (cliConfigPath , []byte (fmt .Sprintf (cliConfigTemplate , cacheDir )), os .ModePerm ) // nolint:gosec
1620+ require .NoError (t , err , "failed to write %s" , cliConfigPath )
1621+
1622+ // Run terraform providers mirror to mirror required providers to cacheDir
1623+ cmd := exec .CommandContext (ctx , "terraform" , "providers" , "mirror" , cacheDir )
1624+ cmd .Env = os .Environ () // without this terraform may complain about path
1625+ cmd .Env = append (cmd .Env , "TF_CLI_CONFIG_FILE=" + cliConfigPath )
1626+ cmd .Dir = tempDir
1627+ out , err := cmd .CombinedOutput ()
1628+ if ! assert .NoError (t , err ) {
1629+ t .Log ("failed to download providers:" )
1630+ t .Log (string (out ))
1631+ t .FailNow ()
1632+ }
1633+
1634+ t .Logf ("Set TF_CLI_CONFIG_FILE=%s" , cliConfigPath )
1635+ return cliConfigPath
1636+ }
1637+
15901638// Blocked by autostart requirements
15911639func TestExecutorAutostartBlocked (t * testing.T ) {
15921640 t .Parallel ()
0 commit comments