Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions integration/bundle/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package bundle_test

import (
"fmt"
"os"
"testing"

"github.com/databricks/cli/internal/testutil"
)

// TestMain stages a local Terraform filesystem mirror via
// acceptance/install_terraform.py before any test in this package runs.
//
// The Databricks-internal CI runners that execute these tests cannot reach
// registry.terraform.io, so without this setup `bundle deploy` fails inside
// `terraform init` with "could not connect to registry.terraform.io: ... EOF".
// Routing through the local mirror also makes a plain `go test ./integration/bundle/...`
// work outside CI without any extra environment variables.
func TestMain(m *testing.M) {
if err := testutil.SetupTerraform(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to set up Terraform for integration tests: %v\n", err)
os.Exit(1)
}
os.Exit(m.Run())
}
83 changes: 83 additions & 0 deletions internal/testutil/terraform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package testutil

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
)

// SetupTerraform installs Terraform and the Databricks Terraform provider into a
// local filesystem mirror by invoking acceptance/install_terraform.py, then exports
// TF_CLI_CONFIG_FILE / DATABRICKS_TF_CLI_CONFIG_FILE / DATABRICKS_TF_EXEC_PATH /
// TERRAFORM so the CLI subprocess used by tests resolves the provider locally
// instead of contacting registry.terraform.io.
//
// Intended for use from TestMain in integration test packages: the setup runs
// once per `go test` invocation and behaves the same in CI (where
// registry.terraform.io is blocked by Databricks corp network policy) and on a
// developer's laptop.
func SetupTerraform() error {
repoRoot, err := findRepoRoot()
if err != nil {
return fmt.Errorf("locate repo root: %w", err)
}

scriptPath := filepath.Join(repoRoot, "acceptance", "install_terraform.py")
buildDir := filepath.Join(repoRoot, "acceptance", "build", runtime.GOOS+"_"+runtime.GOARCH)
if err := os.MkdirAll(buildDir, 0o755); err != nil {
return fmt.Errorf("create build dir %s: %w", buildDir, err)
}

cmd := exec.Command("python3", scriptPath, "--targetdir", buildDir)
cmd.Stdout = os.Stderr
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("%s: %w", scriptPath, err)
}

binarySuffix := ""
if runtime.GOOS == "windows" {
binarySuffix = ".exe"
}
terraformrcPath := filepath.Join(buildDir, ".terraformrc")
terraformExecPath := filepath.Join(buildDir, "terraform"+binarySuffix)

envs := map[string]string{
"TF_CLI_CONFIG_FILE": terraformrcPath,
"DATABRICKS_TF_CLI_CONFIG_FILE": terraformrcPath,
"DATABRICKS_TF_EXEC_PATH": terraformExecPath,
"TERRAFORM": terraformExecPath,
}
for k, v := range envs {
if err := os.Setenv(k, v); err != nil {
return fmt.Errorf("set %s: %w", k, err)
}
}
return nil
}

// findRepoRoot walks up from the current working directory until it finds a
// directory that contains both go.mod and acceptance/install_terraform.py. The
// pair uniquely identifies the cli repo root and avoids stopping at the nested
// tools/go.mod or any other module along the way.
func findRepoRoot() (string, error) {
cwd, err := os.Getwd()
if err != nil {
return "", err
}
dir := cwd
for {
_, modErr := os.Stat(filepath.Join(dir, "go.mod"))
_, scriptErr := os.Stat(filepath.Join(dir, "acceptance", "install_terraform.py"))
if modErr == nil && scriptErr == nil {
return dir, nil
}
parent := filepath.Dir(dir)
if parent == dir {
return "", fmt.Errorf("cli repo root not found searching up from %s", cwd)
}
dir = parent
}
}
Loading