blob: 67df538507c1f8a747ddd88d250d4be2259082d2 [file] [log] [blame]
// Copyright 2017 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.
package com.google.devtools.build.lib.exec;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.test.TestRunnerAction;
import com.google.devtools.build.lib.util.UserUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
/**
* A policy for running tests. It currently only encompasses the environment computation for the
* test.
*/
public class TestPolicy {
/**
* The user name of the user running Bazel; this may differ from ${USER} for tests that are run
* remotely.
*/
public static final String SYSTEM_USER_NAME = "${SYSTEM_USER_NAME}";
/** An absolute path to a writable directory that is reserved for the current test. */
public static final String TEST_TMP_DIR = "${TEST_TMP_DIR}";
/** The path of the runfiles directory. */
public static final String RUNFILES_DIR = "${RUNFILES_DIR}";
public static final String INHERITED = "${inherited}";
public static final TestPolicy EMPTY_POLICY = new TestPolicy(ImmutableMap.of());
private final ImmutableMap<String, String> envVariables;
/**
* Creates a new instance. The map's keys are the names of the environment variables, while the
* values can be either fixed values, or one of the constants in this class, specifically {@link
* #SYSTEM_USER_NAME}, {@link #TEST_TMP_DIR}, {@link #RUNFILES_DIR}, or {@link #INHERITED}.
*/
public TestPolicy(ImmutableMap<String, String> envVariables) {
this.envVariables = envVariables;
}
/**
* Returns a mutable map of the environment variables for a specific test. This is intended to be
* the final, complete environment - callers should avoid relying on the mutability of the return
* value, and instead change the policy itself.
*/
public Map<String, String> computeTestEnvironment(
TestRunnerAction testAction,
Map<String, String> clientEnv,
Duration timeout,
PathFragment relativeRunfilesDir,
PathFragment tmpDir) {
Map<String, String> env = new HashMap<>();
// Add all env variables, allow some string replacements and inheritance.
String userProp = UserUtils.getUserName();
String tmpDirPath = tmpDir.getPathString();
String runfilesDirPath = relativeRunfilesDir.getPathString();
for (Map.Entry<String, String> entry : envVariables.entrySet()) {
String val = entry.getValue();
if (val.contains("${")) {
if (val.equals(INHERITED)) {
if (!clientEnv.containsKey(entry.getKey())) {
continue;
}
val = clientEnv.get(entry.getKey());
} else {
val = val.replace(SYSTEM_USER_NAME, userProp);
val = val.replace(TEST_TMP_DIR, tmpDirPath);
val = val.replace(RUNFILES_DIR, runfilesDirPath);
}
}
env.put(entry.getKey(), val);
}
// Rule-specified test env.
env.putAll(testAction.getExtraTestEnv());
// Overwrite with the environment common to all actions, see --action_env.
testAction.getConfiguration().getActionEnvironment().resolve(env, clientEnv);
// Overwrite with the environment common to all tests, see --test_env.
testAction.getConfiguration().getTestActionEnvironment().resolve(env, clientEnv);
// Setup any test-specific env variables; note that this does not overwrite existing values for
// TEST_RANDOM_SEED or TEST_SIZE if they're already set.
testAction.setupEnvVariables(env, timeout);
return env;
}
}