Skip to content

Commit ac716d0

Browse files
testbed: add and adopt WithEnvVar for child process (#30491)
**Description:** Adding a feature - These changes add a new `WithEnvVar` `ChildProcessOption` to be able to influence the child process environment without acting on the current environment. They also move the `GOMAXPROCS=2` setting added in dd8e010 to each invoking test because though being helpful to address #27429, the constraint doesn't seem applicable to the helper directly. Limiting the utility as a whole instead of specifying in the test context cannot be easily worked around and is interfering w/ some load testing efforts.
1 parent 071bf3c commit ac716d0

File tree

8 files changed

+92
-16
lines changed

8 files changed

+92
-16
lines changed

.chloggen/testbedmaxprocs.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: testbed
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Adds and adopts new WithEnvVar child process option, moving GOMAXPROCS=2 to initializations
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [30491]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [api]

testbed/testbed/child_process_collector.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"path"
1414
"path/filepath"
1515
"runtime"
16+
"sort"
1617
"strconv"
1718
"sync"
1819
"sync/atomic"
@@ -41,6 +42,9 @@ type childProcessCollector struct {
4142
// Command to execute
4243
cmd *exec.Cmd
4344

45+
// additional env vars (os.Environ() populated by default)
46+
additionalEnv map[string]string
47+
4448
// Various starting/stopping flags
4549
isStarted bool
4650
stopOnce sync.Once
@@ -85,7 +89,7 @@ type ChildProcessOption func(*childProcessCollector)
8589

8690
// NewChildProcessCollector creates a new OtelcolRunner as a child process on the same machine executing the test.
8791
func NewChildProcessCollector(options ...ChildProcessOption) OtelcolRunner {
88-
col := &childProcessCollector{}
92+
col := &childProcessCollector{additionalEnv: map[string]string{}}
8993

9094
for _, option := range options {
9195
option(col)
@@ -101,6 +105,13 @@ func WithAgentExePath(exePath string) ChildProcessOption {
101105
}
102106
}
103107

108+
// WithEnvVar sets an additional environment variable for the process
109+
func WithEnvVar(k, v string) ChildProcessOption {
110+
return func(cpc *childProcessCollector) {
111+
cpc.additionalEnv[k] = v
112+
}
113+
}
114+
104115
func (cp *childProcessCollector) PrepareConfig(configStr string) (configCleanup func(), err error) {
105116
configCleanup = func() {
106117
// NoOp
@@ -204,9 +215,17 @@ func (cp *childProcessCollector) Start(params StartParams) error {
204215
}
205216
// #nosec
206217
cp.cmd = exec.Command(exePath, args...)
207-
cp.cmd.Env = append(os.Environ(),
208-
"GOMAXPROCS=2",
209-
)
218+
cp.cmd.Env = os.Environ()
219+
220+
// update env deterministically
221+
var additionalEnvVars []string
222+
for k := range cp.additionalEnv {
223+
additionalEnvVars = append(additionalEnvVars, k)
224+
}
225+
sort.Strings(additionalEnvVars)
226+
for _, k := range additionalEnvVars {
227+
cp.cmd.Env = append(cp.cmd.Env, fmt.Sprintf("%s=%s", k, cp.additionalEnv[k]))
228+
}
210229

211230
// Capture standard output and standard error.
212231
cp.cmd.Stdout = logFile

testbed/testbed/child_process_collector_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package testbed // import "github.com/open-telemetry/opentelemetry-collector-contrib/testbed/testbed"
55

66
import (
7+
"os"
78
"testing"
89

910
"github.com/stretchr/testify/require"
@@ -18,3 +19,31 @@ func TestAgentExeOption(t *testing.T) {
1819
require.True(t, ok)
1920
require.Equal(t, path, cpc.agentExePath)
2021
}
22+
23+
func TestAgentEnvVarOption(t *testing.T) {
24+
col := NewChildProcessCollector(
25+
WithAgentExePath("not-real"),
26+
WithEnvVar("var-one", "var-one-value"),
27+
WithEnvVar("var-two", "var-two-value"),
28+
WithEnvVar("var-two", "actual-var-two-value"),
29+
)
30+
31+
cpc, ok := col.(*childProcessCollector)
32+
require.True(t, ok)
33+
34+
expeectedEnvVarMap := map[string]string{
35+
"var-one": "var-one-value",
36+
"var-two": "actual-var-two-value",
37+
}
38+
require.Equal(t, expeectedEnvVarMap, cpc.additionalEnv)
39+
40+
// results from `not-real` not being found but contents unrelated to this test
41+
require.Error(t, col.Start(
42+
StartParams{
43+
CmdArgs: []string{"--config", "to-prevent-builder"},
44+
LogFilePath: "/dev/null",
45+
},
46+
))
47+
expectedEnvVars := append(os.Environ(), "var-one=var-one-value", "var-two=actual-var-two-value")
48+
require.Equal(t, expectedEnvVars, cpc.cmd.Env)
49+
}

testbed/tests/e2e_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ func TestIdleMode(t *testing.T) {
2929
sender := testbed.NewOTLPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t))
3030
receiver := testbed.NewOTLPDataReceiver(testbed.GetAvailablePort(t))
3131
cfg := createConfigYaml(t, sender, receiver, resultDir, nil, nil)
32-
cp := testbed.NewChildProcessCollector()
32+
cp := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
33+
3334
cleanup, err := cp.PrepareConfig(cfg)
3435
require.NoError(t, err)
3536
t.Cleanup(cleanup)
@@ -77,7 +78,7 @@ func TestBallastMemory(t *testing.T) {
7778
ballastCfg := createConfigYaml(
7879
t, sender, receiver, resultDir, nil,
7980
map[string]string{"memory_ballast": fmt.Sprintf(ballastConfig, test.ballastSize)})
80-
cp := testbed.NewChildProcessCollector()
81+
cp := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
8182
cleanup, err := cp.PrepareConfig(ballastCfg)
8283
require.NoError(t, err)
8384
t.Cleanup(cleanup)

testbed/tests/metric_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func TestMetricsFromFile(t *testing.T) {
109109
// ItemsPerBatch is based on the data from the file.
110110
ItemsPerBatch: dataProvider.ItemsPerBatch,
111111
}
112-
agentProc := testbed.NewChildProcessCollector()
112+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
113113

114114
sender := testbed.NewOTLPMetricDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t))
115115
receiver := testbed.NewOTLPDataReceiver(testbed.GetAvailablePort(t))

testbed/tests/resource_processor_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func TestMetricResourceProcessor(t *testing.T) {
107107
resultDir, err := filepath.Abs(filepath.Join("results", t.Name()))
108108
require.NoError(t, err)
109109

110-
agentProc := testbed.NewChildProcessCollector()
110+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
111111
processors := map[string]string{
112112
"resource": test.resourceProcessorConfig,
113113
}

testbed/tests/scenarios.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func Scenario10kItemsPerSecond(
143143
ItemsPerBatch: 100,
144144
Parallel: 1,
145145
}
146-
agentProc := testbed.NewChildProcessCollector()
146+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
147147

148148
configStr := createConfigYaml(t, sender, receiver, resultDir, processors, extensions)
149149
configCleanup, err := agentProc.PrepareConfig(configStr)
@@ -201,7 +201,7 @@ func Scenario10kItemsPerSecondAlternateBackend(
201201
ItemsPerBatch: 100,
202202
Parallel: 1,
203203
}
204-
agentProc := testbed.NewChildProcessCollector()
204+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
205205

206206
configStr := createConfigYaml(t, sender, receiver, resultDir, processors, extensions)
207207
fmt.Println(configStr)
@@ -268,7 +268,7 @@ func Scenario1kSPSWithAttrs(t *testing.T, args []string, tests []TestCase, proce
268268

269269
options := constructLoadOptions(test)
270270

271-
agentProc := testbed.NewChildProcessCollector()
271+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
272272

273273
// Prepare results dir.
274274
resultDir, err := filepath.Abs(path.Join("results", t.Name()))
@@ -334,7 +334,7 @@ func ScenarioTestTraceNoBackend10kSPS(
334334
require.NoError(t, err)
335335

336336
options := testbed.LoadOptions{DataItemsPerSecond: 10000, ItemsPerBatch: 10}
337-
agentProc := testbed.NewChildProcessCollector()
337+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
338338
configStr := createConfigYaml(t, sender, receiver, resultDir, configuration.Processor, nil)
339339
configCleanup, err := agentProc.PrepareConfig(configStr)
340340
require.NoError(t, err)
@@ -378,7 +378,7 @@ func ScenarioSendingQueuesFull(
378378
resultDir, err := filepath.Abs(path.Join("results", t.Name()))
379379
require.NoError(t, err)
380380

381-
agentProc := testbed.NewChildProcessCollector()
381+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
382382

383383
configStr := createConfigYaml(t, sender, receiver, resultDir, processors, extensions)
384384
configCleanup, err := agentProc.PrepareConfig(configStr)
@@ -460,7 +460,7 @@ func ScenarioSendingQueuesNotFull(
460460
resultDir, err := filepath.Abs(path.Join("results", t.Name()))
461461
require.NoError(t, err)
462462

463-
agentProc := testbed.NewChildProcessCollector()
463+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
464464

465465
configStr := createConfigYaml(t, sender, receiver, resultDir, processors, extensions)
466466
configCleanup, err := agentProc.PrepareConfig(configStr)

testbed/tests/trace_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ func TestTraceAttributesProcessor(t *testing.T) {
445445
`,
446446
}
447447

448-
agentProc := testbed.NewChildProcessCollector()
448+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
449449
configStr := createConfigYaml(t, test.sender, test.receiver, resultDir, processors, nil)
450450
configCleanup, err := agentProc.PrepareConfig(configStr)
451451
require.NoError(t, err)
@@ -531,7 +531,7 @@ func TestTraceAttributesProcessorJaegerGRPC(t *testing.T) {
531531
`,
532532
}
533533

534-
agentProc := testbed.NewChildProcessCollector()
534+
agentProc := testbed.NewChildProcessCollector(testbed.WithEnvVar("GOMAXPROCS", "2"))
535535
configStr := createConfigYaml(t, sender, receiver, resultDir, processors, nil)
536536
configCleanup, err := agentProc.PrepareConfig(configStr)
537537
require.NoError(t, err)

0 commit comments

Comments
 (0)