Some checks failed
CI Workflow / Check GoReleaser config (pull_request) Successful in 6s
CI Workflow / CI (pull_request) Failing after 16m49s
CI Workflow / Code coverage report (pull_request) Has been skipped
CI Workflow / Test readiness for publishing provider (pull_request) Successful in 18m3s
219 lines
7.4 KiB
Go
219 lines
7.4 KiB
Go
package testutils
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"log/slog"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
|
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
|
"github.com/hashicorp/terraform-plugin-testing/config"
|
|
"github.com/hashicorp/terraform-plugin-testing/echoprovider"
|
|
"github.com/joho/godotenv"
|
|
|
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit"
|
|
)
|
|
|
|
const (
|
|
// Default location of credentials JSON
|
|
// credentialsFilePath = ".stackit/credentials.json" //nolint:gosec // linter false positive
|
|
serviceAccountFilePath = ".stackit/service_account.json"
|
|
)
|
|
|
|
var (
|
|
// TestAccProtoV6ProviderFactories is used to instantiate a provider during
|
|
// acceptance testing. The factory function will be invoked for every Terraform
|
|
// CLI command executed to create a provider server to which the CLI can
|
|
// reattach.
|
|
TestAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
|
|
"stackitprivatepreview": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
|
|
}
|
|
|
|
// TestEphemeralAccProtoV6ProviderFactories is used to instantiate a provider during
|
|
// acceptance testing. The factory function will be invoked for every Terraform
|
|
// CLI command executed to create a provider server to which the CLI can
|
|
// reattach.
|
|
//
|
|
// See the Terraform acceptance test documentation on ephemeral resources for more information:
|
|
// https://developer.hashicorp.com/terraform/plugin/testing/acceptance-tests/ephemeral-resources
|
|
TestEphemeralAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
|
|
"stackitprivatepreview": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
|
|
"echo": echoprovider.NewProviderServer(),
|
|
}
|
|
|
|
// E2ETestsEnabled checks if end-to-end tests should be run.
|
|
// It is enabled when the TF_ACC environment variable is set to "1".
|
|
E2ETestsEnabled = os.Getenv("TF_ACC") == "1"
|
|
// OrganizationId is the id of organization used for tests
|
|
OrganizationId = os.Getenv("TF_ACC_ORGANIZATION_ID")
|
|
// ProjectId is the id of project used for tests
|
|
ProjectId = os.Getenv("TF_ACC_PROJECT_ID")
|
|
Region = os.Getenv("TF_ACC_REGION")
|
|
// ServiceAccountFile is the json file of the service account
|
|
ServiceAccountFile = os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE")
|
|
// ServerId is the id of a server used for some tests
|
|
ServerId = getenv("TF_ACC_SERVER_ID", "")
|
|
// TestProjectParentContainerID is the container id of the parent resource under which projects are created as part of the resource-manager acceptance tests
|
|
TestProjectParentContainerID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID")
|
|
// TestProjectParentUUID is the uuid of the parent resource under which projects are created as part of the resource-manager acceptance tests
|
|
TestProjectParentUUID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_UUID")
|
|
// TestProjectServiceAccountEmail is the e-mail of a service account with admin permissions on the organization under which projects are created as part of the resource-manager acceptance tests
|
|
TestProjectServiceAccountEmail = os.Getenv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL")
|
|
// TestProjectUserEmail is the e-mail of a user for the project created as part of the resource-manager acceptance tests
|
|
// Default email: acc-test@sa.stackit.cloud
|
|
TestProjectUserEmail = getenv("TF_ACC_TEST_PROJECT_USER_EMAIL", "acc-test@sa.stackit.cloud")
|
|
// TestImageLocalFilePath is the local path to an image file used for image acceptance tests
|
|
TestImageLocalFilePath = getenv("TF_ACC_TEST_IMAGE_LOCAL_FILE_PATH", "default")
|
|
)
|
|
|
|
func Setup() {
|
|
root, err := getRoot()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
err = godotenv.Load(fmt.Sprintf("%s/.env", *root))
|
|
if err != nil {
|
|
slog.Info("could not find .env file - not loading .env")
|
|
return
|
|
}
|
|
slog.Info("loaded .env file", "path", *root)
|
|
}
|
|
|
|
func getRoot() (*string, error) {
|
|
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
lines := strings.Split(string(out), "\n")
|
|
return &lines[0], nil
|
|
}
|
|
|
|
func ResourceNameWithDateTime(name string) string {
|
|
dateTime := time.Now().Format(time.RFC3339)
|
|
// Remove timezone to have a smaller datetime
|
|
dateTimeTrimmed, _, _ := strings.Cut(dateTime, "+")
|
|
return fmt.Sprintf("tf-acc-%s-%s", name, dateTimeTrimmed)
|
|
}
|
|
|
|
func GetTestProjectServiceAccountJson(path string) string {
|
|
var err error
|
|
token, tokenSet := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_JSON")
|
|
if !tokenSet || token == "" {
|
|
token, err = readTestServiceAccountJsonFromFile(path)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
}
|
|
return token
|
|
}
|
|
|
|
// func GetTestProjectServiceAccountToken(path string) string {
|
|
// var err error
|
|
// token, tokenSet := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN")
|
|
// if !tokenSet || token == "" {
|
|
// token, err = readTestTokenFromCredentialsFile(path)
|
|
// if err != nil {
|
|
// return ""
|
|
// }
|
|
// }
|
|
// return token
|
|
//}
|
|
//
|
|
//func readTestTokenFromCredentialsFile(path string) (string, error) {
|
|
// if path == "" {
|
|
// customPath, customPathSet := os.LookupEnv("STACKIT_CREDENTIALS_PATH")
|
|
// if !customPathSet || customPath == "" {
|
|
// path = credentialsFilePath
|
|
// home, err := os.UserHomeDir()
|
|
// if err != nil {
|
|
// return "", fmt.Errorf("getting home directory: %w", err)
|
|
// }
|
|
// path = filepath.Join(home, path)
|
|
// } else {
|
|
// path = customPath
|
|
// }
|
|
// }
|
|
//
|
|
// credentialsRaw, err := os.ReadFile(path)
|
|
// if err != nil {
|
|
// return "", fmt.Errorf("opening file: %w", err)
|
|
// }
|
|
//
|
|
// var credentials struct {
|
|
// TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN string `json:"TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN"`
|
|
// }
|
|
// err = json.Unmarshal(credentialsRaw, &credentials)
|
|
// if err != nil {
|
|
// return "", fmt.Errorf("unmarshalling credentials: %w", err)
|
|
// }
|
|
// return credentials.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN, nil
|
|
//}
|
|
|
|
func readTestServiceAccountJsonFromFile(path string) (string, error) {
|
|
if path == "" {
|
|
customPath, customPathSet := os.LookupEnv("STACKIT_SERVICE_ACCOUNT_PATH")
|
|
if !customPathSet || customPath == "" {
|
|
path = serviceAccountFilePath
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return "", fmt.Errorf("getting home directory: %w", err)
|
|
}
|
|
path = filepath.Join(home, path)
|
|
} else {
|
|
path = customPath
|
|
}
|
|
}
|
|
|
|
credentialsRaw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return "", fmt.Errorf("opening file: %w", err)
|
|
}
|
|
return string(credentialsRaw), nil
|
|
}
|
|
|
|
func getenv(key, defaultValue string) string {
|
|
val := os.Getenv(key)
|
|
if val == "" {
|
|
return defaultValue
|
|
}
|
|
return val
|
|
}
|
|
|
|
// CreateDefaultLocalFile is a helper for local_file_path. No real data is created
|
|
func CreateDefaultLocalFile() os.File {
|
|
// Define the file name and size
|
|
fileName := "test-512k.img"
|
|
size := 512 * 1024 // 512 KB
|
|
|
|
// Create the file
|
|
file, err := os.Create(fileName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Seek to the desired position (512 KB)
|
|
_, err = file.Seek(int64(size), 0)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return *file
|
|
}
|
|
|
|
func ConvertConfigVariable(variable config.Variable) string {
|
|
tmpByteArray, _ := variable.MarshalJSON()
|
|
// In case the variable is a string, the quotes should be removed
|
|
if tmpByteArray[0] == '"' && tmpByteArray[len(tmpByteArray)-1] == '"' {
|
|
result := string(tmpByteArray[1 : len(tmpByteArray)-1])
|
|
// Replace escaped quotes which where added MarshalJSON
|
|
rawString := strings.ReplaceAll(result, `\"`, `"`)
|
|
return rawString
|
|
}
|
|
return string(tmpByteArray)
|
|
}
|