@Test
  public void sanitizeSymlinkedWorkingDirectory() throws IOException {
    TemporaryFolder folder = new TemporaryFolder();
    folder.create();

    // Setup up a symlink to our working directory.
    Path symlinkedRoot = folder.getRoot().toPath().resolve("symlinked-root");
    java.nio.file.Files.createSymbolicLink(symlinkedRoot, tmp.getRootPath());

    // Run the build, setting PWD to the above symlink.  Typically, this causes compilers to use
    // the symlinked directory, even though it's not the right project root.
    Map<String, String> envCopy = Maps.newHashMap(System.getenv());
    envCopy.put("PWD", symlinkedRoot.toString());
    workspace
        .runBuckCommandWithEnvironmentAndContext(
            tmp.getRootPath(),
            Optional.<NGContext>absent(),
            Optional.<BuckEventListener>absent(),
            Optional.of(ImmutableMap.copyOf(envCopy)),
            "build",
            "//:simple#default,static")
        .assertSuccess();

    // Verify that we still sanitized this path correctly.
    Path lib = workspace.getPath("buck-out/gen/simple#default,static/libsimple.a");
    String contents = Files.asByteSource(lib.toFile()).asCharSource(Charsets.ISO_8859_1).read();
    assertFalse(lib.toString(), contents.contains(tmp.getRootPath().toString()));
    assertFalse(lib.toString(), contents.contains(symlinkedRoot.toString()));

    folder.delete();
  }
  @Test
  public void binaryWithDependenciesCompilationDatabase() throws IOException {
    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(this, "compilation_database", tmp);
    workspace.setUp();
    Path compilationDatabase =
        workspace.buildAndReturnOutput("//:binary_with_dep#compilation-database");

    assertEquals(
        Paths.get("buck-out/gen/__binary_with_dep#compilation-database.json"),
        tmp.getRootPath().relativize(compilationDatabase));

    String binaryHeaderSymlinkTreeFolder =
        String.format(
            "buck-out/gen/binary_with_dep#default,%s",
            CxxDescriptionEnhancer.HEADER_SYMLINK_TREE_FLAVOR);
    String binaryExportedHeaderSymlinkTreeFoler =
        String.format(
            "buck-out/gen/library_with_header#default,%s",
            CxxDescriptionEnhancer.EXPORTED_HEADER_SYMLINK_TREE_FLAVOR);

    assertTrue(Files.exists(tmp.getRootPath().resolve(binaryHeaderSymlinkTreeFolder)));
    assertTrue(Files.exists(tmp.getRootPath().resolve(binaryExportedHeaderSymlinkTreeFoler)));

    String libraryExportedHeaderSymlinkTreeFoler =
        String.format(
            "buck-out/gen/library_with_header#default,%s",
            CxxDescriptionEnhancer.EXPORTED_HEADER_SYMLINK_TREE_FLAVOR);

    // Verify that symlink folders for headers are created and header file is linked.
    assertTrue(Files.exists(tmp.getRootPath().resolve(libraryExportedHeaderSymlinkTreeFoler)));
    assertTrue(
        Files.exists(tmp.getRootPath().resolve(libraryExportedHeaderSymlinkTreeFoler + "/bar.h")));

    Map<String, CxxCompilationDatabaseEntry> fileToEntry =
        CxxCompilationDatabaseEntry.parseCompilationDatabaseJsonFile(compilationDatabase);
    assertEquals(1, fileToEntry.size());
    assertHasEntry(
        fileToEntry,
        "foo.cpp",
        new ImmutableList.Builder<String>()
            .add(COMPILER_PATH)
            .add("-I")
            .add(headerSymlinkTreeIncludePath(binaryHeaderSymlinkTreeFolder))
            .add("-I")
            .add(headerSymlinkTreeIncludePath(binaryExportedHeaderSymlinkTreeFoler))
            .addAll(EXTRA_FLAGS_FOR_HEADER_MAPS)
            .addAll(COMPILER_SPECIFIC_FLAGS)
            .add("-x")
            .add("c++")
            .add("-c")
            .add("-o")
            .add("buck-out/gen/binary_with_dep#compile-foo.cpp.o,default/foo.cpp.o")
            .add("foo.cpp")
            .build());
  }
 @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);
 }
 @Test
 public void sanitizeWorkingDirectory() throws IOException {
   workspace.runBuckBuild("//:simple#default,static").assertSuccess();
   Path lib = workspace.getPath("buck-out/gen/simple#default,static/libsimple.a");
   String contents = Files.asByteSource(lib.toFile()).asCharSource(Charsets.ISO_8859_1).read();
   assertFalse(lib.toString(), contents.contains(tmp.getRootPath().toString()));
 }
  @Test
  public void testAppleLibraryBuildsFramework() throws Exception {
    assumeTrue(Platform.detect() == Platform.MACOS);
    assumeTrue(
        AppleNativeIntegrationTestUtils.isApplePlatformAvailable(
            ApplePlatform.builder().setName(ApplePlatform.Name.MACOSX).build()));

    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(
            this, "apple_library_builds_something", tmp);
    workspace.setUp();

    ProjectWorkspace.ProcessResult result =
        workspace.runBuckCommand(
            "build", "//Libraries/TestLibrary:TestLibrary#framework,macosx-x86_64");
    result.assertSuccess();

    Path frameworkPath =
        tmp.getRootPath()
            .resolve(BuckConstant.GEN_DIR)
            .resolve(
                "Libraries/TestLibrary/TestLibrary#framework,macosx-x86_64/TestLibrary.framework");
    assertThat(Files.exists(frameworkPath), is(true));
    assertThat(Files.exists(frameworkPath.resolve("Contents/Info.plist")), is(true));
    Path libraryPath = frameworkPath.resolve("Contents/MacOS/TestLibrary");
    assertThat(Files.exists(libraryPath), is(true));
    assertThat(
        workspace.runCommand("file", libraryPath.toString()).getStdout().get(),
        containsString("dynamically linked shared library"));
  }
  @Test
  public void testAppleLibraryExportedHeaderSymlinkTree() throws IOException {
    assumeTrue(Platform.detect() == Platform.MACOS);

    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(
            this, "apple_library_header_symlink_tree", tmp);
    workspace.setUp();

    BuildTarget buildTarget =
        BuildTargetFactory.newInstance(
            "//Libraries/TestLibrary:TestLibrary#"
                + "default,"
                + CxxDescriptionEnhancer.EXPORTED_HEADER_SYMLINK_TREE_FLAVOR);
    ProjectWorkspace.ProcessResult result =
        workspace.runBuckCommand("build", buildTarget.getFullyQualifiedName());
    result.assertSuccess();

    Path projectRoot = tmp.getRootPath().toRealPath();

    Path inputPath = projectRoot.resolve(buildTarget.getBasePath());
    Path outputPath = projectRoot.resolve(BuildTargets.getGenPath(buildTarget, "%s"));

    assertIsSymbolicLink(
        outputPath.resolve("TestLibrary/PublicHeader.h"), inputPath.resolve("PublicHeader.h"));
  }
  @Test
  public void usesSecondCache() throws IOException {
    Path path = Paths.get("world.txt");
    Path fullPath = tmp2.getRootPath().resolve(path);

    DefaultFileHashCache innerCache =
        new DefaultFileHashCache(new ProjectFilesystem(tmp.getRootPath()));

    // The second project filesystem has the file.
    ProjectFilesystem filesystem2 = new ProjectFilesystem(tmp2.getRootPath());
    DefaultFileHashCache innerCache2 = new DefaultFileHashCache(filesystem2);
    filesystem2.touch(path);

    StackedFileHashCache cache =
        new StackedFileHashCache(ImmutableList.of(innerCache, innerCache2));
    cache.get(fullPath);
    assertTrue(innerCache2.willGet(path));
  }
 private void assertHasEntry(
     Map<String, CxxCompilationDatabaseEntry> fileToEntry, String fileName, List<String> command)
     throws IOException {
   String key = tmp.getRootPath().toRealPath().resolve(fileName).toString();
   CxxCompilationDatabaseEntry entry = fileToEntry.get(key);
   assertNotNull("There should be an entry for " + key + ".", entry);
   MoreAsserts.assertIterablesEquals(command, entry.args);
   assertEquals(
       Joiner.on(' ').join(Iterables.transform(command, Escaper.SHELL_ESCAPER)), entry.command);
 }
 @Before
 public void enableVerboseRuleKeys() throws Exception {
   lastPositionInLog = 0;
   ruleKeyBuilderLogger = Logger.getLogger(RuleKeyBuilder.class.getName());
   previousRuleKeyBuilderLevel = ruleKeyBuilderLogger.getLevel();
   ruleKeyBuilderLogger.setLevel(Level.FINER);
   Path fullLogFilePath = tmp.getRootPath().resolve(LOG_FILE_PATH);
   Files.createDirectories(fullLogFilePath.getParent());
   FileHandler handler = new FileHandler(fullLogFilePath.toString());
   handler.setFormatter(new LogFormatter());
   ruleKeyBuilderLogger.addHandler(handler);
 }
 private ProcessExecutor.Result runRuleKeyDiffer(ProjectWorkspace workspace)
     throws IOException, InterruptedException {
   ProcessExecutor.Result result =
       workspace.runCommand(
           "python2.7",
           Paths.get("scripts", "diff_rulekeys.py").toString(),
           tmp.getRootPath().resolve("buck-0.log").toString(),
           tmp.getRootPath().resolve("buck-1.log").toString(),
           "//:java_lib_2");
   assertThat(result.getStderr(), Matchers.equalTo(Optional.of("")));
   assertThat(result.getExitCode(), Matchers.is(0));
   return result;
 }
  @Before
  public void setUp() throws IOException, InterruptedException {
    executorService = Executors.newScheduledThreadPool(5);
    // In case root_restrict_files is enabled in /etc/watchmanconfig, assume
    // this is one of the entries so it doesn't give up.
    tmp.newFolder(".git");
    Watchman watchman =
        Watchman.build(tmp.getRootPath(), getWatchmanEnv(), new TestConsole(), new FakeClock(0));

    // We assume watchman has been installed and configured properly on the system, and that setting
    // up the watch is successful.
    assumeFalse(watchman == Watchman.NULL_WATCHMAN);
  }
  @Test
  public void testAppleLibraryBuildsSomething() throws IOException {
    assumeTrue(Platform.detect() == Platform.MACOS);
    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(
            this, "apple_library_builds_something", tmp);
    workspace.setUp();

    ProjectWorkspace.ProcessResult result =
        workspace.runBuckCommand("build", "//Libraries/TestLibrary:TestLibrary#static,default");
    result.assertSuccess();

    assertTrue(Files.exists(tmp.getRootPath().resolve(BuckConstant.GEN_DIR)));
  }
  @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 testAppleLibraryBuildsForWatchSimulator() throws IOException {
    assumeTrue(
        AppleNativeIntegrationTestUtils.isApplePlatformAvailable(
            ApplePlatform.builder().setName(ApplePlatform.Name.WATCHSIMULATOR).build()));

    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(
            this, "apple_library_builds_something", tmp);
    workspace.setUp();

    ProjectWorkspace.ProcessResult result =
        workspace.runBuckCommand(
            "build", "//Libraries/TestLibrary:TestLibrary#watchsimulator-i386,static");
    result.assertSuccess();

    assertTrue(Files.exists(tmp.getRootPath().resolve(BuckConstant.GEN_DIR)));
  }
  @Test
  public void testAppleLibraryBuildsSomethingUsingAppleCxxPlatform() throws IOException {
    assumeTrue(Platform.detect() == Platform.MACOS);
    assumeTrue(
        AppleNativeIntegrationTestUtils.isApplePlatformAvailable(
            ApplePlatform.builder().setName(ApplePlatform.Name.MACOSX).build()));

    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(
            this, "apple_library_builds_something", tmp);
    workspace.setUp();

    ProjectWorkspace.ProcessResult result =
        workspace.runBuckCommand(
            "build", "//Libraries/TestLibrary:TestLibrary#static,macosx-x86_64");
    result.assertSuccess();

    assertTrue(Files.exists(tmp.getRootPath().resolve(BuckConstant.GEN_DIR)));
  }
 private ProjectFilesystem createProjectFilesystem() {
   return new ProjectFilesystem(tmp.getRootPath());
 }
 private Path createPath(String first, String... more) {
   return tmpFolder.getRootPath().getFileSystem().getPath(first, more);
 }