@Test
  public void ruleKeyDoesNotChangeWhenOnlyDependencyRuleKeyChanges() throws Exception {
    ProjectFilesystem filesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);

    Path depOutput = Paths.get("output");
    FakeBuildRule dep =
        resolver.addToIndex(
            new FakeBuildRule(BuildTargetFactory.newInstance("//:dep"), filesystem, pathResolver));
    dep.setOutputFile(depOutput.toString());
    filesystem.writeContentsToPath("hello", dep.getPathToOutput());

    FakeFileHashCache hashCache =
        new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(depOutput), HashCode.fromInt(0)));

    BuildRule rule =
        GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:rule"))
            .setOut("out")
            .setSrcs(ImmutableList.<SourcePath>of(new BuildTargetSourcePath(dep.getBuildTarget())))
            .build(resolver, filesystem);

    RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    assertThat(inputKey1, Matchers.equalTo(inputKey2));
  }
Beispiel #2
0
  @Test
  public void testCreateRelativeSymlinkToFilesInRoot() throws IOException {
    ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmp.getRoot());
    tmp.newFile("biz.txt");

    Path pathToDesiredLinkUnderProjectRoot = Paths.get("gamma.txt");
    Path pathToExistingFileUnderProjectRoot = Paths.get("biz.txt");
    Path relativePath =
        MorePaths.createRelativeSymlink(
            pathToDesiredLinkUnderProjectRoot,
            pathToExistingFileUnderProjectRoot,
            projectFilesystem);
    assertEquals("biz.txt", relativePath.toString());

    Path absolutePathToDesiredLinkUnderProjectRoot =
        projectFilesystem.resolve(pathToDesiredLinkUnderProjectRoot);
    assertTrue(Files.isSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot));
    Path targetOfSymbolicLink = Files.readSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot);
    assertEquals(relativePath, targetOfSymbolicLink);

    Path absolutePathToExistingFileUnderProjectRoot =
        projectFilesystem.resolve(pathToExistingFileUnderProjectRoot);
    Files.write(absolutePathToExistingFileUnderProjectRoot, "Hello, World!".getBytes());
    String dataReadFromSymlink =
        new String(Files.readAllBytes(absolutePathToDesiredLinkUnderProjectRoot));
    assertEquals("Hello, World!", dataReadFromSymlink);
  }
  @Test
  public void testOutputFailed() throws IOException {
    ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmpDir.getRoot().toPath());

    ChromeTraceBuildListener listener =
        new ChromeTraceBuildListener(
            projectFilesystem,
            new FakeClock(1409702151000000000L),
            new ObjectMapper(),
            Locale.US,
            TimeZone.getTimeZone("America/Los_Angeles"),
            /* tracesToKeep */ 3,
            false);
    try {
      assumeTrue("Can make the root directory read-only", tmpDir.getRoot().setReadOnly());
      listener.outputTrace(new BuildId("BUILD_ID"));
      fail("Expected an exception.");
    } catch (HumanReadableException e) {
      assertEquals(
          "Unable to write trace file: java.nio.file.AccessDeniedException: "
              + projectFilesystem.resolve(BuckConstant.BUCK_OUTPUT_PATH),
          e.getMessage());
    } finally {
      tmpDir.getRoot().setWritable(true);
    }
  }
  @BeforeClass
  public static void createParser() {
    ProjectFilesystem filesystem = new FakeProjectFilesystem();
    FakeBuckConfig buckConfig = new FakeBuckConfig();
    ParserConfig parserConfig = new ParserConfig(buckConfig);
    PythonBuckConfig pythonBuckConfig = new PythonBuckConfig(buckConfig, new ExecutableFinder());

    ImmutableSet<Description<?>> descriptions =
        ImmutableSet.of(
            new RemoteFileDescription(new ExplodingDownloader()), new PrebuiltJarDescription());

    DefaultProjectBuildFileParserFactory parserFactory =
        new DefaultProjectBuildFileParserFactory(
            filesystem.getRootPath(),
            pythonBuckConfig.getPythonInterpreter(),
            parserConfig.getAllowEmptyGlobs(),
            parserConfig.getBuildFileName(),
            parserConfig.getDefaultIncludes(),
            descriptions);
    buildFileParser =
        parserFactory.createParser(
            new TestConsole(),
            ImmutableMap.<String, String>of(),
            BuckEventBusFactory.newInstance());
  }
  @Test
  public void canCompressTraces() throws IOException {
    ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmpDir.getRoot().toPath());

    ChromeTraceBuildListener listener =
        new ChromeTraceBuildListener(
            projectFilesystem,
            new FakeClock(1409702151000000000L),
            new ObjectMapper(),
            Locale.US,
            TimeZone.getTimeZone("America/Los_Angeles"),
            /* tracesToKeep */ 1,
            true);
    listener.outputTrace(new BuildId("BUILD_ID"));

    Path tracePath = Paths.get("buck-out/log/traces/build.2014-09-02.16-55-51.BUILD_ID.trace.gz");

    assertTrue(projectFilesystem.exists(tracePath));

    BufferedReader reader =
        new BufferedReader(
            new InputStreamReader(
                new GZIPInputStream(projectFilesystem.newFileInputStream(tracePath))));

    List<?> elements = new Gson().fromJson(reader, List.class);
    assertThat(elements, notNullValue());
  }
 public Optional<Path> checkPathExists(String pathString, String errorMsg) {
   Path path = Paths.get(pathString);
   if (projectFilesystem.exists(path)) {
     return Optional.of(projectFilesystem.getPathForRelativePath(path));
   }
   throw new HumanReadableException(errorMsg + path);
 }
Beispiel #7
0
 private static boolean inputFilesUnderSymlink(
     // We use Collection<Path> instead of Iterable<Path> to prevent
     // accidentally passing in Path, since Path itself is Iterable<Path>.
     Collection<Path> inputs,
     ProjectFilesystem projectFilesystem,
     Map<Path, Path> symlinkExistenceCache,
     Map<Path, Path> newSymlinksEncountered)
     throws IOException {
   boolean result = false;
   for (Path input : inputs) {
     for (int i = 1; i < input.getNameCount(); i++) {
       Path subpath = input.subpath(0, i);
       Path resolvedSymlink = symlinkExistenceCache.get(subpath);
       if (resolvedSymlink != null) {
         LOG.debug("Detected cached symlink %s -> %s", subpath, resolvedSymlink);
         newSymlinksEncountered.put(subpath, resolvedSymlink);
         result = true;
       } else if (projectFilesystem.isSymLink(subpath)) {
         Path symlinkTarget = projectFilesystem.resolve(subpath).toRealPath();
         Path relativeSymlinkTarget =
             projectFilesystem.getPathRelativeToProjectRoot(symlinkTarget).or(symlinkTarget);
         LOG.debug("Detected symbolic link %s -> %s", subpath, relativeSymlinkTarget);
         newSymlinksEncountered.put(subpath, relativeSymlinkTarget);
         symlinkExistenceCache.put(subpath, relativeSymlinkTarget);
         result = true;
       }
     }
   }
   return result;
 }
Beispiel #8
0
  private ImmutableMap<Path, Path> getExpandedSourcePaths(
      ExecutionContext context, ImmutableMap<Path, Path> paths) throws IOException {
    ProjectFilesystem projectFilesystem = context.getProjectFilesystem();
    ImmutableMap.Builder<Path, Path> sources = ImmutableMap.builder();

    for (ImmutableMap.Entry<Path, Path> ent : paths.entrySet()) {
      if (ent.getValue().toString().endsWith(SRC_ZIP)) {
        Path destinationDirectory = projectFilesystem.resolve(tempDir.resolve(ent.getKey()));
        Files.createDirectories(destinationDirectory);

        ImmutableList<Path> zipPaths =
            Unzip.extractZipFile(
                projectFilesystem.resolve(ent.getValue()),
                destinationDirectory,
                Unzip.ExistingFileMode.OVERWRITE);
        for (Path path : zipPaths) {
          Path modulePath = destinationDirectory.relativize(path);
          sources.put(modulePath, path);
        }
      } else {
        sources.put(ent.getKey(), ent.getValue());
      }
    }

    return sources.build();
  }
  @Test
  public void testAppleDynamicLibraryWithDsym() throws Exception {
    assumeTrue(Platform.detect() == Platform.MACOS);
    assumeTrue(AppleNativeIntegrationTestUtils.isApplePlatformAvailable(ApplePlatform.MACOSX));

    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(this, "apple_library_shared", tmp);
    workspace.setUp();
    ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath());

    ProjectWorkspace.ProcessResult result =
        workspace.runBuckCommand(
            "build",
            "//Libraries/TestLibrary:TestLibrary#shared,macosx-x86_64,dwarf-and-dsym",
            "--config",
            "cxx.cflags=-g");
    result.assertSuccess();

    Path output =
        tmp.getRoot()
            .resolve(filesystem.getBuckPaths().getGenDir())
            .resolve("Libraries/TestLibrary/TestLibrary#macosx-x86_64,shared")
            .resolve("libLibraries_TestLibrary_TestLibrary.dylib");
    assertThat(Files.exists(output), is(true));

    Path dsymPath =
        tmp.getRoot()
            .resolve(filesystem.getBuckPaths().getGenDir())
            .resolve("Libraries/TestLibrary")
            .resolve("TestLibrary#apple-dsym,macosx-x86_64,shared.dSYM");
    assertThat(Files.exists(dsymPath), is(true));
    AppleDsymTestUtil.checkDsymFileHasDebugSymbol("+[TestClass answer]", workspace, dsymPath);
  }
Beispiel #10
0
 public static int parseAndWriteBuckCompatibleDepfile(
     ExecutionContext context,
     ProjectFilesystem filesystem,
     HeaderPathNormalizer headerPathNormalizer,
     HeaderVerification headerVerification,
     Path sourceDepFile,
     Path destDepFile,
     Path inputPath,
     Path outputPath)
     throws IOException {
   // Process the dependency file, fixing up the paths, and write it out to it's final location.
   // The paths of the headers written out to the depfile are the paths to the symlinks from the
   // root of the repo if the compilation included them from the header search paths pointing to
   // the symlink trees, or paths to headers relative to the source file if the compilation
   // included them using source relative include paths. To handle both cases we check for the
   // prerequisites both in the values and the keys of the replacement map.
   Logger.get(Depfiles.class).debug("Processing dependency file %s as Makefile", sourceDepFile);
   ImmutableMap<String, Object> params =
       ImmutableMap.<String, Object>of("input", inputPath, "output", outputPath);
   try (InputStream input = filesystem.newFileInputStream(sourceDepFile);
       BufferedReader reader = new BufferedReader(new InputStreamReader(input));
       OutputStream output = filesystem.newFileOutputStream(destDepFile);
       BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
       SimplePerfEvent.Scope perfEvent =
           SimplePerfEvent.scope(
               context.getBuckEventBus(), PerfEventId.of("depfile-parse"), params)) {
     ImmutableList<String> prereqs = Depfiles.parseDepfile(reader).getPrereqs();
     // Skip the first prereq, as it's the input source file.
     Preconditions.checkState(inputPath.toString().equals(prereqs.get(0)));
     ImmutableList<String> headers = prereqs.subList(1, prereqs.size());
     for (String rawHeader : headers) {
       Path header = Paths.get(rawHeader).normalize();
       Optional<Path> absolutePath =
           headerPathNormalizer.getAbsolutePathForUnnormalizedPath(header);
       if (absolutePath.isPresent()) {
         Preconditions.checkState(absolutePath.get().isAbsolute());
         writer.write(absolutePath.get().toString());
         writer.newLine();
       } else if (headerVerification.getMode() != HeaderVerification.Mode.IGNORE
           && !headerVerification.isWhitelisted(header.toString())) {
         context
             .getBuckEventBus()
             .post(
                 ConsoleEvent.create(
                     headerVerification.getMode() == HeaderVerification.Mode.ERROR
                         ? Level.SEVERE
                         : Level.WARNING,
                     "%s: included an untracked header \"%s\"",
                     inputPath,
                     header));
         if (headerVerification.getMode() == HeaderVerification.Mode.ERROR) {
           return 1;
         }
       }
     }
   }
   return 0;
 }
  private void assertCompDir(Path compDir, Optional<String> failure) throws Exception {
    ProjectFilesystem filesystem = new ProjectFilesystem(tmp.getRoot().toPath());
    CxxPlatform platform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig()));

    // Build up the paths to various files the archive step will use.
    ImmutableList<String> compiler =
        platform.getCc().getCommandPrefix(new SourcePathResolver(new BuildRuleResolver()));
    Path output = filesystem.resolve(Paths.get("output.o"));
    Path relativeInput = Paths.get("input.c");
    Path input = filesystem.resolve(relativeInput);
    filesystem.writeContentsToPath("int main() {}", relativeInput);

    ImmutableList.Builder<String> preprocessorCommand = ImmutableList.builder();
    preprocessorCommand.addAll(compiler);

    ImmutableList.Builder<String> compilerCommand = ImmutableList.builder();
    compilerCommand.addAll(compiler);
    compilerCommand.add("-g");

    DebugPathSanitizer sanitizer =
        new DebugPathSanitizer(200, File.separatorChar, compDir, ImmutableBiMap.<Path, Path>of());

    // Build an archive step.
    CxxPreprocessAndCompileStep step =
        new CxxPreprocessAndCompileStep(
            CxxPreprocessAndCompileStep.Operation.COMPILE_MUNGE_DEBUGINFO,
            output,
            relativeInput,
            CxxSource.Type.C,
            Optional.of(preprocessorCommand.build()),
            Optional.of(compilerCommand.build()),
            ImmutableMap.<Path, Path>of(),
            sanitizer);

    // Execute the archive step and verify it ran successfully.
    ExecutionContext executionContext =
        TestExecutionContext.newBuilder()
            .setProjectFilesystem(new ProjectFilesystem(tmp.getRoot().toPath()))
            .build();
    TestConsole console = (TestConsole) executionContext.getConsole();
    int exitCode = step.execute(executionContext);
    if (failure.isPresent()) {
      assertNotEquals("compile step succeeded", 0, exitCode);
      assertThat(
          console.getTextWrittenToStdErr(),
          console.getTextWrittenToStdErr(),
          Matchers.containsString(failure.get()));
    } else {
      assertEquals("compile step failed: " + console.getTextWrittenToStdErr(), 0, exitCode);
      // Verify that we find the expected compilation dir embedded in the file.
      String contents = new String(Files.readAllBytes(output));
      assertThat(contents, Matchers.containsString(sanitizer.getCompilationDirectory()));
    }

    // Cleanup.
    Files.delete(input);
    Files.deleteIfExists(output);
  }
  @Test
  public void usesCorrectCommandForPreprocess() {

    // Setup some dummy values for inputs to the CxxPreprocessAndCompile.
    SourcePathResolver pathResolver =
        new SourcePathResolver(
            new BuildRuleResolver(TargetGraph.EMPTY, new BuildTargetNodeToBuildRuleTransformer()));
    BuildTarget target = BuildTargetFactory.newInstance("//foo:bar");
    BuildRuleParams params = new FakeBuildRuleParamsBuilder(target).build();
    ProjectFilesystem filesystem = new FakeProjectFilesystem();
    ImmutableList<String> platformFlags = ImmutableList.of("-Dtest=blah");
    ImmutableList<String> ruleFlags = ImmutableList.of("-Dfoo=bar");
    Path output = Paths.get("test.ii");
    Path depFile = Paths.get("test.ii.dep");
    Path input = Paths.get("test.cpp");
    Path prefixHeader = Paths.get("prefix.pch");

    CxxPreprocessAndCompile buildRule =
        CxxPreprocessAndCompile.preprocess(
            params,
            pathResolver,
            new PreprocessorDelegate(
                pathResolver,
                DEFAULT_SANITIZER,
                DEFAULT_WORKING_DIR,
                DEFAULT_PREPROCESSOR,
                platformFlags,
                ruleFlags,
                ImmutableSet.<Path>of(),
                ImmutableSet.<Path>of(),
                ImmutableSet.<Path>of(),
                DEFAULT_FRAMEWORK_ROOTS,
                DEFAULT_FRAMEWORK_PATH_SEARCH_PATH_FUNCTION,
                Optional.<SourcePath>of(new FakeSourcePath(filesystem, prefixHeader.toString())),
                ImmutableList.of(CxxHeaders.builder().build())),
            output,
            new FakeSourcePath(input.toString()),
            DEFAULT_INPUT_TYPE,
            DEFAULT_SANITIZER);

    // Verify it uses the expected command.
    ImmutableList<String> expectedPreprocessCommand =
        ImmutableList.<String>builder()
            .add("preprocessor")
            .add("-Dtest=blah")
            .add("-Dfoo=bar")
            .add("-include")
            .add(filesystem.resolve(prefixHeader).toString())
            .add("-x", "c++")
            .add("-E")
            .add("-MD")
            .add("-MF")
            .add(depFile.toString() + ".tmp")
            .add(input.toString())
            .build();
    ImmutableList<String> actualPreprocessCommand = buildRule.makeMainStep().getCommand();
    assertEquals(expectedPreprocessCommand, actualPreprocessCommand);
  }
Beispiel #13
0
 public long getOutputSize() throws IOException {
   long size = 0;
   for (Path path : getRecordedDirsAndFiles()) {
     if (projectFilesystem.isFile(path)) {
       size += projectFilesystem.getFileSize(path);
     }
   }
   return size;
 }
 @Test
 public void skipsFirstCacheBecauseIgnored() throws IOException {
   Path path = Paths.get("world.txt");
   Path fullPath = tmp.getRootPath().resolve(path);
   ProjectFilesystem filesystem = new ProjectFilesystem(tmp.getRootPath(), ImmutableSet.of(path));
   filesystem.touch(path);
   DefaultFileHashCache innerCache = new DefaultFileHashCache(filesystem);
   StackedFileHashCache cache = new StackedFileHashCache(ImmutableList.of(innerCache));
   expectedException.expect(NoSuchFileException.class);
   cache.get(fullPath);
 }
Beispiel #15
0
 @Override
 public int execute(ExecutionContext context) throws InterruptedException {
   ProjectFilesystem filesystem = context.getProjectFilesystem();
   try {
     filesystem.move(source, destination, options);
   } catch (IOException e) {
     context.logError(e, "error moving %s -> %s", source, destination);
     return 1;
   }
   return 0;
 }
Beispiel #16
0
  /**
   * Looks through filtered drawables for files not of the target density and replaces them with
   * scaled versions.
   *
   * <p>Any drawables found by this step didn't have equivalents in the target density. If they are
   * of a higher density, we can replicate what Android does and downscale them at compile-time.
   */
  private void scaleUnmatchedDrawables(ExecutionContext context)
      throws IOException, InterruptedException {
    ResourceFilters.Density targetDensity = ResourceFilters.Density.ORDERING.max(targetDensities);

    // Go over all the images that remain after filtering.
    Preconditions.checkNotNull(drawableFinder);
    Collection<Path> drawables =
        drawableFinder.findDrawables(inResDirToOutResDirMap.values(), filesystem);
    for (Path drawable : drawables) {
      if (drawable.toString().endsWith(".9.png")) {
        // Skip nine-patch for now.
        continue;
      }

      ResourceFilters.Qualifiers qualifiers = new ResourceFilters.Qualifiers(drawable);
      ResourceFilters.Density density = qualifiers.density;

      // If the image has a qualifier but it's not the right one.
      Preconditions.checkNotNull(targetDensities);
      if (!targetDensities.contains(density)) {

        // Replace density qualifier with target density using regular expression to match
        // the qualifier in the context of a path to a drawable.
        String fromDensity =
            (density == ResourceFilters.Density.NO_QUALIFIER ? "" : "-") + density.toString();
        Path destination =
            Paths.get(
                MorePaths.pathWithUnixSeparators(drawable)
                    .replaceFirst(
                        "((?:^|/)drawable[^/]*)" + Pattern.quote(fromDensity) + "(-|$|/)",
                        "$1-" + targetDensity + "$2"));

        double factor = targetDensity.value() / density.value();
        if (factor >= 1.0) {
          // There is no point in up-scaling, or converting between drawable and drawable-mdpi.
          continue;
        }

        // Make sure destination folder exists and perform downscaling.
        filesystem.createParentDirs(destination);
        Preconditions.checkNotNull(imageScaler);
        imageScaler.scale(factor, drawable, destination, context);

        // Delete source file.
        filesystem.deleteFileAtPath(drawable);

        // Delete newly-empty directories to prevent missing resources errors in apkbuilder.
        Path parent = drawable.getParent();
        if (filesystem.listFiles(parent).length == 0) {
          filesystem.deleteFileAtPath(parent);
        }
      }
    }
  }
  @Test
  public void testGetBuildStepsWhenThereAreNoClassesToDex()
      throws IOException, InterruptedException {
    JavaLibrary javaLibrary = createMock(JavaLibrary.class);
    expect(javaLibrary.getClassNamesToHashes())
        .andReturn(ImmutableSortedMap.<String, HashCode>of());

    BuildContext context = createMock(BuildContext.class);
    FakeBuildableContext buildableContext = new FakeBuildableContext();
    ProjectFilesystem projectFilesystem = createMock(ProjectFilesystem.class);

    replayAll();

    BuildTarget buildTarget = BuildTargetFactory.newInstance("//foo:bar");
    BuildRuleParams params =
        new FakeBuildRuleParamsBuilder(buildTarget).setProjectFilesystem(projectFilesystem).build();
    DexProducedFromJavaLibrary preDex =
        new DexProducedFromJavaLibrary(
            params, new SourcePathResolver(new BuildRuleResolver()), javaLibrary);
    List<Step> steps = preDex.getBuildSteps(context, buildableContext);

    verifyAll();
    resetAll();

    expect(projectFilesystem.resolve(Paths.get("buck-out/gen/foo")))
        .andReturn(Paths.get("/home/user/buck-out/gen/foo"));
    expect(projectFilesystem.resolve(Paths.get("buck-out/gen/foo/bar.dex.jar")))
        .andReturn(Paths.get("/home/user/buck-out/gen/foo/bar.dex.jar"));
    replayAll();

    ExecutionContext executionContext = TestExecutionContext.newBuilder().build();

    MoreAsserts.assertSteps(
        "Do not generate a .dex.jar file.",
        ImmutableList.of(
            String.format("rm -f %s", Paths.get("/home/user/buck-out/gen/foo/bar.dex.jar")),
            String.format("mkdir -p %s", Paths.get("/home/user/buck-out/gen/foo")),
            "record_empty_dx"),
        steps,
        executionContext);

    verifyAll();
    resetAll();

    replayAll();

    Step recordArtifactAndMetadataStep = steps.get(2);
    assertThat(recordArtifactAndMetadataStep.getShortName(), startsWith("record_"));
    int exitCode = recordArtifactAndMetadataStep.execute(executionContext);
    assertEquals(0, exitCode);

    verifyAll();
  }
Beispiel #18
0
  /**
   * Writes the metadata currently stored in memory to the directory returned by {@link
   * BuildInfo#getPathToMetadataDirectory(BuildTarget)}.
   */
  public void writeMetadataToDisk(boolean clearExistingMetadata) throws IOException {
    if (clearExistingMetadata) {
      projectFilesystem.deleteRecursivelyIfExists(pathToMetadataDirectory);
    }
    projectFilesystem.mkdirs(pathToMetadataDirectory);

    for (Map.Entry<String, String> entry :
        Iterables.concat(metadataToWrite.entrySet(), getBuildMetadata().entrySet())) {
      projectFilesystem.writeContentsToPath(
          entry.getValue(), pathToMetadataDirectory.resolve(entry.getKey()));
    }
  }
  private int handleGet(Request baseRequest, HttpServletResponse response) throws IOException {
    if (!artifactCache.isPresent()) {
      response.getWriter().write("Serving local cache is disabled for this instance.");
      return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
    }

    String path = baseRequest.getUri().getPath();
    String[] pathElements = path.split("/");
    if (pathElements.length != 4 || !pathElements[2].equals("key")) {
      response.getWriter().write("Incorrect url format.");
      return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
    }

    RuleKey ruleKey = RuleKey.TO_RULE_KEY.apply(pathElements[3]);

    Path temp = null;
    try {
      temp =
          projectFilesystem.createTempFile(BuckConstant.SCRATCH_PATH, "outgoing_rulekey", ".tmp");
      projectFilesystem.createParentDirs(temp);
      CacheResult fetchResult;
      try {
        fetchResult = artifactCache.get().fetch(ruleKey, temp);
      } catch (InterruptedException e) {
        LOG.error(e, "Interrupted when fetching from local cache.");
        e.printStackTrace(response.getWriter());
        return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
      }
      if (!fetchResult.getType().isSuccess()) {
        return HttpServletResponse.SC_NOT_FOUND;
      }

      final Path tempFinal = temp;
      HttpArtifactCacheBinaryProtocol.FetchResponse fetchResponse =
          new HttpArtifactCacheBinaryProtocol.FetchResponse(
              ImmutableSet.of(ruleKey),
              fetchResult.getMetadata(),
              new ByteSource() {
                @Override
                public InputStream openStream() throws IOException {
                  return projectFilesystem.newFileInputStream(tempFinal);
                }
              });
      fetchResponse.write(response.getOutputStream());
      response.setContentLengthLong(fetchResponse.getContentLength());
      return HttpServletResponse.SC_OK;
    } finally {
      if (temp != null) {
        projectFilesystem.deleteFileAtPathIfExists(temp);
      }
    }
  }
  @Test
  public void usesFirstCache() throws IOException {
    ProjectFilesystem filesystem = FakeProjectFilesystem.createJavaOnlyFilesystem();

    Path path = Paths.get("world.txt");
    filesystem.touch(path);

    Path fullPath = filesystem.resolve(path);
    DefaultFileHashCache innerCache = new DefaultFileHashCache(filesystem);
    StackedFileHashCache cache = new StackedFileHashCache(ImmutableList.of(innerCache));
    cache.get(fullPath);
    assertTrue(innerCache.willGet(path));
  }
Beispiel #21
0
  @Override
  public StepExecutionResult execute(ExecutionContext context) throws InterruptedException {
    // Build the process, redirecting output to the provided output file.  In general,
    // it's undesirable that both stdout and stderr are being redirected to the same
    // input stream.  However, due to the nature of OS pipe buffering, we can't really
    // maintain the natural interleaving of multiple output streams in a way that we
    // can correctly associate both stdout/stderr streams to the one correct test out
    // of the many that ran.  So, our best bet is to just combine them all into stdout,
    // so they get properly interleaved with the test start and end messages that we
    // use when we parse the test output.
    ProcessBuilder builder = new ProcessBuilder();
    builder.command(command);
    builder.redirectOutput(filesystem.resolve(output).toFile());
    builder.redirectErrorStream(true);

    Process process;
    try {
      process = BgProcessKiller.startProcess(builder);
    } catch (IOException e) {
      context.logError(e, "Error starting command %s", command);
      return StepExecutionResult.ERROR;
    }

    // Run the test process, saving the exit code.
    ProcessExecutor executor = context.getProcessExecutor();
    ImmutableSet<ProcessExecutor.Option> options =
        ImmutableSet.of(ProcessExecutor.Option.EXPECTING_STD_OUT);
    ProcessExecutor.Result result =
        executor.execute(
            process,
            options,
            /* stdin */ Optional.<String>absent(),
            /* timeOutMs */ testRuleTimeoutMs,
            /* timeOutHandler */ Optional.<Function<Process, Void>>absent());

    if (result.isTimedOut()) {
      throw new HumanReadableException(
          "Timed out after %d ms running test command %s", testRuleTimeoutMs.or(-1L), command);
    }

    // Since test binaries return a non-zero exit code when unittests fail, save the exit code
    // to a file rather than signalling a step failure.
    try (FileOutputStream stream = new FileOutputStream(filesystem.resolve(exitCode).toFile())) {
      stream.write((Integer.toString(result.getExitCode())).getBytes());
    } catch (IOException e) {
      context.logError(e, "Error saving exit code to %s", exitCode);
      return StepExecutionResult.ERROR;
    }

    return StepExecutionResult.SUCCESS;
  }
Beispiel #22
0
  public OCamlBuildStep(
      SourcePathResolver resolver,
      ProjectFilesystem filesystem,
      OCamlBuildContext ocamlContext,
      ImmutableMap<String, String> cCompilerEnvironment,
      ImmutableList<String> cCompiler,
      ImmutableMap<String, String> cxxCompilerEnvironment,
      ImmutableList<String> cxxCompiler) {
    this.resolver = resolver;
    this.filesystem = filesystem;
    this.ocamlContext = ocamlContext;
    this.cCompilerEnvironment = cCompilerEnvironment;
    this.cCompiler = cCompiler;
    this.cxxCompilerEnvironment = cxxCompilerEnvironment;
    this.cxxCompiler = cxxCompiler;

    hasGeneratedSources =
        ocamlContext.getLexInput().size() > 0 || ocamlContext.getYaccInput().size() > 0;

    this.depToolStep =
        new OCamlDepToolStep(
            filesystem.getRootPath(),
            this.ocamlContext.getSourcePathResolver(),
            this.ocamlContext.getOcamlDepTool().get(),
            ocamlContext.getMLInput(),
            this.ocamlContext.getIncludeFlags(/* isBytecode */ false, /* excludeDeps */ true));
  }
Beispiel #23
0
  private int executeCCompilation(
      ExecutionContext context, ImmutableList.Builder<Path> linkerInputs)
      throws IOException, InterruptedException {

    ImmutableList.Builder<String> cCompileFlags = ImmutableList.builder();
    cCompileFlags.addAll(ocamlContext.getCCompileFlags());
    cCompileFlags.addAll(ocamlContext.getCommonCFlags());

    CxxPreprocessorInput cxxPreprocessorInput = ocamlContext.getCxxPreprocessorInput();

    for (SourcePath cSrc : ocamlContext.getCInput()) {
      Path outputPath = ocamlContext.getCOutput(resolver.getAbsolutePath(cSrc));
      linkerInputs.add(outputPath);
      Step compileStep =
          new OCamlCCompileStep(
              resolver,
              filesystem.getRootPath(),
              new OCamlCCompileStep.Args(
                  cCompilerEnvironment,
                  cCompiler,
                  ocamlContext.getOcamlCompiler().get(),
                  outputPath,
                  cSrc,
                  cCompileFlags.build(),
                  ImmutableMap.copyOf(cxxPreprocessorInput.getIncludes().getNameToPathMap())));
      int compileExitCode = compileStep.execute(context);
      if (compileExitCode != 0) {
        return compileExitCode;
      }
    }
    return 0;
  }
Beispiel #24
0
  private StepExecutionResult executeCCompilation(
      ExecutionContext context, ImmutableList.Builder<Path> linkerInputs)
      throws IOException, InterruptedException {

    ImmutableList.Builder<String> cCompileFlags = ImmutableList.builder();
    cCompileFlags.addAll(ocamlContext.getCCompileFlags());
    cCompileFlags.addAll(ocamlContext.getCommonCFlags());

    CxxPreprocessorInput cxxPreprocessorInput = ocamlContext.getCxxPreprocessorInput();

    for (SourcePath cSrc : ocamlContext.getCInput()) {
      Path outputPath = ocamlContext.getCOutput(resolver.getAbsolutePath(cSrc));
      linkerInputs.add(outputPath);
      Step compileStep =
          new OCamlCCompileStep(
              resolver,
              filesystem.getRootPath(),
              new OCamlCCompileStep.Args(
                  cCompilerEnvironment,
                  cCompiler,
                  ocamlContext.getOcamlCompiler().get(),
                  ocamlContext.getOCamlInteropIncludesDir(),
                  outputPath,
                  cSrc,
                  cCompileFlags.build(),
                  cxxPreprocessorInput.getIncludes()));
      StepExecutionResult compileExecutionResult = compileStep.execute(context);
      if (!compileExecutionResult.isSuccess()) {
        return compileExecutionResult;
      }
    }
    return StepExecutionResult.SUCCESS;
  }
 private ImmutableList<String> getExtraFlagsForHeaderMaps(ProjectFilesystem filesystem)
     throws IOException {
   // This works around OS X being amusing about the location of temp directories.
   return PREPROCESSOR_SUPPORTS_HEADER_MAPS
       ? ImmutableList.of("-I", filesystem.getBuckPaths().getBuckOut().toString())
       : ImmutableList.<String>of();
 }
Beispiel #26
0
  private ImmutableSortedSet<Path> getRecordedOutputDirsAndFiles() throws IOException {
    final ImmutableSortedSet.Builder<Path> paths = ImmutableSortedSet.naturalOrder();

    // Add files from output directories.
    for (final Path output : pathsToOutputs) {
      projectFilesystem.walkRelativeFileTree(
          output,
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException {
              paths.add(file);
              return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
                throws IOException {
              paths.add(dir);
              return FileVisitResult.CONTINUE;
            }
          });
    }

    return paths.build();
  }
  @Test
  public void shouldFindNeededDependenciesFromSymbols() throws IOException, InterruptedException {
    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(this, "symbol_finder", temporaryFolder);
    workspace.setUp();

    ProjectFilesystem projectFilesystem = new ProjectFilesystem(temporaryFolder.getRootPath());
    ImmutableMap<String, String> environment = ImmutableMap.copyOf(System.getenv());

    Config rawConfig =
        Config.createDefaultConfig(
            projectFilesystem.getRootPath(),
            ImmutableMap.<String, ImmutableMap<String, String>>of());
    BuckConfig config =
        new BuckConfig(
            rawConfig, projectFilesystem, Architecture.detect(), Platform.detect(), environment);
    ImmutableSet<Description<?>> allDescriptions =
        DefaultKnownBuildRuleTypes.getDefaultKnownBuildRuleTypes(projectFilesystem)
            .getAllDescriptions();
    BuckEventBus buckEventBus = BuckEventBusFactory.newInstance();

    MissingSymbolsHandler missingSymbolsHandler =
        MissingSymbolsHandler.create(
            projectFilesystem,
            allDescriptions,
            config,
            buckEventBus,
            new TestConsole(),
            DEFAULT_JAVAC_OPTIONS,
            environment);

    MissingSymbolEvent missingSymbolEvent =
        MissingSymbolEvent.create(
            BuildTargetFactory.newInstance(workspace.getDestPath(), "//java/com/example/b:b"),
            "com.example.a.A",
            MissingSymbolEvent.SymbolType.Java);

    ImmutableSetMultimap<BuildTarget, BuildTarget> neededDeps =
        missingSymbolsHandler.getNeededDependencies(ImmutableList.of(missingSymbolEvent));

    assertEquals(
        "MissingSymbolsHandler failed to find the needed dependency.",
        neededDeps,
        ImmutableSetMultimap.of(
            BuildTargetFactory.newInstance(workspace.getDestPath(), "//java/com/example/b:b"),
            BuildTargetFactory.newInstance(workspace.getDestPath(), "//java/com/example/a:a")));
  }
  @Test
  public void testDeleteFiles() throws IOException {
    ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmpDir.getRoot().toPath());

    String tracePath = String.format("%s/build.trace", BuckConstant.BUCK_TRACE_DIR);
    File traceFile = new File(tmpDir.getRoot(), tracePath);
    projectFilesystem.createParentDirs(tracePath);
    traceFile.createNewFile();
    traceFile.setLastModified(0);

    for (int i = 0; i < 10; ++i) {
      File oldResult =
          new File(
              tmpDir.getRoot(),
              String.format("%s/build.100%d.trace", BuckConstant.BUCK_TRACE_DIR, i));
      oldResult.createNewFile();
      oldResult.setLastModified(TimeUnit.SECONDS.toMillis(i));
    }

    ChromeTraceBuildListener listener =
        new ChromeTraceBuildListener(
            projectFilesystem,
            new FakeClock(1409702151000000000L),
            new ObjectMapper(),
            Locale.US,
            TimeZone.getTimeZone("America/Los_Angeles"),
            /* tracesToKeep */ 3,
            false);

    listener.deleteOldTraces();

    ImmutableList<String> files =
        FluentIterable.from(Arrays.asList(projectFilesystem.listFiles(BuckConstant.BUCK_TRACE_DIR)))
            .transform(
                new Function<File, String>() {
                  @Override
                  public String apply(File input) {
                    return input.getName();
                  }
                })
            .toList();
    assertEquals(4, files.size());
    assertEquals(
        ImmutableSortedSet.of(
            "build.trace", "build.1009.trace", "build.1008.trace", "build.1007.trace"),
        ImmutableSortedSet.copyOf(files));
  }
 private void createFiles(ProjectFilesystem filesystem, String... paths) throws IOException {
   Path root = filesystem.getRootPath();
   for (String path : paths) {
     Path resolved = root.resolve(path);
     Files.createDirectories(resolved.getParent());
     Files.write(resolved, "".getBytes(UTF_8));
   }
 }
  @Test
  public void testPackagedResourceOnIndividualFile() throws IOException {
    ProjectFilesystem filesystem = new FakeProjectFilesystem();
    PackagedResource packagedResource =
        PackagedResourceTestUtil.getPackagedResource(filesystem, "testdata/packaged_resource_one");

    assertThat(packagedResource.getFilenamePath().toString(), is("packaged_resource_one"));

    assertThat(
        packagedResource.getResourceIdentifier(),
        is(
            "com.facebook.buck.testutil.packaged_resource.PackagedResourceTestUtil"
                + "#testdata/packaged_resource_one"));

    String fileContent = filesystem.readFileIfItExists(packagedResource.get()).get();
    assertThat(fileContent, is("abc"));
  }