aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/shell/integration/action_env_test.sh
blob: f1fe4a5d59d7d722cd3c0ba5c5ce8658d7700cff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#!/bin/bash
#
# Copyright 2016 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# An end-to-end test that Bazel's provides the correct environment variables
# to actions.

# Load the test setup defined in the parent directory
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CURRENT_DIR}/../integration_test_setup.sh" \
  || { echo "integration_test_setup.sh not found!" >&2; exit 1; }

#### SETUP #############################################################

set -e

function set_up() {
  mkdir -p pkg
  cat > pkg/BUILD <<EOF
genrule(
  name = "showenv",
  outs = ["env.txt"],
  cmd = "env | sort > \"\$@\""
)

load("//pkg:build.bzl", "environ")

environ(name = "no_default_env", env = 0)
environ(name = "with_default_env", env = 1)

sh_test(
    name = "test_env_foo",
    srcs = ["test_env_foo.sh"],
)
EOF
  cat > pkg/build.bzl <<EOF
def _impl(ctx):
  output = ctx.outputs.out
  ctx.actions.run_shell(
      inputs=[],
      outputs=[output],
      use_default_shell_env = ctx.attr.env,
      command="env > %s" % output.path)

environ = rule(
    implementation=_impl,
    attrs={"env": attr.bool(default=True)},
    outputs={"out": "%{name}.env"},
)
EOF
  cat > pkg/test_env_foo.sh <<'EOF'
#!/bin/sh

echo "FOO is >${FOO}<"

{ echo "${FOO}" | grep foo; } || { echo "expected FOO to contain foo"; exit 1; }

EOF
  chmod u+x pkg/test_env_foo.sh
}

#### TESTS #############################################################

function test_simple() {
  export FOO=baz
  bazel build --action_env=FOO=bar pkg:showenv \
      || fail "${PRODUCT_NAME} build showenv failed"

  cat `bazel info ${PRODUCT_NAME}-genfiles`/pkg/env.txt > $TEST_log
  expect_log "FOO=bar"
}

function test_simple_latest_wins() {
  export FOO=environmentfoo
  export BAR=environmentbar
  bazel build --action_env=FOO=foo \
      --action_env=BAR=willbeoverridden --action_env=BAR=bar pkg:showenv \
      || fail "${PRODUCT_NAME} build showenv failed"

  cat `bazel info ${PRODUCT_NAME}-genfiles`/pkg/env.txt > $TEST_log
  expect_log "FOO=foo"
  expect_log "BAR=bar"
}

function test_client_env() {
  export FOO=startup_foo
  bazel clean --expunge
  bazel help build > /dev/null || fail "${PRODUCT_NAME} help failed"
  export FOO=client_foo
  bazel build --action_env=FOO pkg:showenv || \
    fail "${PRODUCT_NAME} build showenv failed"

  cat `bazel info ${PRODUCT_NAME}-genfiles`/pkg/env.txt > $TEST_log
  expect_log "FOO=client_foo"
}

function test_redo_action() {
  export FOO=initial_foo
  export UNRELATED=some_value
  bazel build --action_env=FOO pkg:showenv \
    || fail "${PRODUCT_NAME} build showenv failed"

  cat `bazel info ${PRODUCT_NAME}-genfiles`/pkg/env.txt > $TEST_log
  expect_log "FOO=initial_foo"

  # If an unrelated value changes, we expect the action not to be executed again
  export UNRELATED=some_other_value
  bazel build --action_env=FOO -s --experimental_ui pkg:showenv 2> $TEST_log \
      || fail "${PRODUCT_NAME} build showenv failed"
  expect_not_log '^SUBCOMMAND.*pkg:showenv'

  # However, if a used variable changes, we expect the change to be propagated
  export FOO=changed_foo
  bazel build --action_env=FOO -s --experimental_ui pkg:showenv 2> $TEST_log \
      || fail "${PRODUCT_NAME} build showenv failed"
  expect_log '^SUBCOMMAND.*pkg:showenv'
  cat `bazel info ${PRODUCT_NAME}-genfiles`/pkg/env.txt > $TEST_log
  expect_log "FOO=changed_foo"

  # But repeating the build with no further changes, no action should happen
  bazel build --action_env=FOO -s --experimental_ui pkg:showenv 2> $TEST_log \
      || fail "${PRODUCT_NAME} build showenv failed"
  expect_not_log '^SUBCOMMAND.*pkg:showenv'
}

function test_latest_wins_arg() {
  export FOO=bar
  export BAR=baz
  bazel build --action_env=BAR --action_env=FOO --action_env=FOO=foo \
      pkg:showenv || fail "${PRODUCT_NAME} build showenv failed"

  cat `bazel info ${PRODUCT_NAME}-genfiles`/pkg/env.txt > $TEST_log
  expect_log "FOO=foo"
  expect_log "BAR=baz"
  expect_not_log "FOO=bar"
}

function test_latest_wins_env() {
  export FOO=bar
  export BAR=baz
  bazel build --action_env=BAR --action_env=FOO=foo --action_env=FOO \
      pkg:showenv || fail "${PRODUCT_NAME} build showenv failed"

  cat `bazel info ${PRODUCT_NAME}-genfiles`/pkg/env.txt > $TEST_log
  expect_log "FOO=bar"
  expect_log "BAR=baz"
  expect_not_log "FOO=foo"
}

function test_env_freezing() {
  add_to_bazelrc "build --action_env=FREEZE_TEST_FOO"
  add_to_bazelrc "build --action_env=FREEZE_TEST_BAR=is_fixed"
  add_to_bazelrc "build --action_env=FREEZE_TEST_BAZ=will_be_overridden"
  add_to_bazelrc "build --action_env=FREEZE_TEST_BUILD"

  export FREEZE_TEST_FOO=client_foo
  export FREEZE_TEST_BAR=client_bar
  export FREEZE_TEST_BAZ=client_baz
  export FREEZE_TEST_BUILD=client_build

  bazel info --action_env=FREEZE_TEST_BAZ client-env > $TEST_log

  expect_log "build --action_env=FREEZE_TEST_FOO=client_foo"
  expect_not_log "FREEZE_TEST_BAR"
  expect_log "build --action_env=FREEZE_TEST_BAZ=client_baz"
  expect_log "build --action_env=FREEZE_TEST_BUILD=client_build"

  rm -f .${PRODUCT_NAME}rc
}

function test_use_default_shell_env {
    bazel build --action_env=FOO=bar //pkg/...
    echo
    cat bazel-bin/pkg/with_default_env.env
    echo
    grep -q FOO=bar bazel-bin/pkg/with_default_env.env \
        || fail "static action environment not honored"
    (grep -q FOO=bar bazel-bin/pkg/no_default_env.env \
         && fail "static action_env used, even though requested not to") || true

    export BAR=baz
    bazel build --action_env=BAR //pkg/...
    grep -q BAR=baz bazel-bin/pkg/with_default_env.env \
        || fail "dynamic action environment not honored"
    (grep -q BAR bazel-bin/pkg/no_default_env.env \
         && fail "dynamic action_env used, even though requested not to") || true
}

function test_action_env_changes_honored {
    # Verify that changes to the explicitly specified action_env in honored in
    # tests. Regression test for #3265.

    # start with a fresh bazel, to have a reproducible starting point
    bazel clean --expunge
    bazel test --test_output=all --action_env=FOO=foo //pkg:test_env_foo \
        || fail "expected to pass with correct value for FOO"
    # While the test is cached, changing the environment should rerun it and
    # detect the failure in the new environemnt.
    (bazel test --test_output=all --action_env=FOO=bar //pkg:test_env_foo \
         && fail "expected to fail with incorrect value for FOO") || true
    # Redo the same FOO being taken from the environment
    env FOO=foo bazel test --test_output=all --action_env=FOO //pkg:test_env_foo \
        || fail "expected to pass with correct value for FOO from the environment"
    (env FOO=bar bazel test --test_output=all --action_env=FOO=bar //pkg:test_env_foo \
         && fail "expected to fail with incorrect value for FOO from the environment") || true

}

run_suite "Tests for bazel's handling of environment variables in actions"