aboutsummaryrefslogtreecommitdiff
path: root/compiler_wrapper/env_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_wrapper/env_test.go')
-rw-r--r--compiler_wrapper/env_test.go215
1 files changed, 215 insertions, 0 deletions
diff --git a/compiler_wrapper/env_test.go b/compiler_wrapper/env_test.go
new file mode 100644
index 00000000..05d7d136
--- /dev/null
+++ b/compiler_wrapper/env_test.go
@@ -0,0 +1,215 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "flag"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+// Attention: The tests in this file execute the test binary again with the `-run` flag.
+// This is needed as they want to test an `exec`, which terminates the test process.
+var internalexececho = flag.Bool("internalexececho", false, "internal flag used for tests that exec")
+
+func TestProcessEnvExecPathAndArgs(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ if *internalexececho {
+ execEcho(ctx, &command{
+ Path: "some_binary",
+ Args: []string{"arg1", "arg2"},
+ })
+ return
+ }
+ logLines := forkAndReadEcho(ctx)
+ if !strings.HasSuffix(logLines[0], "/some_binary arg1 arg2") {
+ t.Errorf("incorrect path or args: %s", logLines[0])
+ }
+ })
+}
+
+func TestProcessEnvExecAddEnv(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ if *internalexececho {
+ execEcho(ctx, &command{
+ Path: "some_binary",
+ EnvUpdates: []string{"ABC=xyz"},
+ })
+ return
+ }
+
+ logLines := forkAndReadEcho(ctx)
+ for _, ll := range logLines {
+ if ll == "ABC=xyz" {
+ return
+ }
+ }
+ t.Errorf("could not find new env variable: %s", logLines)
+ })
+}
+
+func TestProcessEnvExecUpdateEnv(t *testing.T) {
+ if os.Getenv("PATH") == "" {
+ t.Fatal("no PATH environment variable found!")
+ }
+ withTestContext(t, func(ctx *testContext) {
+ if *internalexececho {
+ execEcho(ctx, &command{
+ Path: "some_binary",
+ EnvUpdates: []string{"PATH=xyz"},
+ })
+ return
+ }
+ logLines := forkAndReadEcho(ctx)
+ for _, ll := range logLines {
+ if ll == "PATH=xyz" {
+ return
+ }
+ }
+ t.Errorf("could not find updated env variable: %s", logLines)
+ })
+}
+
+func TestProcessEnvExecDeleteEnv(t *testing.T) {
+ if os.Getenv("PATH") == "" {
+ t.Fatal("no PATH environment variable found!")
+ }
+ withTestContext(t, func(ctx *testContext) {
+ if *internalexececho {
+ execEcho(ctx, &command{
+ Path: "some_binary",
+ EnvUpdates: []string{"PATH="},
+ })
+ return
+ }
+ logLines := forkAndReadEcho(ctx)
+ for _, ll := range logLines {
+ if strings.HasPrefix(ll, "PATH=") {
+ t.Errorf("path env was not removed: %s", ll)
+ }
+ }
+ })
+}
+
+func TestProcessEnvRunCmdPathAndArgs(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ cmd := &command{
+ Path: "some_binary",
+ Args: []string{"arg1", "arg2"},
+ }
+ logLines := runAndEcho(ctx, cmd)
+ if !strings.HasSuffix(logLines[0], "/some_binary arg1 arg2") {
+ t.Errorf("incorrect path or args: %s", logLines[0])
+ }
+ })
+}
+
+func TestProcessEnvRunCmdAddEnv(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ cmd := &command{
+ Path: "some_binary",
+ EnvUpdates: []string{"ABC=xyz"},
+ }
+ logLines := runAndEcho(ctx, cmd)
+ for _, ll := range logLines {
+ if ll == "ABC=xyz" {
+ return
+ }
+ }
+ t.Errorf("could not find new env variable: %s", logLines)
+ })
+}
+
+func TestProcessEnvRunCmdUpdateEnv(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ if os.Getenv("PATH") == "" {
+ t.Fatal("no PATH environment variable found!")
+ }
+ cmd := &command{
+ Path: "some_binary",
+ EnvUpdates: []string{"PATH=xyz"},
+ }
+ logLines := runAndEcho(ctx, cmd)
+ for _, ll := range logLines {
+ if ll == "PATH=xyz" {
+ return
+ }
+ }
+ t.Errorf("could not find updated env variable: %s", logLines)
+ })
+}
+
+func TestProcessEnvRunCmdDeleteEnv(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ if os.Getenv("PATH") == "" {
+ t.Fatal("no PATH environment variable found!")
+ }
+ cmd := &command{
+ Path: "some_binary",
+ EnvUpdates: []string{"PATH="},
+ }
+ logLines := runAndEcho(ctx, cmd)
+ for _, ll := range logLines {
+ if strings.HasPrefix(ll, "PATH=") {
+ t.Errorf("path env was not removed: %s", ll)
+ }
+ }
+ })
+}
+
+func execEcho(ctx *testContext, cmd *command) {
+ env := &processEnv{}
+ err := env.exec(createEcho(ctx, cmd))
+ if err != nil {
+ os.Stderr.WriteString(err.Error())
+ }
+ os.Exit(1)
+}
+
+func forkAndReadEcho(ctx *testContext) []string {
+ testBin, err := os.Executable()
+ if err != nil {
+ ctx.t.Fatalf("unable to read the executable: %s", err)
+ }
+
+ subCmd := exec.Command(testBin, "-internalexececho", "-test.run="+ctx.t.Name())
+ output, err := subCmd.CombinedOutput()
+ if err != nil {
+ ctx.t.Fatalf("error calling test binary again for exec: %s", err)
+ }
+ return strings.Split(string(output), "\n")
+}
+
+func runAndEcho(ctx *testContext, cmd *command) []string {
+ env, err := newProcessEnv()
+ if err != nil {
+ ctx.t.Fatalf("creation of process env failed: %s", err)
+ }
+ buffer := bytes.Buffer{}
+ if err := env.run(createEcho(ctx, cmd), nil, &buffer, &buffer); err != nil {
+ ctx.t.Fatalf("run failed: %s", err)
+ }
+ return strings.Split(buffer.String(), "\n")
+}
+
+func createEcho(ctx *testContext, cmd *command) *command {
+ content := `
+/usr/bin/echo "$0" "$@"
+/usr/bin/env
+`
+ fullPath := filepath.Join(ctx.tempDir, cmd.Path)
+ ctx.writeFile(fullPath, content)
+ // Note: Using a self executable wrapper does not work due to a race condition
+ // on unix systems. See https://github.com/golang/go/issues/22315
+ return &command{
+ Path: "bash",
+ Args: append([]string{fullPath}, cmd.Args...),
+ EnvUpdates: cmd.EnvUpdates,
+ }
+}