package config_test import ( "fmt" "os" "path" "reflect" "slices" "strings" "testing" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/recipe" ) var ( TestFolder = os.ExpandEnv("$PWD/../../tests/resources/test_folder") ValidAbraConf = os.ExpandEnv("$PWD/../../tests/resources/valid_abra_config") ) // make sure these are in alphabetical order var ( TFolders = []string{"folder1", "folder2"} TFiles = []string{"bar.env", "foo.env"} ) var ( AppName = "ecloud" ServerName = "evil.corp" ) var ExpectedAppEnv = config.AppEnv{ "DOMAIN": "ecloud.evil.corp", "RECIPE": "ecloud", } var ExpectedApp = config.App{ Name: AppName, Recipe: ExpectedAppEnv["RECIPE"], Domain: ExpectedAppEnv["DOMAIN"], Env: ExpectedAppEnv, Path: ExpectedAppFile.Path, Server: ExpectedAppFile.Server, } var ExpectedAppFile = config.AppFile{ Path: path.Join(ValidAbraConf, "servers", ServerName, AppName+".env"), Server: ServerName, } var ExpectedAppFiles = map[string]config.AppFile{ AppName: ExpectedAppFile, } func TestGetAllFoldersInDirectory(t *testing.T) { folders, err := config.GetAllFoldersInDirectory(TestFolder) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(folders, TFolders) { t.Fatalf("did not get expected folders. Expected: (%s), Got: (%s)", strings.Join(TFolders, ","), strings.Join(folders, ",")) } } func TestGetAllFilesInDirectory(t *testing.T) { files, err := config.GetAllFilesInDirectory(TestFolder) if err != nil { t.Fatal(err) } var fileNames []string for _, file := range files { fileNames = append(fileNames, file.Name()) } if !reflect.DeepEqual(fileNames, TFiles) { t.Fatalf("did not get expected files. Expected: (%s), Got: (%s)", strings.Join(TFiles, ","), strings.Join(fileNames, ",")) } } func TestReadEnv(t *testing.T) { env, err := config.ReadEnv(ExpectedAppFile.Path) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(env, ExpectedAppEnv) { t.Fatalf( "did not get expected application settings. Expected: DOMAIN=%s RECIPE=%s; Got: DOMAIN=%s RECIPE=%s", ExpectedAppEnv["DOMAIN"], ExpectedAppEnv["RECIPE"], env["DOMAIN"], env["RECIPE"], ) } } func TestReadAbraShEnvVars(t *testing.T) { offline := true r, err := recipe.Get("abra-test-recipe", offline) if err != nil { t.Fatal(err) } abraShPath := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, r.Name, "abra.sh") abraShEnv, err := config.ReadAbraShEnvVars(abraShPath) if err != nil { t.Fatal(err) } if len(abraShEnv) == 0 { t.Error("at least one env var should be exported") } if _, ok := abraShEnv["INNER_FOO"]; ok { t.Error("INNER_FOO should not be exported") } if _, ok := abraShEnv["INNER_BAZ"]; ok { t.Error("INNER_BAZ should not be exported") } if _, ok := abraShEnv["OUTER_FOO"]; !ok { t.Error("OUTER_FOO should be exported") } } func TestReadAbraShCmdNames(t *testing.T) { offline := true r, err := recipe.Get("abra-test-recipe", offline) if err != nil { t.Fatal(err) } abraShPath := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, r.Name, "abra.sh") cmdNames, err := config.ReadAbraShCmdNames(abraShPath) if err != nil { t.Fatal(err) } if len(cmdNames) == 0 { t.Error("at least one command name should be found") } expectedCmdNames := []string{"test_cmd", "test_cmd_args"} for _, cmdName := range expectedCmdNames { if !slices.Contains(cmdNames, cmdName) { t.Fatalf("%s should have been found in %s", cmdName, abraShPath) } } } func TestCheckEnv(t *testing.T) { offline := true r, err := recipe.Get("abra-test-recipe", offline) if err != nil { t.Fatal(err) } envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSample, err := config.ReadEnv(envSamplePath) if err != nil { t.Fatal(err) } app := config.App{ Name: "test-app", Recipe: r.Name, Domain: "example.com", Env: envSample, Path: "example.com.env", Server: "example.com", } envVars, err := config.CheckEnv(app) if err != nil { t.Fatal(err) } for _, envVar := range envVars { if !envVar.Present { t.Fatalf("%s should be present", envVar.Name) } } } func TestCheckEnvError(t *testing.T) { offline := true r, err := recipe.Get("abra-test-recipe", offline) if err != nil { t.Fatal(err) } envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSample, err := config.ReadEnv(envSamplePath) if err != nil { t.Fatal(err) } delete(envSample, "DOMAIN") app := config.App{ Name: "test-app", Recipe: r.Name, Domain: "example.com", Env: envSample, Path: "example.com.env", Server: "example.com", } envVars, err := config.CheckEnv(app) if err != nil { t.Fatal(err) } for _, envVar := range envVars { if envVar.Name == "DOMAIN" && envVar.Present { t.Fatalf("%s should not be present", envVar.Name) } } } func TestEnvVarCommentsRemoved(t *testing.T) { offline := true r, err := recipe.Get("abra-test-recipe", offline) if err != nil { t.Fatal(err) } envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSample, err := config.ReadEnv(envSamplePath) if err != nil { t.Fatal(err) } envVar, exists := envSample["WITH_COMMENT"] if !exists { t.Fatal("WITH_COMMENT env var should be present in .env.sample") } if strings.Contains(envVar, "should be removed") { t.Fatalf("comment from '%s' should be removed", envVar) } envVar, exists = envSample["SECRET_TEST_PASS_TWO_VERSION"] if !exists { t.Fatal("WITH_COMMENT env var should be present in .env.sample") } if strings.Contains(envVar, "length") { t.Fatal("comment from env var SECRET_TEST_PASS_TWO_VERSION should have been removed") } } func TestEnvVarModifiersIncluded(t *testing.T) { offline := true r, err := recipe.Get("abra-test-recipe", offline) if err != nil { t.Fatal(err) } envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSample, modifiers, err := config.ReadEnvWithModifiers(envSamplePath) if err != nil { t.Fatal(err) } if !strings.Contains(envSample["SECRET_TEST_PASS_TWO_VERSION"], "v1") { t.Errorf("value should be 'v1', got: '%s'", envSample["SECRET_TEST_PASS_TWO_VERSION"]) } if modifiers == nil || modifiers["SECRET_TEST_PASS_TWO_VERSION"] == nil { t.Errorf("no modifiers included") } else { if modifiers["SECRET_TEST_PASS_TWO_VERSION"]["length"] != "10" { t.Errorf("length modifier should be '10', got: '%s'", modifiers["SECRET_TEST_PASS_TWO_VERSION"]["length"]) } } }