1package process
2
3import (
4 "strings"
5 "testing"
6
7 "github.com/stretchr/testify/require"
8)
9
10func TestMergeRuntimeSafety(t *testing.T) {
11 tests := []struct {
12 name string
13 environ []string
14 wantGODEBUG string
15 wantChanged bool
16 }{
17 {name: "missing", environ: []string{"HOME=/tmp"}, wantGODEBUG: "gcshrinkstackoff=1", wantChanged: true},
18 {name: "preserves settings", environ: []string{"GODEBUG=gctrace=1"}, wantGODEBUG: "gctrace=1,gcshrinkstackoff=1", wantChanged: true},
19 {name: "overrides unsafe value", environ: []string{"GODEBUG=gcshrinkstackoff=0,gctrace=1"}, wantGODEBUG: "gctrace=1,gcshrinkstackoff=1", wantChanged: true},
20 {name: "already safe", environ: []string{"GODEBUG=gctrace=1,gcshrinkstackoff=1"}, wantGODEBUG: "gctrace=1,gcshrinkstackoff=1", wantChanged: false},
21 {name: "safe first keeps position without exec", environ: []string{"GODEBUG=gcshrinkstackoff=1,gctrace=1"}, wantGODEBUG: "gcshrinkstackoff=1,gctrace=1", wantChanged: false},
22 {name: "collapses duplicates", environ: []string{"GODEBUG=gcshrinkstackoff=0,gcshrinkstackoff=1"}, wantGODEBUG: "gcshrinkstackoff=1", wantChanged: true},
23 {name: "bare key without value is unsafe", environ: []string{"GODEBUG=gcshrinkstackoff"}, wantGODEBUG: "gcshrinkstackoff=1", wantChanged: true},
24 {name: "preserves other debug keys", environ: []string{"GODEBUG=tracebacklabels=0,x509sslcertoverrideplatform=0"}, wantGODEBUG: "tracebacklabels=0,x509sslcertoverrideplatform=0,gcshrinkstackoff=1", wantChanged: true},
25 {name: "merges separate duplicate entries", environ: []string{"GODEBUG=gcshrinkstackoff=1", "GODEBUG=gctrace=1"}, wantGODEBUG: "gctrace=1,gcshrinkstackoff=1", wantChanged: true},
26 {name: "safe first entry does not hide second entry keys", environ: []string{"GODEBUG=gcshrinkstackoff=1", "GODEBUG=cpu.all=off"}, wantGODEBUG: "cpu.all=off,gcshrinkstackoff=1", wantChanged: true},
27 {name: "unsafe first entry preserves second entry keys", environ: []string{"GODEBUG=cpu.all=off", "GODEBUG=gcshrinkstackoff=1,foo=bar"}, wantGODEBUG: "cpu.all=off,foo=bar,gcshrinkstackoff=1", wantChanged: true},
28 }
29 for _, tt := range tests {
30 t.Run(tt.name, func(t *testing.T) {
31 got, changed := MergeRuntimeSafety(tt.environ)
32 require.Equal(t, tt.wantChanged, changed)
33 require.Equal(t, tt.wantGODEBUG, EnvironmentValue(got, "GODEBUG"))
34 if changed {
35 // Normalization always collapses to a single trailing
36 // entry; no duplicate GODEBUG may survive a change.
37 count := 0
38 for _, entry := range got {
39 if strings.HasPrefix(entry, "GODEBUG=") {
40 count++
41 }
42 }
43 require.Equal(t, 1, count, "changed environ must hold exactly one GODEBUG entry")
44 }
45 })
46 }
47}
48
49func TestMergeRuntimeSafetyDoesNotMutateInput(t *testing.T) {
50 input := []string{"GODEBUG=gctrace=1"}
51 got, changed := MergeRuntimeSafety(input)
52 require.True(t, changed)
53 require.Equal(t, []string{"GODEBUG=gctrace=1"}, input)
54 require.Equal(t, "gctrace=1,gcshrinkstackoff=1", EnvironmentValue(got, "GODEBUG"))
55}