@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); } }
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); } }
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()); }
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(); }
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); }
/** * 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; }
@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)"); } }
@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())); } }
@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"); }
/** * 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); }
/** * 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 -> <build_root>/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; }
@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()); }
@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); }
/** * 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; } } }
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(); }
@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)"); } }
/** 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)); } } }
@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(); } }
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()); }
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); } }
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."); }
@Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof DecompressorValue)) { return false; } return directory.equals(((DecompressorValue) other).directory); }
/** * 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; }
@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); } }
/** 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; } }
@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(); }