Example #1
0
  @Test
  public void testVerbose10AddsVerboseFlagToDx() {
    // Context with --verbose 10.
    ExecutionContext context = createExecutionContext(10);
    Function<Path, Path> pathAbsolutifier = context.getProjectFilesystem().getAbsolutifier();

    DxStep dx = new DxStep(SAMPLE_OUTPUT_PATH, SAMPLE_FILES_TO_DEX);

    String expected =
        String.format(
            "%s --statistics --verbose --output %s %s",
            EXPECTED_DX_PREFIX,
            SAMPLE_OUTPUT_PATH,
            Joiner.on(' ').join(Iterables.transform(SAMPLE_FILES_TO_DEX, pathAbsolutifier)));
    MoreAsserts.assertShellCommands(
        "Ensure that the --statistics flag is present.",
        ImmutableList.of(expected),
        ImmutableList.<Step>of(dx),
        context);

    assertTrue(
        "Should print stdout since `dx --verbose` is enabled.",
        dx.shouldPrintStdout(context.getVerbosity()));
    assertTrue(
        "Should print stdout since `dx --verbose` is enabled.",
        dx.shouldPrintStderr(context.getVerbosity()));
    verifyAll();
  }
Example #2
0
  @Test
  public void testDxCommandNoOptimizeForceJumbo() {
    // Context with --verbose 2.
    ExecutionContext context = createExecutionContext(2);
    Function<Path, Path> pathAbsolutifier = context.getProjectFilesystem().getAbsolutifier();

    DxStep dx =
        new DxStep(
            SAMPLE_OUTPUT_PATH,
            SAMPLE_FILES_TO_DEX,
            EnumSet.of(DxStep.Option.NO_OPTIMIZE, DxStep.Option.FORCE_JUMBO));

    String expected =
        String.format(
            "%s --no-optimize --force-jumbo --output %s %s",
            EXPECTED_DX_PREFIX,
            SAMPLE_OUTPUT_PATH,
            Joiner.on(' ').join(Iterables.transform(SAMPLE_FILES_TO_DEX, pathAbsolutifier)));
    MoreAsserts.assertShellCommands(
        "Both --no-optimize and --force-jumbo should be present.",
        ImmutableList.of(expected),
        ImmutableList.<Step>of(dx),
        context);
    verifyAll();
  }
Example #3
0
  @Test
  public void testIsTestRunRequiredForTestBuiltLocally()
      throws IOException, ExecutionException, InterruptedException {
    ExecutionContext executionContext = createMock(ExecutionContext.class);
    expect(executionContext.isDebugEnabled()).andReturn(false);

    FakeTestRule testRule =
        new FakeTestRule(
            ImmutableSet.<Label>of(Label.of("windows")),
            BuildTargetFactory.newInstance("//:lulz"),
            new SourcePathResolver(new BuildRuleResolver()),
            ImmutableSortedSet.<BuildRule>of());

    CachingBuildEngine cachingBuildEngine = createMock(CachingBuildEngine.class);
    BuildResult result = new BuildResult(testRule, BUILT_LOCALLY, CacheResult.skip());
    expect(cachingBuildEngine.getBuildRuleResult(BuildTargetFactory.newInstance("//:lulz")))
        .andReturn(result);
    replay(executionContext, cachingBuildEngine);

    assertTrue(
        "A test built locally should always run regardless of any cached result. ",
        TestRunning.isTestRunRequiredForTest(
            testRule,
            cachingBuildEngine,
            executionContext,
            createMock(TestRuleKeyFileHelper.class),
            /* results cache enabled */ true,
            /* running with test selectors */ false));

    verify(executionContext, cachingBuildEngine);
  }
Example #4
0
  @Test
  public void testUseCustomDxOptionWithNullSupplier() {
    // Context with --verbose 2.
    ExecutionContext context = createExecutionContext(2);
    Function<Path, Path> pathAbsolutifier = context.getProjectFilesystem().getAbsolutifier();

    DxStep dx =
        new DxStep(
            SAMPLE_OUTPUT_PATH,
            SAMPLE_FILES_TO_DEX,
            EnumSet.of(Option.USE_CUSTOM_DX_IF_AVAILABLE),
            new Supplier<String>() {
              @Override
              public String get() {
                return null;
              }
            });

    String expected =
        String.format(
            "%s --output %s %s",
            EXPECTED_DX_PREFIX,
            SAMPLE_OUTPUT_PATH,
            Joiner.on(' ').join(Iterables.transform(SAMPLE_FILES_TO_DEX, pathAbsolutifier)));
    MoreAsserts.assertShellCommands(
        "Should fall back to /usr/bin/dx even though USE_CUSTOM_DX_IF_AVAILABLE is used.",
        ImmutableList.of(expected),
        ImmutableList.<Step>of(dx),
        context);
    verifyAll();
  }
Example #5
0
  @Test
  public void testIsTestRunRequiredForTestBuiltFromCacheIfHasTestResultFiles()
      throws IOException, ExecutionException, InterruptedException {
    ExecutionContext executionContext = createMock(ExecutionContext.class);
    expect(executionContext.isDebugEnabled()).andReturn(false);

    FakeTestRule testRule =
        new FakeTestRule(
            ImmutableSet.<Label>of(Label.of("windows")),
            BuildTargetFactory.newInstance("//:lulz"),
            new SourcePathResolver(new BuildRuleResolver()),
            ImmutableSortedSet.<BuildRule>of());

    CachingBuildEngine cachingBuildEngine = createMock(CachingBuildEngine.class);
    BuildResult result = new BuildResult(testRule, FETCHED_FROM_CACHE, CacheResult.hit("dir"));
    expect(cachingBuildEngine.getBuildRuleResult(BuildTargetFactory.newInstance("//:lulz")))
        .andReturn(result);
    replay(executionContext, cachingBuildEngine);

    assertTrue(
        "A cache hit updates the build artifact but not the test results. "
            + "Therefore, the test should be re-run to ensure the test results are up to date.",
        TestRunning.isTestRunRequiredForTest(
            testRule,
            cachingBuildEngine,
            executionContext,
            createMock(TestRuleKeyFileHelper.class),
            /* results cache enabled */ true,
            /* running with test selectors */ false));

    verify(executionContext, cachingBuildEngine);
  }
Example #6
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);
  }
Example #8
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;
 }
Example #9
0
 @Override
 public int execute(ExecutionContext context) {
   try (InputStream sourceStream = source.openStream()) {
     context
         .getProjectFilesystem()
         .copyToPath(sourceStream, outputPath, StandardCopyOption.REPLACE_EXISTING);
     return 0;
   } catch (IOException e) {
     LOG.error(e, "Couldn't copy bytes to %s", outputPath);
     e.printStackTrace(context.getStdErr());
     return 1;
   }
 }
Example #10
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;
  }
Example #11
0
 @Override
 public int execute(ExecutionContext context) {
   try {
     if (shouldRecurse) {
       context.getProjectFilesystem().copyFolder(source, destination);
     } else {
       context.getProjectFilesystem().copyFile(source, destination);
     }
     return 0;
   } catch (IOException e) {
     context.logError(e, "Failed when trying to copy: %s", getDescription(context));
     return 1;
   }
 }
  @Test
  public void testIsTestRunRequiredForTestInDebugMode() throws IOException {
    ExecutionContext executionContext = createMock(ExecutionContext.class);
    expect(executionContext.isDebugEnabled()).andReturn(true);

    replay(executionContext);

    assertTrue(
        "In debug mode, test should always run regardless of any cached results since "
            + "the user is expecting to hook up a debugger.",
        TestCommand.isTestRunRequiredForTest(
            createMock(TestRule.class), executionContext, createMock(TestRuleKeyFileHelper.class)));

    verify(executionContext);
  }
  @Override
  public int execute(ExecutionContext context) {
    File inputDirectory = inputDirectoryPath.toFile();
    Preconditions.checkState(
        inputDirectory.exists() && inputDirectory.isDirectory(),
        "%s must be a directory.",
        inputDirectoryPath);

    try {
      ImmutableMap.Builder<File, ZipEntry> zipEntriesBuilder = ImmutableMap.builder();
      addDirectoryToZipEntryList(inputDirectory, "", zipEntriesBuilder);
      ImmutableMap<File, ZipEntry> zipEntries = zipEntriesBuilder.build();

      if (!zipEntries.isEmpty()) {
        try (CustomZipOutputStream outputStream =
            ZipOutputStreams.newOutputStream(outputZipPath.toFile())) {
          for (Map.Entry<File, ZipEntry> zipEntry : zipEntries.entrySet()) {
            outputStream.putNextEntry(zipEntry.getValue());
            ByteStreams.copy(Files.newInputStreamSupplier(zipEntry.getKey()), outputStream);
            outputStream.closeEntry();
          }
        }
      }
    } catch (IOException e) {
      e.printStackTrace(context.getStdErr());
      return 1;
    }
    return 0;
  }
Example #14
0
  @Test
  public void testShouldIncludeDxInEnvironmentIfPresent() {
    File fakeDx = new File("."); // We do no checks on whether dx is executable, but it must exist
    AndroidPlatformTarget android = EasyMock.createNiceMock(AndroidPlatformTarget.class);
    EasyMock.expect(android.getDxExecutable()).andStubReturn(fakeDx);
    EasyMock.replay(android);

    Genrule rule =
        Genrule.newGenruleBuilder(new FakeAbstractBuildRuleBuilderParams())
            .setBuildTarget(BuildTargetFactory.newInstance("//example:genrule"))
            .setBash(Optional.of("true"))
            .setOut("/dev/null")
            .build(new BuildRuleResolver());

    ExecutionContext context =
        ExecutionContext.builder()
            .setConsole(new TestConsole())
            .setProjectFilesystem(new ProjectFilesystem(new File(".")))
            .setAndroidPlatformTarget(Optional.of(android))
            .setEventBus(BuckEventBusFactory.newInstance())
            .setPlatform(Platform.detect())
            .build();

    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
    rule.addEnvironmentVariables(context, builder);
    ImmutableMap<String, String> env = builder.build();

    assertEquals(fakeDx.getAbsolutePath(), env.get("DX"));

    EasyMock.verify(android);
  }
Example #15
0
  /**
   * @param androidSdkDir where the user's Android SDK is installed.
   * @param buildDependencies How to include dependencies when building rules.
   */
  public Build(
      DependencyGraph dependencyGraph,
      Optional<File> androidSdkDir,
      Optional<File> ndkRoot,
      ProjectFilesystem projectFilesystem,
      ArtifactCache artifactCache,
      ListeningExecutorService listeningExecutorService,
      JavaPackageFinder javaPackageFinder,
      Console console,
      long defaultTestTimeoutMillis,
      boolean isCodeCoverageEnabled,
      boolean isDebugEnabled,
      BuildDependencies buildDependencies) {
    this.dependencyGraph = Preconditions.checkNotNull(dependencyGraph);

    Optional<AndroidPlatformTarget> androidPlatformTarget =
        findAndroidPlatformTarget(dependencyGraph, androidSdkDir, console.getStdErr());
    this.executionContext =
        ExecutionContext.builder()
            .setProjectFilesystem(projectFilesystem)
            .setConsole(console)
            .setAndroidPlatformTarget(androidPlatformTarget)
            .setNdkRoot(ndkRoot)
            .setDefaultTestTimeoutMillis(defaultTestTimeoutMillis)
            .setCodeCoverageEnabled(isCodeCoverageEnabled)
            .setDebugEnabled(isDebugEnabled)
            .build();
    this.artifactCache = Preconditions.checkNotNull(artifactCache);
    this.stepRunner = new DefaultStepRunner(executionContext, listeningExecutorService);
    this.javaPackageFinder = Preconditions.checkNotNull(javaPackageFinder);
    this.buildDependencies = Preconditions.checkNotNull(buildDependencies);
  }
Example #16
0
  @Override
  public String getDescription(ExecutionContext context) {
    ImmutableList.Builder<String> args = ImmutableList.builder();
    args.add("unzip");

    Verbosity verbosity = context.getVerbosity();
    if (!verbosity.shouldUseVerbosityFlagIfAvailable()) {
      if (verbosity.shouldPrintStandardInformation()) {
        args.add("-q");
      } else {
        args.add("-qq");
      }
    }

    // overwrite existing files without prompting
    if (overwriteExistingFiles) {
      args.add("-o");
    }

    // output directory
    args.add("-d").add(pathToDestinationDirectory);

    // file to unzip
    args.add(pathToZipFile);

    // specific files within the archive to unzip -- if empty, extract all
    args.addAll(filesToExtract);

    return Joiner.on(" ").join(args.build());
  }
Example #17
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();
  }
Example #18
0
 @VisibleForTesting
 static boolean isTestRunRequiredForTest(
     TestRule test,
     BuildEngine cachingBuildEngine,
     ExecutionContext executionContext,
     TestRuleKeyFileHelper testRuleKeyFileHelper,
     boolean isResultsCacheEnabled,
     boolean isRunningWithTestSelectors)
     throws IOException, ExecutionException, InterruptedException {
   boolean isTestRunRequired;
   BuildResult result;
   if (executionContext.isDebugEnabled()) {
     // If debug is enabled, then we should always run the tests as the user is expecting to
     // hook up a debugger.
     isTestRunRequired = true;
   } else if (isRunningWithTestSelectors) {
     // As a feature to aid developers, we'll assume that when we are using test selectors,
     // we should always run each test (and never look at the cache.)
     // TODO(user) When #3090004 and #3436849 are closed we can respect the cache again.
     isTestRunRequired = true;
   } else if (((result = cachingBuildEngine.getBuildRuleResult(test.getBuildTarget())) != null)
       && result.getSuccess() == BuildRuleSuccessType.MATCHING_RULE_KEY
       && isResultsCacheEnabled
       && test.hasTestResultFiles(executionContext)
       && testRuleKeyFileHelper.isRuleKeyInDir(test)) {
     // If this build rule's artifacts (which includes the rule's output and its test result
     // files) are up to date, then no commands are necessary to run the tests. The test result
     // files will be read from the XML files in interpretTestResults().
     isTestRunRequired = false;
   } else {
     isTestRunRequired = true;
   }
   return isTestRunRequired;
 }
Example #19
0
  @Override
  public int execute(ExecutionContext context) {
    List<String> lines = Lists.newArrayList();
    // Run with -e so the script will fail if any of the steps fail.
    lines.add("#!/bin/sh");
    lines.add("set -e");

    // Create a tmp directory that will be deleted when this script exits.
    lines.add("BUCK_PROJECT_ROOT=`mktemp -d -t sh_binary.XXXXXXXXXX`");
    lines.add(
        "trap \"chmod -R 755 $BUCK_PROJECT_ROOT "
            + "&& rm -rf $BUCK_PROJECT_ROOT\" EXIT HUP INT TERM");

    // Navigate to the tmp directory.
    lines.add("cd $BUCK_PROJECT_ROOT");

    // Symlink the resources to the $BUCK_PROJECT_ROOT directory.
    Function<String, String> pathRelativizer = context.getProjectFilesystem().getPathRelativizer();
    createSymlinkCommands(resources, pathRelativizer, lines);

    // Make everything in $BUCK_PROJECT_ROOT read-only.
    lines.add("find $BUCK_PROJECT_ROOT -type d -exec chmod 555 {} \\;");
    lines.add("find $BUCK_PROJECT_ROOT -type f -exec chmod 444 {} \\;");

    // Forward the args to this generated script to scriptToRun and execute it.
    lines.add(
        String.format(
            "BUCK_PROJECT_ROOT=$BUCK_PROJECT_ROOT %s \"$@\"",
            pathRelativizer.apply(scriptToRun.toString())));

    // Write the contents to the file.
    File output = context.getProjectFilesystem().getFileForRelativePath(outputFile.toString());
    try {
      Files.write(Joiner.on('\n').join(lines) + '\n', output, Charsets.UTF_8);
    } catch (IOException e) {
      e.printStackTrace(context.getStdErr());
      return 1;
    }

    // Make sure the file is executable.
    if (output.setExecutable(/* executable */ true, /* ownerOnly */ false)) {
      return 0;
    } else {
      context.getConsole().printErrorText("Failed to set file as executable: " + output);
      return 1;
    }
  }
  @Test
  public void testIsTestRunRequiredForTestBuiltLocally() throws IOException {
    ExecutionContext executionContext = createMock(ExecutionContext.class);
    expect(executionContext.isDebugEnabled()).andReturn(false);

    TestRule testRule = createMock(TestRule.class);
    expect(testRule.getBuildResultType()).andReturn(BuildRuleSuccess.Type.BUILT_LOCALLY);

    replay(executionContext, testRule);

    assertTrue(
        "A test built locally should always run regardless of any cached result. ",
        TestCommand.isTestRunRequiredForTest(
            testRule, executionContext, createMock(TestRuleKeyFileHelper.class)));

    verify(executionContext, testRule);
  }
Example #21
0
 @Override
 public int execute(ExecutionContext context) {
   try {
     return doExecute(context);
   } catch (Exception e) {
     context.logError(e, "There was an error filtering resources.");
     return 1;
   }
 }
  @Test
  public void testIsTestRunRequiredForTestBuiltFromCacheIfHasTestResultFiles() throws IOException {
    ExecutionContext executionContext = createMock(ExecutionContext.class);
    expect(executionContext.isDebugEnabled()).andReturn(false);

    TestRule testRule = createMock(TestRule.class);
    expect(testRule.getBuildResultType()).andReturn(BuildRuleSuccess.Type.FETCHED_FROM_CACHE);

    replay(executionContext, testRule);

    assertTrue(
        "A cache hit updates the build artifact but not the test results. "
            + "Therefore, the test should be re-run to ensure the test results are up to date.",
        TestCommand.isTestRunRequiredForTest(
            testRule, executionContext, createMock(TestRuleKeyFileHelper.class)));

    verify(executionContext, testRule);
  }
  @Test
  public void shouldUseSpecifiedJavacJar() throws Exception {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    BuildRule rule = new FakeBuildRule("//:fake", pathResolver);
    resolver.addToIndex(rule);

    Path fakeJavacJar = Paths.get("ae036e57-77a7-4356-a79c-0f85b1a3290d", "fakeJavac.jar");
    ExecutionContext executionContext = TestExecutionContext.newInstance();
    MockClassLoader mockClassLoader =
        new MockClassLoader(
            ClassLoader.getSystemClassLoader(),
            ImmutableMap.<String, Class<?>>of(
                "com.sun.tools.javac.api.JavacTool", MockJavac.class));
    executionContext
        .getClassLoaderCache()
        .injectClassLoader(
            ClassLoader.getSystemClassLoader(),
            ImmutableList.of(fakeJavacJar.toUri().toURL()),
            mockClassLoader);

    Jsr199Javac javac = createJavac(/* withSyntaxError */ false, Optional.of(fakeJavacJar));

    boolean caught = false;

    try {
      javac.buildWithClasspath(
          executionContext,
          createProjectFilesystem(),
          PATH_RESOLVER,
          BuildTargetFactory.newInstance("//some:example"),
          ImmutableList.<String>of(),
          SOURCE_PATHS,
          Optional.of(pathToSrcsList),
          Optional.<Path>absent());
      fail("Did not expect compilation to succeed");
    } catch (UnsupportedOperationException ex) {
      if (ex.toString().contains("abcdef")) {
        caught = true;
      }
    }

    assertTrue("mock Java compiler should throw", caught);
  }
Example #24
0
  public ListenableFuture<List<BuildRuleSuccess>> executeBuild(
      EventBus events, Set<BuildRule> rulesToBuild) throws IOException, StepFailedException {
    buildContext =
        BuildContext.builder()
            .setProjectRoot(executionContext.getProjectDirectoryRoot())
            .setDependencyGraph(dependencyGraph)
            .setStepRunner(stepRunner)
            .setProjectFilesystem(executionContext.getProjectFilesystem())
            .setArtifactCache(artifactCache)
            .setJavaPackageFinder(javaPackageFinder)
            .setEventBus(events)
            .setAndroidBootclasspathForAndroidPlatformTarget(
                executionContext.getAndroidPlatformTargetOptional())
            .setBuildDependencies(buildDependencies)
            .setConsole(executionContext.getConsole())
            .build();

    return Builder.getInstance().buildRules(rulesToBuild, buildContext);
  }
Example #25
0
 @Override
 public int execute(ExecutionContext context) {
   try {
     extractZipFile(
         pathToZipFile, pathToDestinationDirectory, filesToExtract, overwriteExistingFiles);
   } catch (IOException e) {
     e.printStackTrace(context.getStdErr());
     return 1;
   }
   return 0;
 }
Example #26
0
  @Test
  public void testIsTestRunRequiredIfRuleKeyNotPresent()
      throws IOException, ExecutionException, InterruptedException {
    ExecutionContext executionContext = createMock(ExecutionContext.class);
    expect(executionContext.isDebugEnabled()).andReturn(false);

    FakeTestRule testRule =
        new FakeTestRule(
            ImmutableSet.<Label>of(Label.of("windows")),
            BuildTargetFactory.newInstance("//:lulz"),
            new SourcePathResolver(new BuildRuleResolver()),
            ImmutableSortedSet.<BuildRule>of()) {

          @Override
          public boolean hasTestResultFiles(ExecutionContext context) {
            return true;
          }
        };

    TestRuleKeyFileHelper testRuleKeyFileHelper = createNiceMock(TestRuleKeyFileHelper.class);
    expect(testRuleKeyFileHelper.isRuleKeyInDir(testRule)).andReturn(false);

    CachingBuildEngine cachingBuildEngine = createMock(CachingBuildEngine.class);
    BuildResult result = new BuildResult(testRule, MATCHING_RULE_KEY, CacheResult.skip());
    expect(cachingBuildEngine.getBuildRuleResult(BuildTargetFactory.newInstance("//:lulz")))
        .andReturn(result);
    replay(executionContext, cachingBuildEngine, testRuleKeyFileHelper);

    assertTrue(
        "A cached build should run the tests if the test output directory\'s rule key is not "
            + "present or does not matche the rule key for the test.",
        TestRunning.isTestRunRequiredForTest(
            testRule,
            cachingBuildEngine,
            executionContext,
            testRuleKeyFileHelper,
            /* results cache enabled */ true,
            /* running with test selectors */ false));

    verify(executionContext, cachingBuildEngine, testRuleKeyFileHelper);
  }
  @Test
  public void testIsTestRunRequiredIfRuleKeyNotPresent() throws IOException {
    ExecutionContext executionContext = createMock(ExecutionContext.class);
    expect(executionContext.isDebugEnabled()).andReturn(false);

    TestRule testRule = createNiceMock(TestRule.class);
    expect(testRule.getBuildResultType()).andReturn(BuildRuleSuccess.Type.MATCHING_RULE_KEY);
    expect(testRule.hasTestResultFiles(executionContext)).andReturn(true);

    TestRuleKeyFileHelper testRuleKeyFileHelper = createNiceMock(TestRuleKeyFileHelper.class);
    expect(testRuleKeyFileHelper.isRuleKeyInDir(testRule)).andReturn(false);

    replay(executionContext, testRule, testRuleKeyFileHelper);

    assertTrue(
        "A cached build should run the tests if the test output directory\'s rule key is not "
            + "present or does not matche the rule key for the test.",
        TestCommand.isTestRunRequiredForTest(testRule, executionContext, testRuleKeyFileHelper));

    verify(executionContext, testRule, testRuleKeyFileHelper);
  }
Example #28
0
  @Test
  public void testNonObfuscatedBuild() throws IOException {
    Path proguardConfigFile = Paths.get("the/configuration.txt");
    Path proguardMappingFile = Paths.get("the/mapping.txt");
    SplitZipStep splitZipStep =
        new SplitZipStep(
            /* inputPathsToSplit */ ImmutableSet.<Path>of(),
            /* secondaryJarMetaPath */ Paths.get(""),
            /* primaryJarPath */ Paths.get(""),
            /* secondaryJarDir */ Paths.get(""),
            /* secondaryJarPattern */ "",
            /* proguardFullConfigFile */ Optional.of(proguardConfigFile),
            /* proguardMappingFile */ Optional.of(proguardMappingFile),
            /* primaryDexPatterns */ ImmutableSet.<String>of("primary"),
            /* primaryDexClassesFile */ Optional.<Path>absent(),
            ZipSplitter.DexSplitStrategy.MAXIMIZE_PRIMARY_DEX_SIZE,
            DexStore.JAR,
            /* pathToReportDir */ Paths.get(""),
            /* useLinearAllocSplitDex */ true,
            /* linearAllocHardLimit */ 4 * 1024 * 1024);

    ProjectFilesystem projectFilesystem = EasyMock.createMock(ProjectFilesystem.class);
    EasyMock.expect(projectFilesystem.readLines(proguardConfigFile))
        .andReturn(ImmutableList.<String>of("-dontobfuscate"));
    ExecutionContext context = EasyMock.createMock(ExecutionContext.class);
    EasyMock.expect(context.getProjectFilesystem()).andReturn(projectFilesystem).anyTimes();
    EasyMock.replay(projectFilesystem, context);

    Predicate<String> requiredInPrimaryZipPredicate =
        splitZipStep.createRequiredInPrimaryZipPredicate(context);
    assertTrue(
        "Primary class should be in primary.",
        requiredInPrimaryZipPredicate.apply("primary.class"));
    assertFalse(
        "Secondary class should be in secondary.",
        requiredInPrimaryZipPredicate.apply("secondary.class"));

    EasyMock.verify(projectFilesystem, context);
  }
Example #29
0
  private ExitCodeAndOutput processJsonConfig(File jsonTempFile, boolean generateMinimalProject)
      throws IOException {
    ImmutableList.Builder<String> argsBuilder =
        ImmutableList.<String>builder()
            .add(pythonInterpreter)
            .add(PATH_TO_INTELLIJ_PY)
            .add(jsonTempFile.getAbsolutePath());

    if (generateMinimalProject) {
      argsBuilder.add("--generate_minimum_project");
    }

    final ImmutableList<String> args = argsBuilder.build();

    ShellStep command =
        new ShellStep() {

          @Override
          public String getShortName() {
            return "python";
          }

          @Override
          protected ImmutableList<String> getShellCommandInternal(ExecutionContext context) {
            return args;
          }
        };

    Console console = executionContext.getConsole();
    Console childConsole =
        new Console(Verbosity.SILENT, console.getStdOut(), console.getStdErr(), Ansi.withoutTty());
    ExecutionContext childContext =
        ExecutionContext.builder()
            .setExecutionContext(executionContext)
            .setConsole(childConsole)
            .build();
    int exitCode = command.execute(childContext);
    return new ExitCodeAndOutput(exitCode, command.getStdout(), command.getStderr());
  }
  public ExopackageInstaller(
      ExecutionContext context, AdbHelper adbHelper, InstallableApk apkRule) {
    this.adbHelper = adbHelper;
    this.projectFilesystem = apkRule.getProjectFilesystem();
    this.eventBus = context.getBuckEventBus();
    this.apkRule = apkRule;
    this.packageName = AdbHelper.tryToExtractPackageNameFromManifest(apkRule);
    this.dataRoot = Paths.get("/data/local/tmp/exopackage/").resolve(packageName);

    Preconditions.checkArgument(AdbHelper.PACKAGE_NAME_PATTERN.matcher(packageName).matches());

    Optional<ExopackageInfo> exopackageInfo = apkRule.getExopackageInfo();
    Preconditions.checkArgument(exopackageInfo.isPresent());
    this.exopackageInfo = exopackageInfo.get();
  }