1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 // testGetenv gives us a controlled set of variables for testing Expand.
15 func testGetenv(s string) string {
37 var expandTests = []struct {
41 {"$*", "all the args"},
43 {"${*}", "all the args"},
45 {"${1}", "ARGUMENT1"},
46 {"now is the time", "now is the time"},
47 {"$HOME", "/usr/gopher"},
48 {"$home_1", "/usr/foo"},
49 {"${HOME}", "/usr/gopher"},
50 {"${H}OME", "(Value of H)OME"},
51 {"A$$$#$1$H$home_1*B", "APIDNARGSARGUMENT1(Value of H)/usr/foo*B"},
52 {"start$+middle$^end$", "start$+middle$^end$"},
53 {"mixed$|bag$$$", "mixed$|bagPID$"},
56 {"${", ""}, // invalid syntax; eat up the characters
57 {"${}", ""}, // invalid syntax; eat up the characters
60 func TestExpand(t *testing.T) {
61 for _, test := range expandTests {
62 result := Expand(test.in, testGetenv)
63 if result != test.out {
64 t.Errorf("Expand(%q)=%q; expected %q", test.in, result, test.out)
69 var global interface{}
71 func BenchmarkExpand(b *testing.B) {
72 b.Run("noop", func(b *testing.B) {
75 for i := 0; i < b.N; i++ {
76 s = Expand("tick tick tick tick", func(string) string { return "" })
80 b.Run("multiple", func(b *testing.B) {
83 for i := 0; i < b.N; i++ {
84 s = Expand("$a $a $a $a", func(string) string { return "boom" })
90 func TestConsistentEnviron(t *testing.T) {
92 for i := 0; i < 10; i++ {
94 if !reflect.DeepEqual(e0, e1) {
95 t.Fatalf("environment changed")
100 func TestUnsetenv(t *testing.T) {
101 const testKey = "GO_TEST_UNSETENV"
103 prefix := testKey + "="
104 for _, key := range Environ() {
105 if strings.HasPrefix(key, prefix) {
111 if err := Setenv(testKey, "1"); err != nil {
112 t.Fatalf("Setenv: %v", err)
115 t.Error("Setenv didn't set TestUnsetenv")
117 if err := Unsetenv(testKey); err != nil {
118 t.Fatalf("Unsetenv: %v", err)
121 t.Fatal("Unsetenv didn't clear TestUnsetenv")
125 func TestClearenv(t *testing.T) {
126 const testKey = "GO_TEST_CLEARENV"
127 const testValue = "1"
130 defer func(origEnv []string) {
131 for _, pair := range origEnv {
132 // Environment variables on Windows can begin with =
133 // https://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
134 i := strings.Index(pair[1:], "=") + 1
135 if err := Setenv(pair[:i], pair[i+1:]); err != nil {
136 t.Errorf("Setenv(%q, %q) failed during reset: %v", pair[:i], pair[i+1:], err)
141 if err := Setenv(testKey, testValue); err != nil {
142 t.Fatalf("Setenv(%q, %q) failed: %v", testKey, testValue, err)
144 if _, ok := LookupEnv(testKey); !ok {
145 t.Errorf("Setenv(%q, %q) didn't set $%s", testKey, testValue, testKey)
148 if val, ok := LookupEnv(testKey); ok {
149 t.Errorf("Clearenv() didn't clear $%s, remained with value %q", testKey, val)
153 func TestLookupEnv(t *testing.T) {
154 const smallpox = "SMALLPOX" // No one has smallpox.
155 value, ok := LookupEnv(smallpox) // Should not exist.
156 if ok || value != "" {
157 t.Fatalf("%s=%q", smallpox, value)
159 defer Unsetenv(smallpox)
160 err := Setenv(smallpox, "virus")
162 t.Fatalf("failed to release smallpox virus")
164 _, ok = LookupEnv(smallpox)
166 t.Errorf("smallpox release failed; world remains safe but LookupEnv is broken")