Search in sources :

Example 1 with Path

use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.

the class AndroidNdkRepositoryFunction method fetch.

@Override
public RepositoryDirectoryValue.Builder fetch(Rule rule, Path outputDirectory, BlazeDirectories directories, Environment env, Map<String, String> markerData) throws InterruptedException, RepositoryFunctionException {
    Map<String, String> environ = declareEnvironmentDependencies(markerData, env, PATH_ENV_VAR_AS_LIST);
    if (environ == null) {
        return null;
    }
    prepareLocalRepositorySymlinkTree(rule, outputDirectory);
    WorkspaceAttributeMapper attributes = WorkspaceAttributeMapper.of(rule);
    PathFragment pathFragment;
    if (attributes.isAttributeValueExplicitlySpecified("path")) {
        pathFragment = getTargetPath(rule, directories.getWorkspace());
    } else if (environ.get(PATH_ENV_VAR) != null) {
        pathFragment = getAndroidNdkHomeEnvironmentVar(directories.getWorkspace(), environ);
    } else {
        throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "Either the path attribute of android_ndk_repository or the ANDROID_NDK_HOME " + " environment variable must be set."), Transience.PERSISTENT);
    }
    Path ndkSymlinkTreeDirectory = outputDirectory.getRelative("ndk");
    try {
        ndkSymlinkTreeDirectory.createDirectory();
    } catch (IOException e) {
        throw new RepositoryFunctionException(e, Transience.TRANSIENT);
    }
    Path ndkHome = directories.getOutputBase().getFileSystem().getPath(pathFragment);
    if (!symlinkLocalRepositoryContents(ndkSymlinkTreeDirectory, ndkHome)) {
        return null;
    }
    String ruleName = rule.getName();
    // We need to fetch the NDK release info from the actual home to avoid cycle in the
    // dependency graph (the path relative to the repository root depends on the
    // repository being fetched).
    NdkRelease ndkRelease = getNdkRelease(ndkHome, env);
    if (env.valuesMissing()) {
        return null;
    }
    String apiLevelString;
    if (attributes.isAttributeValueExplicitlySpecified("api_level")) {
        try {
            apiLevelString = attributes.get("api_level", Type.INTEGER).toString();
        } catch (EvalException e) {
            throw new RepositoryFunctionException(e, Transience.PERSISTENT);
        }
    } else {
        DirectoryListingValue platformsDirectoryValue = AndroidRepositoryUtils.getDirectoryListing(ndkHome, PLATFORMS_DIR, env);
        if (platformsDirectoryValue == null) {
            return null;
        }
        ImmutableSortedSet<Integer> apiLevels = AndroidRepositoryUtils.getApiLevels(platformsDirectoryValue.getDirents());
        if (apiLevels.isEmpty()) {
            // themselves.
            throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "android_ndk_repository requires that at least one Android platform is present in " + "the Android NDK platforms directory. Please ensure that the path attribute " + "or the ANDROID_NDK_HOME environment variable points to a valid NDK."), Transience.PERSISTENT);
        }
        apiLevelString = apiLevels.first().toString();
    }
    // NDK minor revisions should be backwards compatible within a major revision, the crosstools
    // we generate don't care about the minor revision.
    NdkMajorRevision ndkMajorRevision;
    if (!ndkRelease.isValid) {
        String warningMessage = String.format("The revision of the Android NDK referenced by android_ndk_repository rule '%s' " + "could not be determined (the revision string found is '%s'). Defaulting to " + "revision %s.", ruleName, ndkRelease.rawRelease, AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getKey());
        env.getListener().handle(Event.warn(warningMessage));
        ndkMajorRevision = AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getValue();
    } else if (!AndroidNdkCrosstools.isKnownNDKRevision(ndkRelease)) {
        String warningMessage = String.format("The major revision of the Android NDK referenced by android_ndk_repository rule " + "'%s' is %s. The major revisions supported by Bazel are %s. Defaulting to " + "revision %s.", ruleName, ndkRelease.majorRevision, AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS.keySet(), AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getKey());
        env.getListener().handle(Event.warn(warningMessage));
        ndkMajorRevision = AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getValue();
    } else {
        ndkMajorRevision = AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS.get(ndkRelease.majorRevision);
    }
    ApiLevel apiLevel = ndkMajorRevision.apiLevel(env.getListener(), ruleName, apiLevelString);
    ImmutableList.Builder<CrosstoolStlPair> crosstoolsAndStls = ImmutableList.builder();
    try {
        String hostPlatform = AndroidNdkCrosstools.getHostPlatform(ndkRelease);
        NdkPaths ndkPaths = new NdkPaths(ruleName, hostPlatform, apiLevel);
        for (StlImpl stlImpl : StlImpls.get(ndkPaths)) {
            CrosstoolRelease crosstoolRelease = ndkMajorRevision.crosstoolRelease(ndkPaths, stlImpl, hostPlatform);
            crosstoolsAndStls.add(new CrosstoolStlPair(crosstoolRelease, stlImpl));
        }
    } catch (NdkCrosstoolsException e) {
        throw new RepositoryFunctionException(new IOException(e), Transience.PERSISTENT);
    }
    String buildFile = createBuildFile(ruleName, crosstoolsAndStls.build());
    writeBuildFile(outputDirectory, buildFile);
    return RepositoryDirectoryValue.builder().setPath(outputDirectory);
}
Also used : RootedPath(com.google.devtools.build.lib.vfs.RootedPath) ToolPath(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath) Path(com.google.devtools.build.lib.vfs.Path) NdkRelease(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkRelease) ImmutableList(com.google.common.collect.ImmutableList) StlImpl(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpl) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) EvalException(com.google.devtools.build.lib.syntax.EvalException) IOException(java.io.IOException) NdkPaths(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkPaths) DirectoryListingValue(com.google.devtools.build.lib.skyframe.DirectoryListingValue) NdkMajorRevision(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkMajorRevision) ApiLevel(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.ApiLevel) CrosstoolRelease(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease) WorkspaceAttributeMapper(com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper) NdkCrosstoolsException(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools.NdkCrosstoolsException)

Example 2 with Path

use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.

the class AndroidNdkRepositoryFunction method getNdkRelease.

private static NdkRelease getNdkRelease(Path directory, Environment env) throws RepositoryFunctionException, InterruptedException {
    // For NDK r11+
    Path releaseFilePath = directory.getRelative("source.properties");
    if (!releaseFilePath.exists()) {
        // For NDK r10e
        releaseFilePath = directory.getRelative("RELEASE.TXT");
    }
    SkyKey releaseFileKey = FileValue.key(RootedPath.toRootedPath(directory, releaseFilePath));
    String releaseFileContent;
    try {
        env.getValueOrThrow(releaseFileKey, IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
        releaseFileContent = new String(FileSystemUtils.readContent(releaseFilePath));
    } catch (IOException | FileSymlinkException | InconsistentFilesystemException e) {
        throw new RepositoryFunctionException(new IOException("Could not read " + releaseFilePath.getBaseName() + " in Android NDK: " + e.getMessage()), Transience.PERSISTENT);
    }
    return NdkRelease.create(releaseFileContent.trim());
}
Also used : RootedPath(com.google.devtools.build.lib.vfs.RootedPath) ToolPath(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath) Path(com.google.devtools.build.lib.vfs.Path) SkyKey(com.google.devtools.build.skyframe.SkyKey) FileSymlinkException(com.google.devtools.build.lib.skyframe.FileSymlinkException) IOException(java.io.IOException) InconsistentFilesystemException(com.google.devtools.build.lib.skyframe.InconsistentFilesystemException)

Example 3 with Path

use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.

the class StandaloneTestStrategy method exec.

@Override
public void exec(TestRunnerAction action, ActionExecutionContext actionExecutionContext) throws ExecException, InterruptedException {
    Path execRoot = actionExecutionContext.getExecutor().getExecRoot();
    Path coverageDir = execRoot.getRelative(action.getCoverageDirectory());
    Path runfilesDir = getLocalRunfilesDirectory(action, actionExecutionContext, binTools, action.getLocalShellEnvironment(), action.isEnableRunfiles());
    Path tmpDir = tmpDirRoot.getChild(getTmpDirName(action.getExecutionSettings().getExecutable().getExecPath()));
    Map<String, String> env = setupEnvironment(action, execRoot, runfilesDir, tmpDir);
    Path workingDirectory = runfilesDir.getRelative(action.getRunfilesPrefix());
    ResolvedPaths resolvedPaths = action.resolve(execRoot);
    Map<String, String> info = new HashMap<>();
    // This key is only understood by StandaloneSpawnStrategy.
    info.put("timeout", "" + getTimeout(action));
    info.putAll(action.getTestProperties().getExecutionInfo());
    Spawn spawn = new SimpleSpawn(action, getArgs(COLLECT_COVERAGE, action), ImmutableMap.copyOf(env), ImmutableMap.copyOf(info), new RunfilesSupplierImpl(runfilesDir.asFragment(), action.getExecutionSettings().getRunfiles()), /*inputs=*/
    ImmutableList.copyOf(action.getInputs()), /*tools=*/
    ImmutableList.<Artifact>of(), /*filesetManifests=*/
    ImmutableList.<Artifact>of(), ImmutableList.copyOf(action.getSpawnOutputs()), action.getTestProperties().getLocalResourceUsage(executionOptions.usingLocalTestJobs()));
    Executor executor = actionExecutionContext.getExecutor();
    TestResultData.Builder dataBuilder = TestResultData.newBuilder();
    try {
        int maxAttempts = getTestAttempts(action);
        TestResultData data = executeTestAttempt(action, spawn, actionExecutionContext, execRoot, coverageDir, tmpDir, workingDirectory);
        int attempt;
        for (attempt = 1; data.getStatus() != BlazeTestStatus.PASSED && attempt < maxAttempts; attempt++) {
            processFailedTestAttempt(attempt, executor, action, dataBuilder, data, actionExecutionContext.getFileOutErr());
            data = executeTestAttempt(action, spawn, actionExecutionContext, execRoot, coverageDir, tmpDir, workingDirectory);
        }
        processLastTestAttempt(attempt, dataBuilder, data);
        ImmutableList.Builder<Pair<String, Path>> testOutputsBuilder = new ImmutableList.Builder<>();
        if (action.getTestLog().getPath().exists()) {
            testOutputsBuilder.add(Pair.of("test.log", action.getTestLog().getPath()));
        }
        if (resolvedPaths.getXmlOutputPath().exists()) {
            testOutputsBuilder.add(Pair.of("test.xml", resolvedPaths.getXmlOutputPath()));
        }
        executor.getEventBus().post(new TestAttempt(action, attempt, data.getTestPassed(), data.getRunDurationMillis(), testOutputsBuilder.build(), true));
        finalizeTest(actionExecutionContext, action, dataBuilder.build());
    } catch (IOException e) {
        executor.getEventHandler().handle(Event.error("Caught I/O exception: " + e));
        throw new EnvironmentalExecException("unexpected I/O exception", e);
    }
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) TestResultData(com.google.devtools.build.lib.view.test.TestStatus.TestResultData) HashMap(java.util.HashMap) SimpleSpawn(com.google.devtools.build.lib.actions.SimpleSpawn) ImmutableList(com.google.common.collect.ImmutableList) Builder(com.google.devtools.build.lib.view.test.TestStatus.TestResultData.Builder) IOException(java.io.IOException) EnvironmentalExecException(com.google.devtools.build.lib.actions.EnvironmentalExecException) RunfilesSupplierImpl(com.google.devtools.build.lib.analysis.RunfilesSupplierImpl) ResolvedPaths(com.google.devtools.build.lib.rules.test.TestRunnerAction.ResolvedPaths) Executor(com.google.devtools.build.lib.actions.Executor) Builder(com.google.devtools.build.lib.view.test.TestStatus.TestResultData.Builder) TestAttempt(com.google.devtools.build.lib.rules.test.TestAttempt) SimpleSpawn(com.google.devtools.build.lib.actions.SimpleSpawn) Spawn(com.google.devtools.build.lib.actions.Spawn) Pair(com.google.devtools.build.lib.util.Pair)

Example 4 with Path

use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.

the class StandaloneTestStrategy method processFailedTestAttempt.

private void processFailedTestAttempt(int attempt, Executor executor, TestRunnerAction action, Builder dataBuilder, TestResultData data, FileOutErr outErr) throws IOException {
    ImmutableList.Builder<Pair<String, Path>> testOutputsBuilder = new ImmutableList.Builder<>();
    // Rename outputs
    String namePrefix = FileSystemUtils.removeExtension(action.getTestLog().getExecPath().getBaseName());
    Path attemptsDir = action.getTestLog().getPath().getParentDirectory().getChild(namePrefix + "_attempts");
    attemptsDir.createDirectory();
    String attemptPrefix = "attempt_" + attempt;
    Path testLog = attemptsDir.getChild(attemptPrefix + ".log");
    if (action.getTestLog().getPath().exists()) {
        action.getTestLog().getPath().renameTo(testLog);
        testOutputsBuilder.add(Pair.of("test.log", testLog));
    }
    ResolvedPaths resolvedPaths = action.resolve(executor.getExecRoot());
    if (resolvedPaths.getXmlOutputPath().exists()) {
        Path destinationPath = attemptsDir.getChild(attemptPrefix + ".xml");
        resolvedPaths.getXmlOutputPath().renameTo(destinationPath);
        testOutputsBuilder.add(Pair.of("test.xml", destinationPath));
    }
    // Add the test log to the output
    dataBuilder.addFailedLogs(testLog.toString());
    dataBuilder.addTestTimes(data.getTestTimes(0));
    dataBuilder.addAllTestProcessTimes(data.getTestProcessTimesList());
    executor.getEventBus().post(new TestAttempt(action, attempt, data.getTestPassed(), data.getRunDurationMillis(), testOutputsBuilder.build(), false));
    processTestOutput(executor, outErr, new TestResult(action, data, false), testLog);
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) ImmutableList(com.google.common.collect.ImmutableList) Builder(com.google.devtools.build.lib.view.test.TestStatus.TestResultData.Builder) TestAttempt(com.google.devtools.build.lib.rules.test.TestAttempt) TestResult(com.google.devtools.build.lib.rules.test.TestResult) ResolvedPaths(com.google.devtools.build.lib.rules.test.TestRunnerAction.ResolvedPaths) Pair(com.google.devtools.build.lib.util.Pair)

Example 5 with Path

use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.

the class StandaloneTestStrategy method processTestOutput.

/**
   * Outputs test result to the stdout after test has finished (e.g. for --test_output=all or
   * --test_output=errors). Will also try to group output lines together (up to 10000 lines) so
   * parallel test outputs will not get interleaved.
   */
protected void processTestOutput(Executor executor, FileOutErr outErr, TestResult result, Path testLogPath) throws IOException {
    Path testOutput = executor.getExecRoot().getRelative(testLogPath.asFragment());
    boolean isPassed = result.getData().getTestPassed();
    try {
        if (TestLogHelper.shouldOutputTestLog(executionOptions.testOutput, isPassed)) {
            TestLogHelper.writeTestLog(testOutput, result.getTestName(), outErr.getOutputStream());
        }
    } finally {
        if (isPassed) {
            executor.getEventHandler().handle(Event.of(EventKind.PASS, null, result.getTestName()));
        } else {
            if (result.getData().getStatus() == BlazeTestStatus.TIMEOUT) {
                executor.getEventHandler().handle(Event.of(EventKind.TIMEOUT, null, result.getTestName() + " (see " + testOutput + ")"));
            } else {
                executor.getEventHandler().handle(Event.of(EventKind.FAIL, null, result.getTestName() + " (see " + testOutput + ")"));
            }
        }
    }
}
Also used : Path(com.google.devtools.build.lib.vfs.Path)

Aggregations

Path (com.google.devtools.build.lib.vfs.Path)492 Test (org.junit.Test)250 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)111 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)105 IOException (java.io.IOException)102 Artifact (com.google.devtools.build.lib.actions.Artifact)37 SkyKey (com.google.devtools.build.skyframe.SkyKey)37 ArrayList (java.util.ArrayList)29 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)17 FileSystem (com.google.devtools.build.lib.vfs.FileSystem)17 InMemoryFileSystem (com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem)17 HashMap (java.util.HashMap)17 WindowsPath (com.google.devtools.build.lib.windows.WindowsFileSystem.WindowsPath)16 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)14 Before (org.junit.Before)14 Package (com.google.devtools.build.lib.packages.Package)13 FileStatus (com.google.devtools.build.lib.vfs.FileStatus)13 Map (java.util.Map)12 Nullable (javax.annotation.Nullable)12 Executor (com.google.devtools.build.lib.actions.Executor)10