## Description
<!-- **Please link some issue here describing what you are trying to achieve.**
In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->
relates to #1234
## Checklist
- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)
Reviewed-on: #58
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
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)
|
|
}
|