示例#1
1
  @Test
  public void testWorkspaceDies() throws Exception {
    assertTrue(serverThread.isAlive());
    runTestRequest("blaze", 42, COMMAND_STDOUT, COMMAND_STDERR);
    Thread.sleep(HEALTH_CHECK_MILLIS * 2);
    assertTrue(serverThread.isAlive());

    assertTrue(workspaceDir.delete());
    Thread.sleep(HEALTH_CHECK_MILLIS * 2);
    assertFalse(serverThread.isAlive());
  }
  /**
   * Checks whether the {@code traversal}'s path refers to a package directory.
   *
   * @return the result of the lookup; it contains potentially new {@link TraversalRequest} and
   *     {@link FileInfo} so the caller should use these instead of the old ones (this happens when
   *     a package is found, but under a different root than expected)
   */
  private static PkgLookupResult checkIfPackage(
      Environment env, TraversalRequest traversal, FileInfo rootInfo) throws MissingDepException {
    Preconditions.checkArgument(
        rootInfo.type.exists() && !rootInfo.type.isFile(), "{%s} {%s}", traversal, rootInfo);
    PackageLookupValue pkgLookup =
        (PackageLookupValue)
            getDependentSkyValue(env, PackageLookupValue.key(traversal.path.getRelativePath()));

    if (pkgLookup.packageExists()) {
      if (traversal.isGenerated) {
        // The traversal's root was a generated directory, but its root-relative path conflicts with
        // an existing package.
        return PkgLookupResult.conflict(traversal, rootInfo);
      } else {
        // The traversal's root was a source directory and it defines a package.
        Path pkgRoot = pkgLookup.getRoot();
        if (!pkgRoot.equals(traversal.path.getRoot())) {
          // However the root of this package is different from what we expected. stat() the real
          // BUILD file of that package.
          traversal = traversal.forChangedRootPath(pkgRoot);
          rootInfo = lookUpFileInfo(env, traversal);
          Verify.verify(rootInfo.type.exists(), "{%s} {%s}", traversal, rootInfo);
        }
        return PkgLookupResult.pkg(traversal, rootInfo);
      }
    } else {
      // The traversal's root was a directory (source or generated one), no package exists under the
      // same root-relative path.
      return PkgLookupResult.directory(traversal, rootInfo);
    }
  }
示例#3
0
 private void assertPathsAre(List<Path> paths, String... strings) {
   List<String> pathStrings = new ArrayList<>();
   for (Path path : paths) {
     pathStrings.add(path.getPathString());
   }
   assertThat(pathStrings).containsExactlyElementsIn(Arrays.asList(strings));
 }
  @Override
  public SkyValue fetch(Rule rule, Path outputDirectory, Environment env)
      throws SkyFunctionException {
    AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
    PathFragment pathFragment = new PathFragment(mapper.get("path", Type.STRING));
    try {
      FileSystem fs = outputDirectory.getFileSystem();
      if (fs.supportsSymbolicLinksNatively()) {
        outputDirectory.createSymbolicLink(pathFragment);
      } else {
        FileSystemUtils.createDirectoryAndParents(outputDirectory);
        FileSystemUtils.copyTreesBelow(
            fs.getPath(getTargetPath(rule, getWorkspace())), outputDirectory);
      }
    } catch (IOException e) {
      throw new RepositoryFunctionException(
          new IOException(
              "Could not create symlink to repository " + pathFragment + ": " + e.getMessage()),
          Transience.TRANSIENT);
    }
    FileValue repositoryValue = getRepositoryDirectory(outputDirectory, env);
    if (repositoryValue == null) {
      // TODO(bazel-team): If this returns null, we unnecessarily recreate the symlink above on the
      // second execution.
      return null;
    }

    if (!repositoryValue.isDirectory()) {
      throw new RepositoryFunctionException(
          new IOException(rule + " must specify an existing directory"), Transience.TRANSIENT);
    }

    return RepositoryValue.create(outputDirectory);
  }
  public void testSimpleJavaLibrary() throws Exception {
    Path buildFilePath =
        scratch.file(
            "com/google/example/BUILD",
            "java_library(",
            "    name = 'simple',",
            "    srcs = ['simple/Simple.java']",
            ")");
    Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple");
    assertThat(ruleIdeInfos.size()).isEqualTo(1);
    RuleIdeInfo ruleIdeInfo =
        getRuleInfoAndVerifyLabel("//com/google/example:simple", ruleIdeInfos);
    assertThat(ruleIdeInfo.getBuildFile()).isEqualTo(buildFilePath.toString());
    assertThat(ruleIdeInfo.getKind()).isEqualTo(Kind.JAVA_LIBRARY);
    assertThat(ruleIdeInfo.getDependenciesCount()).isEqualTo(0);
    assertThat(relativePathsForSourcesOf(ruleIdeInfo))
        .containsExactly("com/google/example/simple/Simple.java");
    assertThat(
            transform(ruleIdeInfo.getJavaRuleIdeInfo().getJarsList(), LIBRARY_ARTIFACT_TO_STRING))
        .containsExactly(
            jarString(
                "com/google/example", "libsimple.jar", "libsimple-ijar.jar", "libsimple-src.jar"));

    assertThat(getIdeResolveFiles())
        .containsExactly(
            "com/google/example/libsimple.jar",
            "com/google/example/libsimple-ijar.jar",
            "com/google/example/libsimple-src.jar");
  }
  private static FileValue createSymbolicLink(Path from, Path to, Environment env)
      throws RepositoryFunctionException {
    try {
      if (!from.exists()) {
        from.createSymbolicLink(to);
      }
    } catch (IOException e) {
      throw new RepositoryFunctionException(
          new IOException(
              String.format(
                  "Error creating symbolic link from %s to %s: %s", from, to, e.getMessage())),
          Transience.TRANSIENT);
    }

    SkyKey outputDirectoryKey =
        FileValue.key(RootedPath.toRootedPath(from, PathFragment.EMPTY_FRAGMENT));
    try {
      return (FileValue)
          env.getValueOrThrow(
              outputDirectoryKey,
              IOException.class,
              FileSymlinkException.class,
              InconsistentFilesystemException.class);
    } catch (IOException | FileSymlinkException | InconsistentFilesystemException e) {
      throw new RepositoryFunctionException(
          new IOException(String.format("Could not access %s: %s", from, e.getMessage())),
          Transience.PERSISTENT);
    }
  }
示例#7
0
 public void testSymlink() throws Exception {
   Executor executor = new TestExecutorBuilder(directories, null).build();
   action.execute(new ActionExecutionContext(executor, null, null, null, null));
   assertTrue(output.isSymbolicLink());
   assertEquals(input, output.resolveSymbolicLinks());
   assertEquals(inputArtifact, action.getPrimaryInput());
   assertEquals(outputArtifact, action.getPrimaryOutput());
 }
示例#8
0
  public static void main(String[] args) throws Exception {
    OptionsParser parser =
        OptionsParser.newOptionsParser(RemoteOptions.class, RemoteWorkerOptions.class);
    parser.parseAndExitUponError(args);
    RemoteOptions remoteOptions = parser.getOptions(RemoteOptions.class);
    RemoteWorkerOptions remoteWorkerOptions = parser.getOptions(RemoteWorkerOptions.class);

    if (remoteWorkerOptions.workPath == null) {
      printUsage(parser);
      return;
    }

    System.out.println("*** Starting Hazelcast server.");
    ConcurrentMap<String, byte[]> cache = new HazelcastCacheFactory().create(remoteOptions);

    System.out.println(
        "*** Starting grpc server on all locally bound IPs on port "
            + remoteWorkerOptions.listenPort
            + ".");
    Path workPath = getFileSystem().getPath(remoteWorkerOptions.workPath);
    FileSystemUtils.createDirectoryAndParents(workPath);
    RemoteWorker worker = new RemoteWorker(workPath, remoteOptions, remoteWorkerOptions, cache);
    final Server server =
        ServerBuilder.forPort(remoteWorkerOptions.listenPort).addService(worker).build();
    server.start();

    final Path pidFile;
    if (remoteWorkerOptions.pidFile != null) {
      pidFile = getFileSystem().getPath(remoteWorkerOptions.pidFile);
      PrintWriter writer = new PrintWriter(pidFile.getOutputStream());
      writer.append(Integer.toString(ProcessUtils.getpid()));
      writer.append("\n");
      writer.close();
    } else {
      pidFile = null;
    }

    Runtime.getRuntime()
        .addShutdownHook(
            new Thread() {
              @Override
              public void run() {
                System.err.println("*** Shutting down grpc server.");
                server.shutdown();
                if (pidFile != null) {
                  try {
                    pidFile.delete();
                  } catch (IOException e) {
                    System.err.println("Cannot remove pid file: " + pidFile.toString());
                  }
                }
                System.err.println("*** Server shut down.");
              }
            });
    server.awaitTermination();
  }
示例#9
0
 static FileStateValue create(RootedPath rootedPath, @Nullable TimestampGranularityMonitor tsgm)
     throws InconsistentFilesystemException, IOException {
   Path path = rootedPath.asPath();
   // Stat, but don't throw an exception for the common case of a nonexistent file. This still
   // throws an IOException in case any other IO error is encountered.
   FileStatus stat = path.statIfFound(Symlinks.NOFOLLOW);
   if (stat == null) {
     return NONEXISTENT_FILE_STATE_NODE;
   }
   return createWithStatNoFollow(rootedPath, FileStatusWithDigestAdapter.adapt(stat), tsgm);
 }
示例#10
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;
  }
示例#11
0
  @Test
  public void throwsFileAccessException() throws Exception {
    FileSystemUtils.createEmptyFile(testFile);
    NativePosixFiles.chmod(testFile.getPathString(), 0200);

    try {
      NativePosixFiles.md5sum(testFile.getPathString());
      fail("Expected FileAccessException, but wasn't thrown.");
    } catch (FileAccessException e) {
      assertThat(e).hasMessage(testFile + " (Permission denied)");
    }
  }
示例#12
0
 @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   response.setContentType("application/json");
   RemoteWorkResponse.Builder workResponse = RemoteWorkResponse.newBuilder();
   // TODO(alpha): Choose a better temp directory name.
   Path tempRoot = workPath.getRelative("build-" + UUID.randomUUID().toString());
   FileSystemUtils.createDirectoryAndParents(tempRoot);
   boolean deleteTree = true;
   try {
     String workJson = CharStreams.toString(request.getReader());
     RemoteWorkRequest.Builder workRequest = RemoteWorkRequest.newBuilder();
     JsonFormat.parser().merge(workJson, workRequest);
     RemoteWorkRequest work = workRequest.build();
     final MemcacheActionCache actionCache =
         new MemcacheActionCache(tempRoot, remoteOptions, cache);
     final MemcacheWorkExecutor workExecutor =
         new MemcacheWorkExecutor(actionCache, executorService, tempRoot);
     if (options.debug) {
       System.out.println(
           "[INFO] Work received has "
               + work.getInputFilesCount()
               + " inputs files and "
               + work.getOutputFilesCount()
               + " output files.");
     }
     RemoteWorkExecutor.Response executorResponse = workExecutor.submit(work).get();
     if (options.debug) {
       if (!executorResponse.success()) {
         deleteTree = false;
         System.out.println("[WARNING] Work failed.");
         System.out.println(workJson);
       } else {
         System.out.println("[INFO] Work completed.");
       }
     }
     workResponse
         .setSuccess(executorResponse.success())
         .setOut(executorResponse.getOut())
         .setErr(executorResponse.getErr());
   } catch (Exception e) {
     workResponse.setSuccess(false).setOut("").setErr("").setException(e.toString());
   } finally {
     if (deleteTree) {
       FileSystemUtils.deleteTree(tempRoot);
     } else {
       System.out.println("[WARNING] Preserving work directory " + tempRoot.toString() + ".");
     }
     response.setStatus(HttpServletResponse.SC_OK);
     response.getWriter().print(JsonFormat.printer().print(workResponse.build()));
   }
 }
示例#13
0
 @Override
 public void setUp() throws Exception {
   super.setUp();
   input = scratch.file("input.txt", "Hello, world.");
   inputArtifact = getSourceArtifact("input.txt");
   Path linkedInput = directories.getExecRoot().getRelative("input.txt");
   FileSystemUtils.createDirectoryAndParents(linkedInput.getParentDirectory());
   linkedInput.createSymbolicLink(input);
   outputArtifact = getBinArtifactWithNoOwner("destination.txt");
   output = outputArtifact.getPath();
   FileSystemUtils.createDirectoryAndParents(output.getParentDirectory());
   action = new SymlinkAction(NULL_ACTION_OWNER, inputArtifact, outputArtifact, "Symlinking test");
 }
示例#14
0
  /**
   * Symlinks a BUILD file from the local filesystem into the external repository's root.
   *
   * @param rule the rule that declares the build_file path.
   * @param workspaceDirectory the workspace root for the build.
   * @param directoryValue the FileValue corresponding to the external repository's root directory.
   * @param env the Skyframe environment.
   * @return the file value of the symlink created.
   * @throws
   *     com.google.devtools.build.lib.bazel.repository.RepositoryFunction.RepositoryFunctionException
   *     if the BUILD file specified does not exist or cannot be linked.
   */
  protected RepositoryValue symlinkBuildFile(
      Rule rule, Path workspaceDirectory, FileValue directoryValue, Environment env)
      throws RepositoryFunctionException {
    AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
    PathFragment buildFile = new PathFragment(mapper.get("build_file", Type.STRING));
    Path buildFileTarget = workspaceDirectory.getRelative(buildFile);
    if (!buildFileTarget.exists()) {
      throw new RepositoryFunctionException(
          new EvalException(
              rule.getLocation(),
              String.format(
                  "In %s the 'build_file' attribute does not specify an existing file "
                      + "(%s does not exist)",
                  rule, buildFileTarget)),
          Transience.PERSISTENT);
    }

    RootedPath rootedBuild;
    if (buildFile.isAbsolute()) {
      rootedBuild =
          RootedPath.toRootedPath(
              buildFileTarget.getParentDirectory(),
              new PathFragment(buildFileTarget.getBaseName()));
    } else {
      rootedBuild = RootedPath.toRootedPath(workspaceDirectory, buildFile);
    }
    SkyKey buildFileKey = FileValue.key(rootedBuild);
    FileValue buildFileValue;
    try {
      buildFileValue =
          (FileValue)
              env.getValueOrThrow(
                  buildFileKey,
                  IOException.class,
                  FileSymlinkException.class,
                  InconsistentFilesystemException.class);
      if (buildFileValue == null) {
        return null;
      }
    } catch (IOException | FileSymlinkException | InconsistentFilesystemException e) {
      throw new RepositoryFunctionException(
          new IOException("Cannot lookup " + buildFile + ": " + e.getMessage()),
          Transience.TRANSIENT);
    }

    Path buildFilePath = directoryValue.realRootedPath().asPath().getRelative("BUILD");
    if (createSymbolicLink(buildFilePath, buildFileTarget, env) == null) {
      return null;
    }
    return RepositoryValue.createNew(directoryValue, buildFileValue);
  }
示例#15
0
  /**
   * Given a targetDirectory /some/path/to/y that contains files z, w, and v, create the following
   * directory structure:
   *
   * <pre>
   * .external-repository/
   *   x/
   *     WORKSPACE
   *     BUILD -> &lt;build_root&gt;/x.BUILD
   *     z -> /some/path/to/y/z
   *     w -> /some/path/to/y/w
   *     v -> /some/path/to/y/v
   * </pre>
   */
  public static boolean symlinkLocalRepositoryContents(
      Path repositoryDirectory, Path targetDirectory, Environment env)
      throws RepositoryFunctionException {
    try {
      for (Path target : targetDirectory.getDirectoryEntries()) {
        Path symlinkPath = repositoryDirectory.getRelative(target.getBaseName());
        if (createSymbolicLink(symlinkPath, target, env) == null) {
          return false;
        }
      }
    } catch (IOException e) {
      throw new RepositoryFunctionException(e, Transience.TRANSIENT);
    }

    return true;
  }
示例#16
0
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws WorkspaceFileFunctionException, InterruptedException {
    RootedPath workspaceRoot = (RootedPath) skyKey.argument();
    FileValue workspaceFileValue = (FileValue) env.getValue(FileValue.key(workspaceRoot));
    if (workspaceFileValue == null) {
      return null;
    }

    Path repoWorkspace = workspaceRoot.getRoot().getRelative(workspaceRoot.getRelativePath());
    Builder builder =
        new Builder(repoWorkspace, packageFactory.getRuleClassProvider().getRunfilesPrefix());
    WorkspaceFactory parser =
        new WorkspaceFactory(
            builder, packageFactory.getRuleClassProvider(), installDir.getPathString());
    parser.parse(
        ParserInputSource.create(
            ruleClassProvider.getDefaultWorkspaceFile(), new PathFragment("DEFAULT.WORKSPACE")));
    if (!workspaceFileValue.exists()) {
      return new PackageValue(builder.build());
    }

    try {
      parser.parse(ParserInputSource.create(repoWorkspace));
    } catch (IOException e) {
      throw new WorkspaceFileFunctionException(e, Transience.TRANSIENT);
    }

    return new PackageValue(builder.build());
  }
示例#17
0
    @Override
    public boolean equals(Object other) {
      if (this == other) {
        return true;
      }

      if (!(other instanceof DecompressorDescriptor)) {
        return false;
      }

      DecompressorDescriptor descriptor = (DecompressorDescriptor) other;
      return targetKind.equals(descriptor.targetKind)
          && targetName.equals(descriptor.targetName)
          && archivePath.equals(descriptor.archivePath)
          && repositoryPath.equals(descriptor.repositoryPath)
          && prefix.equals(descriptor.prefix);
    }
示例#18
0
 /**
  * Helper method to remove an Artifact. If the Artifact refers to a directory recursively removes
  * the contents of the directory.
  */
 protected void deleteOutput(Artifact output) throws IOException {
   Path path = output.getPath();
   try {
     // Optimize for the common case: output artifacts are files.
     path.delete();
   } catch (IOException e) {
     // Only try to recursively delete a directory if the output root is known. This is just a
     // sanity check so that we do not start deleting random files on disk.
     // TODO(bazel-team): Strengthen this test by making sure that the output is part of the
     // output tree.
     if (path.isDirectory(Symlinks.NOFOLLOW) && output.getRoot() != null) {
       FileSystemUtils.deleteTree(path);
     } else {
       throw e;
     }
   }
 }
示例#19
0
文件: Worker.java 项目: aehlig/bazel
  void createProcess() throws IOException {
    String[] command = workerKey.getArgs().toArray(new String[0]);

    // Follows the logic of {@link com.google.devtools.build.lib.shell.Command}.
    File executable = new File(command[0]);
    if (!executable.isAbsolute() && executable.getParent() != null) {
      command[0] = new File(workDir.getPathFile(), command[0]).getAbsolutePath();
    }
    ProcessBuilder processBuilder =
        new ProcessBuilder(command)
            .directory(workDir.getPathFile())
            .redirectError(Redirect.appendTo(logFile.getPathFile()));
    processBuilder.environment().clear();
    processBuilder.environment().putAll(workerKey.getEnv());

    this.process = processBuilder.start();
  }
示例#20
0
 @Test
 public void throwsFileNotFoundException() throws Exception {
   try {
     NativePosixFiles.md5sum(testFile.getPathString());
     fail("Expected FileNotFoundException, but wasn't thrown.");
   } catch (FileNotFoundException e) {
     assertThat(e).hasMessage(testFile + " (No such file or directory)");
   }
 }
示例#21
0
 /** If the action might create directories as outputs this method must be called. */
 protected void checkOutputsForDirectories(EventHandler eventHandler) {
   for (Artifact output : getOutputs()) {
     Path path = output.getPath();
     String ownerString = Label.print(getOwner().getLabel());
     if (path.isDirectory()) {
       eventHandler.handle(
           new Event(
               EventKind.WARNING,
               getOwner().getLocation(),
               "output '"
                   + output.prettyPrint()
                   + "' of "
                   + ownerString
                   + " is a directory; dependency checking of directories is unsound",
               ownerString));
     }
   }
 }
示例#22
0
  @Override
  public void executeSynchronously(
      RemoteWorkRequest request, StreamObserver<RemoteWorkResponse> responseObserver) {
    Path tempRoot = workPath.getRelative("build-" + UUID.randomUUID().toString());
    try {
      FileSystemUtils.createDirectoryAndParents(tempRoot);
      final ConcurrentMapActionCache actionCache = new ConcurrentMapActionCache(tempRoot, cache);
      final MemcacheWorkExecutor workExecutor =
          MemcacheWorkExecutor.createLocalWorkExecutor(actionCache, tempRoot);
      if (LOG_FINER) {
        LOG.fine(
            "Work received has "
                + request.getInputFilesCount()
                + " input files and "
                + request.getOutputFilesCount()
                + " output files.");
      }
      RemoteWorkResponse response = workExecutor.executeLocally(request);
      responseObserver.onNext(response);
      if (options.debug) {
        if (!response.getSuccess()) {
          LOG.warning("Work failed. Request: " + request.toString() + ".");

        } else if (LOG_FINER) {
          LOG.fine("Work completed.");
        }
      }
      if (!options.debug || response.getSuccess()) {
        FileSystemUtils.deleteTree(tempRoot);
      } else {
        LOG.warning("Preserving work directory " + tempRoot.toString() + ".");
      }
    } catch (IOException | InterruptedException e) {
      RemoteWorkResponse.Builder response = RemoteWorkResponse.newBuilder();
      response.setSuccess(false).setOut("").setErr("").setException(e.toString());
      responseObserver.onNext(response.build());
      if (e instanceof InterruptedException) {
        Thread.currentThread().interrupt();
      }
    } finally {
      responseObserver.onCompleted();
    }
  }
示例#23
0
 public void testExecutableSymlink() throws Exception {
   Executor executor = new TestExecutorBuilder(directories, null).build();
   outputArtifact = getBinArtifactWithNoOwner("destination2.txt");
   output = outputArtifact.getPath();
   action = new ExecutableSymlinkAction(NULL_ACTION_OWNER, inputArtifact, outputArtifact);
   assertFalse(input.isExecutable());
   ActionExecutionContext actionExecutionContext =
       new ActionExecutionContext(executor, null, null, null, null);
   try {
     action.execute(actionExecutionContext);
     fail("Expected ActionExecutionException");
   } catch (ActionExecutionException e) {
     MoreAsserts.assertContainsRegex("'input.txt' is not executable", e.getMessage());
   }
   input.setExecutable(true);
   action.execute(actionExecutionContext);
   assertTrue(output.isSymbolicLink());
   assertEquals(input, output.resolveSymbolicLinks());
 }
示例#24
0
 protected void createWorkspaceFile(Path repositoryDirectory, Rule rule)
     throws RepositoryFunctionException {
   try {
     Path workspaceFile = repositoryDirectory.getRelative("WORKSPACE");
     FileSystemUtils.writeContent(
         workspaceFile,
         Charset.forName("UTF-8"),
         String.format("# DO NOT EDIT: automatically generated WORKSPACE file for %s\n", rule));
   } catch (IOException e) {
     throw new RepositoryFunctionException(e, Transience.TRANSIENT);
   }
 }
示例#25
0
 static FileStateValue createWithStatNoFollow(
     RootedPath rootedPath,
     FileStatusWithDigest statNoFollow,
     @Nullable TimestampGranularityMonitor tsgm)
     throws InconsistentFilesystemException, IOException {
   Path path = rootedPath.asPath();
   if (statNoFollow.isFile()) {
     return statNoFollow.isSpecialFile()
         ? SpecialFileStateValue.fromStat(statNoFollow, tsgm)
         : RegularFileStateValue.fromPath(path, statNoFollow, tsgm);
   } else if (statNoFollow.isDirectory()) {
     return DIRECTORY_FILE_STATE_NODE;
   } else if (statNoFollow.isSymbolicLink()) {
     return new SymlinkFileStateValue(path.readSymbolicLinkUnchecked());
   }
   throw new InconsistentFilesystemException(
       "according to stat, existing path "
           + path
           + " is "
           + "neither a file nor directory nor symlink.");
 }
示例#26
0
  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }

    if (!(other instanceof DecompressorValue)) {
      return false;
    }

    return directory.equals(((DecompressorValue) other).directory);
  }
示例#27
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;
  }
示例#28
0
  @Override
  public void beforeCommand(Command command, CommandEnvironment env) {
    this.env = env;
    env.getEventBus().register(this);

    if (workers == null) {
      Path logDir = env.getRuntime().getOutputBase().getRelative("worker-logs");
      try {
        logDir.createDirectory();
      } catch (IOException e) {
        env.getReporter()
            .handle(Event.error("Could not create directory for worker logs: " + logDir));
      }

      GenericKeyedObjectPoolConfig config = new GenericKeyedObjectPoolConfig();

      // It's better to re-use a worker as often as possible and keep it hot, in order to profit
      // from JIT optimizations as much as possible.
      config.setLifo(true);

      // Check for & deal with idle workers every 5 seconds.
      config.setTimeBetweenEvictionRunsMillis(5 * 1000);

      // Always test the liveliness of worker processes.
      config.setTestOnBorrow(true);
      config.setTestOnCreate(true);
      config.setTestOnReturn(true);
      config.setTestWhileIdle(true);

      // Don't limit the total number of worker processes, as otherwise the pool might be full of
      // e.g. Java workers and could never accommodate another request for a different kind of
      // worker.
      config.setMaxTotal(-1);

      workers = new WorkerPool(new WorkerFactory(), config);
      workers.setReporter(env.getReporter());
      workers.setLogDirectory(logDir);
    }
  }
示例#29
0
  /** Parse a test result XML file into a {@link TestCase}. */
  @Nullable
  protected TestCase parseTestResult(Path resultFile) {
    /* xml files. We avoid parsing it unnecessarily, since test results can potentially consume
    a large amount of memory. */
    if (executionOptions.testSummary != TestSummaryFormat.DETAILED) {
      return null;
    }

    try (InputStream fileStream = resultFile.getInputStream()) {
      return new TestXmlOutputParser().parseXmlIntoTestResult(fileStream);
    } catch (IOException | TestXmlOutputParserException e) {
      return null;
    }
  }
示例#30
0
  @Before
  public final void startServer() throws Exception {
    // Do not use `createUnixTempDir()` here since the file name that results is longer
    // than 108 characters, so cannot be used as local socket address.
    File file = File.createTempFile("scratch", ".tmp", new File("/tmp"));
    file.delete();
    file.mkdir();
    serverDir = this.scratch.dir(file.getAbsolutePath());

    workspaceDir = this.scratch.createUnixTempDir();
    workspaceDir.createDirectory();
    client = new RPCTestingClient(outErr, serverDir.getRelative("server.socket"));
    RPCService service = new RPCService(helloWorldCommand);
    server =
        new RPCServer(
            new JavaClock(),
            service,
            MAX_IDLE_MILLIS,
            HEALTH_CHECK_MILLIS,
            serverDir,
            workspaceDir);
    serverThread.start();
  }