mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 17:59:05 -05:00
114 lines
3.2 KiB
Go
114 lines
3.2 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package testmethod
|
|
|
|
import (
|
|
"context"
|
|
"embed"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
//go:embed data/*
|
|
var embedFS embed.FS
|
|
|
|
// Go builds a key provider as a Go binary and returns its path.
|
|
func Go(t *testing.T) []string {
|
|
t.Helper()
|
|
|
|
// goMod is embedded like this because the go:embed tag doesn't like having module files in embedded paths.
|
|
var goMod = []byte(`module testmethod
|
|
|
|
go 1.22`)
|
|
|
|
tempDir := t.TempDir()
|
|
dir := path.Join(tempDir, "testmethod-go")
|
|
if err := os.MkdirAll(dir, 0700); err != nil {
|
|
t.Errorf("Failed to create temporary directory (%v)", err)
|
|
}
|
|
|
|
if err := os.WriteFile(path.Join(dir, "go.mod"), goMod, 0600); err != nil {
|
|
t.Errorf("%v", err)
|
|
}
|
|
if err := ejectFile("testmethod.go", path.Join(dir, "testmethod.go")); err != nil {
|
|
t.Errorf("%v", err)
|
|
}
|
|
targetBinary := filepath.FromSlash(path.Join(dir, "testmethod"))
|
|
if runtime.GOOS == "windows" {
|
|
targetBinary += ".exe"
|
|
// If we do not use raw backslashes below, the binary won't be found by HCL after parsing.
|
|
targetBinary = strings.ReplaceAll(targetBinary, "\\", `\\`)
|
|
}
|
|
t.Logf("\033[32mCompiling test method binary...\033[0m")
|
|
cmd := exec.Command("go", "build", "-o", targetBinary)
|
|
cmd.Dir = dir
|
|
// TODO move this to a proper test logger once available.
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
if err := cmd.Run(); err != nil {
|
|
t.Skipf("Failed to build test method binary (%v)", err)
|
|
}
|
|
return []string{targetBinary}
|
|
}
|
|
|
|
// Python returns the path to a Python script acting as an encryption method. The function returns all arguments
|
|
// required to run the Python script, including the Python interpreter.
|
|
func Python(t *testing.T) []string {
|
|
t.Helper()
|
|
|
|
tempDir := t.TempDir()
|
|
dir := path.Join(tempDir, "testmethod-py")
|
|
if err := os.MkdirAll(dir, 0700); err != nil {
|
|
t.Errorf("Failed to create temporary directory (%v)", err)
|
|
}
|
|
target := path.Join(dir, "testmethod.py")
|
|
if runtime.GOOS == "windows" {
|
|
// If we do not use raw backslashes below, the binary won't be found by HCL after parsing.
|
|
target = strings.ReplaceAll(target, "\\", `\\`)
|
|
}
|
|
if err := ejectFile("testmethod.py", target); err != nil {
|
|
t.Errorf("%v", err)
|
|
}
|
|
python := findExecutable(t, []string{"python", "python3"}, []string{"--version"})
|
|
|
|
return []string{python, target}
|
|
}
|
|
|
|
func ejectFile(file string, target string) error {
|
|
contents, err := embedFS.ReadFile(path.Join("data", file))
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read %s file from embedded dataset (%w)", file, err)
|
|
}
|
|
if err := os.WriteFile(target, contents, 0600); err != nil {
|
|
return fmt.Errorf("failed to create %s file at %s (%w)", file, target, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func findExecutable(t *testing.T, options []string, testArguments []string) string {
|
|
for _, opt := range options {
|
|
var lastError error
|
|
func() {
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
|
defer cancel()
|
|
cmd := exec.CommandContext(ctx, opt, testArguments...)
|
|
lastError = cmd.Run()
|
|
}()
|
|
if lastError == nil {
|
|
return opt
|
|
}
|
|
}
|
|
t.Skipf("No viable alternative found between %s", strings.Join(options, ", "))
|
|
return ""
|
|
}
|