env_test.go
1 // Copyright 2026 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtime 16 17 import ( 18 "os" 19 "path/filepath" 20 "strings" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 ) 25 26 func TestLoadExtraEnvFromFileUnset(t *testing.T) { 27 t.Setenv("EXECD_ENVS", "") 28 require.Nil(t, loadExtraEnvFromFile(), "expected nil when EXECD_ENVS unset") 29 } 30 31 func TestLoadExtraEnvFromFileParsesAndExpands(t *testing.T) { 32 dir := t.TempDir() 33 envFile := filepath.Join(dir, "env") 34 35 t.Setenv("EXECD_ENVS", envFile) 36 t.Setenv("BASE_DIR", "/opt/base") 37 38 content := strings.Join([]string{ 39 "# comment", 40 "FOO=bar", 41 "PATH=$BASE_DIR/bin", 42 "MALFORMED", 43 "EMPTY=", 44 "", 45 }, "\n") 46 47 require.NoError(t, os.WriteFile(envFile, []byte(content), 0o644)) 48 49 got := loadExtraEnvFromFile() 50 require.Len(t, got, 3) 51 require.Equal(t, "bar", got["FOO"]) 52 require.Equal(t, "/opt/base/bin", got["PATH"]) 53 val, ok := got["EMPTY"] 54 require.True(t, ok) 55 require.Equal(t, "", val) 56 } 57 58 func TestLoadExtraEnvFromFileMissingFile(t *testing.T) { 59 dir := t.TempDir() 60 envFile := filepath.Join(dir, "does-not-exist") 61 t.Setenv("EXECD_ENVS", envFile) 62 63 require.Nil(t, loadExtraEnvFromFile(), "expected nil for missing file") 64 } 65 66 func TestLoadExtraEnvFromFileSupportsHomePath(t *testing.T) { 67 home := t.TempDir() 68 t.Setenv("HOME", home) 69 t.Setenv("USERPROFILE", home) 70 71 envFile := filepath.Join(home, "extra.env") 72 require.NoError(t, os.WriteFile(envFile, []byte("FOO=bar\n"), 0o644)) 73 t.Setenv("EXECD_ENVS", "~/extra.env") 74 75 got := loadExtraEnvFromFile() 76 require.Equal(t, "bar", got["FOO"]) 77 } 78 79 func TestMergeEnvsOverlaysExtra(t *testing.T) { 80 base := []string{"A=1", "B=2"} 81 extra := map[string]string{"B": "override", "C": "3"} 82 83 merged := mergeEnvs(base, extra) 84 got := make(map[string]string) 85 for _, kv := range merged { 86 parts := strings.SplitN(kv, "=", 2) 87 if len(parts) == 2 { 88 got[parts[0]] = parts[1] 89 } 90 } 91 92 require.Len(t, got, 3) 93 require.Equal(t, "1", got["A"]) 94 require.Equal(t, "override", got["B"]) 95 require.Equal(t, "3", got["C"]) 96 } 97 98 func TestMergeExtraEnvsMergesAndOverrides(t *testing.T) { 99 fromFile := map[string]string{"A": "1", "B": "2"} 100 fromRequest := map[string]string{"B": "override", "C": "3"} 101 102 got := mergeExtraEnvs(fromFile, fromRequest) 103 104 require.Len(t, got, 3) 105 require.Equal(t, "1", got["A"]) 106 require.Equal(t, "override", got["B"]) 107 require.Equal(t, "3", got["C"]) 108 } 109 110 func TestMergeExtraEnvsHandlesNilFromFile(t *testing.T) { 111 fromRequest := map[string]string{"ONLY": "request"} 112 113 got := mergeExtraEnvs(nil, fromRequest) 114 115 require.Len(t, got, 1) 116 require.Equal(t, "request", got["ONLY"]) 117 }