|  | // 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. | 
|  | testAction.getExtraTestEnv().resolve(env, clientEnv); | 
|  |  | 
|  | // 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; | 
|  | } | 
|  | } |