6
6
"database/sql"
7
7
"fmt"
8
8
"net/http"
9
- "runtime"
9
+ "os"
10
+ "os/exec"
11
+ "path/filepath"
10
12
"sync/atomic"
11
13
"testing"
12
14
"time"
@@ -1399,13 +1401,10 @@ func TestTemplateDoesNotAllowUserAutostop(t *testing.T) {
1399
1401
// real Terraform provisioner and validate that the workspace is created
1400
1402
// successfully. The workspace itself does not specify any resources, and
1401
1403
// 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
1404
1407
func TestWorkspaceTagsTerraform (t * testing.T ) {
1405
- if runtime .GOOS != "windows" {
1406
- t .Parallel ()
1407
- }
1408
-
1409
1408
mainTfTemplate := `
1410
1409
terraform {
1411
1410
required_providers {
@@ -1424,6 +1423,8 @@ func TestWorkspaceTagsTerraform(t *testing.T) {
1424
1423
}
1425
1424
%s
1426
1425
`
1426
+ tfCliConfigPath := downloadProviders (t , fmt .Sprintf (mainTfTemplate , "" ))
1427
+ t .Setenv ("TF_CLI_CONFIG_FILE" , tfCliConfigPath )
1427
1428
1428
1429
for _ , tc := range []struct {
1429
1430
name string
@@ -1537,10 +1538,8 @@ func TestWorkspaceTagsTerraform(t *testing.T) {
1537
1538
} {
1538
1539
tc := tc
1539
1540
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 )
1544
1543
1545
1544
client , owner := coderdenttest .New (t , & coderdenttest.Options {
1546
1545
Options : & coderdtest.Options {
@@ -1587,6 +1586,55 @@ func TestWorkspaceTagsTerraform(t *testing.T) {
1587
1586
}
1588
1587
}
1589
1588
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
+
1590
1638
// Blocked by autostart requirements
1591
1639
func TestExecutorAutostartBlocked (t * testing.T ) {
1592
1640
t .Parallel ()
0 commit comments