Source file
src/syscall/env_unix_test.go
1
2
3
4
5
6
7 package syscall_test
8
9 import (
10 "fmt"
11 "strconv"
12 "strings"
13 "syscall"
14 "testing"
15 )
16
17 type env struct {
18 name, val string
19 }
20
21 func genDummyEnv(tb testing.TB, size int) []env {
22 tb.Helper()
23 envList := make([]env, size)
24 for idx := range size {
25 envList[idx] = env{
26 name: fmt.Sprintf("DUMMY_VAR_%d", idx),
27 val: fmt.Sprintf("val-%d", idx*100),
28 }
29 }
30 return envList
31 }
32
33 func setDummyEnv(tb testing.TB, envList []env) {
34 tb.Helper()
35 for _, env := range envList {
36 if err := syscall.Setenv(env.name, env.val); err != nil {
37 tb.Fatalf("setenv %s=%q failed: %v", env.name, env.val, err)
38 }
39 }
40 }
41
42 func setupEnvCleanup(tb testing.TB) {
43 tb.Helper()
44 originalEnv := map[string]string{}
45 for _, env := range syscall.Environ() {
46 fields := strings.SplitN(env, "=", 2)
47 name, val := fields[0], fields[1]
48 originalEnv[name] = val
49 }
50 tb.Cleanup(func() {
51 syscall.Clearenv()
52 for name, val := range originalEnv {
53 if err := syscall.Setenv(name, val); err != nil {
54 tb.Fatalf("could not reset env %s=%q: %v", name, val, err)
55 }
56 }
57 })
58 }
59
60 func TestClearenv(t *testing.T) {
61 setupEnvCleanup(t)
62
63 t.Run("DummyVars-4096", func(t *testing.T) {
64 envList := genDummyEnv(t, 4096)
65 setDummyEnv(t, envList)
66
67 if env := syscall.Environ(); len(env) < 4096 {
68 t.Fatalf("env is missing dummy variables: %v", env)
69 }
70 for idx := range 4096 {
71 name := fmt.Sprintf("DUMMY_VAR_%d", idx)
72 if _, ok := syscall.Getenv(name); !ok {
73 t.Fatalf("env is missing dummy variable %s", name)
74 }
75 }
76
77 syscall.Clearenv()
78
79 if env := syscall.Environ(); len(env) != 0 {
80 t.Fatalf("clearenv should've cleared all variables: %v still set", env)
81 }
82 for idx := range 4096 {
83 name := fmt.Sprintf("DUMMY_VAR_%d", idx)
84 if val, ok := syscall.Getenv(name); ok {
85 t.Fatalf("clearenv should've cleared all variables: %s=%q still set", name, val)
86 }
87 }
88 })
89
90
91 t.Run("GODEBUG", func(t *testing.T) {
92 envList := genDummyEnv(t, 100)
93 setDummyEnv(t, envList)
94
95 doNilPanic := func() (ret any) {
96 defer func() {
97 ret = recover()
98 }()
99 panic(nil)
100 }
101
102
103 if err := syscall.Setenv("GODEBUG", "panicnil=1"); err != nil {
104 t.Fatalf("setenv GODEBUG=panicnil=1 failed: %v", err)
105 }
106
107 got := doNilPanic()
108 if got != nil {
109 t.Fatalf("GODEBUG=panicnil=1 did not allow for nil panic: got %#v", got)
110 }
111
112
113 syscall.Clearenv()
114
115 if env := syscall.Environ(); len(env) != 0 {
116 t.Fatalf("clearenv should've cleared all variables: %v still set", env)
117 }
118
119 got = doNilPanic()
120 if got == nil {
121 t.Fatalf("GODEBUG=panicnil=1 being unset didn't reset panicnil behaviour")
122 }
123 if godebug, ok := syscall.Getenv("GODEBUG"); ok {
124 t.Fatalf("GODEBUG still exists in environment despite being unset: GODEBUG=%q", godebug)
125 }
126 })
127 }
128
129 func BenchmarkClearenv(b *testing.B) {
130 setupEnvCleanup(b)
131 b.ResetTimer()
132 for _, size := range []int{100, 1000, 10000} {
133 b.Run(strconv.Itoa(size), func(b *testing.B) {
134 envList := genDummyEnv(b, size)
135 for b.Loop() {
136
137
138
139 setDummyEnv(b, envList)
140 syscall.Clearenv()
141 }
142 })
143 }
144 }
145
View as plain text