Example #1
0
  /**
   * Returns mutable map of default testing shell environment. By itself it is incomplete and is
   * modified further by the specific test strategy implementations (mostly due to the fact that
   * environments used locally and remotely are different).
   */
  protected Map<String, String> getDefaultTestEnvironment(TestRunnerAction action) {
    Map<String, String> env = new HashMap<>();

    env.putAll(action.getConfiguration().getLocalShellEnvironment());
    env.remove("LANG");
    env.put("TZ", "UTC");
    env.put("TEST_SIZE", action.getTestProperties().getSize().toString());
    env.put("TEST_TIMEOUT", Integer.toString(getTimeout(action)));

    if (action.isSharded()) {
      env.put("TEST_SHARD_INDEX", Integer.toString(action.getShardNum()));
      env.put(
          "TEST_TOTAL_SHARDS", Integer.toString(action.getExecutionSettings().getTotalShards()));
    }

    // When we run test multiple times, set different TEST_RANDOM_SEED values for each run.
    if (action.getConfiguration().getRunsPerTestForLabel(action.getOwner().getLabel()) > 1) {
      env.put("TEST_RANDOM_SEED", Integer.toString(action.getRunNumber() + 1));
    }

    String testFilter = action.getExecutionSettings().getTestFilter();
    if (testFilter != null) {
      env.put(TEST_BRIDGE_TEST_FILTER_ENV, testFilter);
    }

    return env;
  }
Example #2
0
  /**
   * Generates a command line to run for the test action, taking into account coverage and {@code
   * --run_under} settings.
   *
   * @param testScript the setup script that invokes the test
   * @param coverageScript a script interjected between setup script and rest of command line to
   *     collect coverage data. If this is an empty string, it is ignored.
   * @param testAction The test action.
   * @return the command line as string list.
   */
  protected List<String> getArgs(
      String testScript, String coverageScript, TestRunnerAction testAction) {
    List<String> args = Lists.newArrayList();
    if (OS.getCurrent() == OS.WINDOWS) {
      args.add(testAction.getShExecutable().getPathString());
      args.add("-c");
      args.add("$0 $*");
    }
    args.add(testScript);
    TestTargetExecutionSettings execSettings = testAction.getExecutionSettings();

    List<String> execArgs = new ArrayList<>();
    if (!coverageScript.isEmpty() && isCoverageMode(testAction)) {
      execArgs.add(coverageScript);
    }

    // Execute the test using the alias in the runfiles tree, as mandated by
    // the Test Encyclopedia.
    execArgs.add(execSettings.getExecutable().getRootRelativePath().getPathString());
    execArgs.addAll(execSettings.getArgs());

    // Insert the command prefix specified by the "--run_under=<command-prefix>" option,
    // if any.
    if (execSettings.getRunUnder() == null) {
      args.addAll(execArgs);
    } else if (execSettings.getRunUnderExecutable() != null) {
      args.add(execSettings.getRunUnderExecutable().getRootRelativePath().getPathString());
      args.addAll(execSettings.getRunUnder().getOptions());
      args.addAll(execArgs);
    } else {
      args.add(testAction.getConfiguration().getShellExecutable().getPathString());
      args.add("-c");

      String runUnderCommand = ShellEscaper.escapeString(execSettings.getRunUnder().getCommand());

      Path fullySpecified =
          SearchPath.which(
              SearchPath.parse(
                  testAction.getTestLog().getPath().getFileSystem(), clientEnv.get("PATH")),
              runUnderCommand);

      if (fullySpecified != null) {
        runUnderCommand = fullySpecified.toString();
      }

      args.add(
          runUnderCommand
              + ' '
              + ShellEscaper.escapeJoinAll(
                  Iterables.concat(execSettings.getRunUnder().getOptions(), execArgs)));
    }
    return args;
  }
Example #3
0
 /**
  * Returns the number of attempts specific test action can be retried.
  *
  * <p>For rules with "flaky = 1" attribute, this method will return 3 unless --flaky_test_attempts
  * option is given and specifies another value.
  */
 @VisibleForTesting /* protected */
 public int getTestAttempts(TestRunnerAction action) {
   if (executionOptions.testAttempts == -1) {
     return action.getTestProperties().isFlaky() ? 3 : 1;
   } else {
     return executionOptions.testAttempts;
   }
 }
Example #4
0
  /**
   * Ensure the runfiles tree exists and is consistent with the TestAction's manifest
   * ($0.runfiles_manifest), bringing it into consistency if not. The contents of the output file
   * $0.runfiles/MANIFEST, if it exists, are used a proxy for the set of existing symlinks, to avoid
   * the need for recursion.
   */
  private static void updateLocalRunfilesDirectory(
      TestRunnerAction testAction,
      Path runfilesDir,
      ActionExecutionContext actionExecutionContext,
      BinTools binTools,
      ImmutableMap<String, String> shellEnvironment,
      boolean enableRunfiles)
      throws ExecException, InterruptedException {
    Executor executor = actionExecutionContext.getExecutor();

    TestTargetExecutionSettings execSettings = testAction.getExecutionSettings();
    try {
      // Avoid rebuilding the runfiles directory if the manifest in it matches the input manifest,
      // implying the symlinks exist and are already up to date.
      if (Arrays.equals(
          runfilesDir.getRelative("MANIFEST").getMD5Digest(),
          execSettings.getInputManifest().getPath().getMD5Digest())) {
        return;
      }
    } catch (IOException e1) {
      // Ignore it - we will just try to create runfiles directory.
    }

    executor
        .getEventHandler()
        .handle(
            Event.progress(
                "Building runfiles directory for '"
                    + execSettings.getExecutable().prettyPrint()
                    + "'."));

    new SymlinkTreeHelper(execSettings.getInputManifest().getPath(), runfilesDir, false)
        .createSymlinks(
            testAction, actionExecutionContext, binTools, shellEnvironment, enableRunfiles);

    executor.getEventHandler().handle(Event.progress(testAction.getProgressMessage()));
  }
Example #5
0
  /**
   * Returns the runfiles directory associated with the test executable, creating/updating it if
   * necessary and --build_runfile_links is specified.
   */
  protected static Path getLocalRunfilesDirectory(
      TestRunnerAction testAction,
      ActionExecutionContext actionExecutionContext,
      BinTools binTools,
      ImmutableMap<String, String> shellEnvironment,
      boolean enableRunfiles)
      throws ExecException, InterruptedException {
    TestTargetExecutionSettings execSettings = testAction.getExecutionSettings();

    // If the symlink farm is already created then return the existing directory. If not we
    // need to explicitly build it. This can happen when --nobuild_runfile_links is supplied
    // as a flag to the build.
    if (execSettings.getRunfilesSymlinksCreated()) {
      return execSettings.getRunfilesDir();
    }

    // TODO(bazel-team): Should we be using TestTargetExecutionSettings#getRunfilesDir() here over
    // generating the directory ourselves?
    Path program = execSettings.getExecutable().getPath();
    Path runfilesDir = program.getParentDirectory().getChild(program.getBaseName() + ".runfiles");

    // Synchronize runfiles tree generation on the runfiles manifest artifact.
    // This is necessary, because we might end up with multiple test runner actions
    // trying to generate same runfiles tree in case of --runs_per_test > 1 or
    // local test sharding.
    long startTime = Profiler.nanoTimeMaybe();
    synchronized (execSettings.getInputManifest()) {
      Profiler.instance().logSimpleTask(startTime, ProfilerTask.WAIT, testAction);
      updateLocalRunfilesDirectory(
          testAction,
          runfilesDir,
          actionExecutionContext,
          binTools,
          shellEnvironment,
          enableRunfiles);
    }

    return runfilesDir;
  }
Example #6
0
 /** @return The test label. */
 public String getLabel() {
   return Label.print(testAction.getOwner().getLabel());
 }
Example #7
0
 /**
  * Gets the test name in a user-friendly format. Will generally include the target name and shard
  * number, if applicable.
  *
  * @return The test name.
  */
 public String getTestName() {
   return testAction.getTestName();
 }
Example #8
0
 /** @return The test status artifact. */
 public Artifact getTestStatusArtifact() {
   // these artifacts are used to keep track of the number of pending and completed tests.
   return testAction.getCacheStatusArtifact();
 }
Example #9
0
 /** @return Coverage data artifact, if available and null otherwise. */
 public PathFragment getCoverageData() {
   if (data.getHasCoverage()) {
     return testAction.getCoverageData().getExecPath();
   }
   return null;
 }
Example #10
0
 /**
  * @return The test log path. Note, that actual log file may no longer correspond to this artifact
  *     - use getActualLogPath() method if you need log location.
  */
 public Path getTestLogPath() {
   return testAction.getTestLog().getPath();
 }
Example #11
0
 /**
  * @return Total number of test shards. 0 means no sharding, whereas 1 means degenerate sharding.
  */
 public int getTotalShards() {
   return testAction.getExecutionSettings().getTotalShards();
 }
Example #12
0
 /** @return The test shard number. */
 public int getShardNum() {
   return testAction.getShardNum();
 }
Example #13
0
 /** Returns true if coverage data should be gathered. */
 protected static boolean isCoverageMode(TestRunnerAction action) {
   return action.getCoverageData() != null;
 }
Example #14
0
 /**
  * Returns timeout value in seconds that should be used for the given test action. We always use
  * the "categorical timeouts" which are based on the --test_timeout flag. A rule picks its timeout
  * but ends up with the same effective value as all other rules in that bucket.
  */
 protected final int getTimeout(TestRunnerAction testAction) {
   return executionOptions.testTimeout.get(testAction.getTestProperties().getTimeout());
 }