blob: 432ab3bb9b9d936c3cb6625dbf48aed5ddab773f [file] [log] [blame]
/*
* Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.java;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.java.abi.AbiWriterProtocol;
import com.facebook.buck.testutil.integration.ProjectWorkspace;
import com.facebook.buck.testutil.integration.ProjectWorkspace.ProcessResult;
import com.facebook.buck.testutil.integration.TestDataHelper;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
/**
* Integration test that verifies that a {@link DefaultJavaLibraryRule} writes its ABI key as part
* of compilation.
*/
public class DefaultJavaLibraryRuleIntegrationTest {
@Rule public TemporaryFolder tmp = new TemporaryFolder();
private ProjectWorkspace workspace;
@Test
public void testBuildJavaLibraryWithoutSrcsAndVerifyAbi() throws IOException {
workspace = TestDataHelper.createProjectWorkspaceForScenario(
this, "abi", tmp);
workspace.setUp();
// Run `buck build`.
ProcessResult buildResult = workspace.runBuckCommand("build", "//:no_srcs");
assertEquals("Successful build should exit with 0.", 0, buildResult.getExitCode());
// This verifies that the ABI key was written correctly.
workspace.verify();
// Verify the build cache.
File buildCache = workspace.getFile("cache_dir");
assertTrue(buildCache.isDirectory());
assertEquals("There should be two entries in the build cache.",
2,
buildCache.listFiles().length);
// Verify the ABI key entry in the build cache.
File[] cacheEntries = buildCache.listFiles();
File abiKeyEntry = cacheEntries[0].length() == 41 ? cacheEntries[0] : cacheEntries[1];
assertEquals(AbiWriterProtocol.EMPTY_ABI_KEY,
Files.readFirstLine(abiKeyEntry, Charsets.UTF_8));
// Run `buck clean`.
ProcessResult cleanResult = workspace.runBuckCommand("clean");
assertEquals("Successful clean should exit with 0.", 0, cleanResult.getExitCode());
assertEquals("The build cache should still exist.", 2, buildCache.listFiles().length);
// Corrupt the build cache!
File outputFileEntry = cacheEntries[0].length() == 41 ? cacheEntries[1] : cacheEntries[0];
Files.write("Hello world!\n", outputFileEntry, Charsets.UTF_8);
// Run `buck build` again.
ProcessResult buildResult2 = workspace.runBuckCommand("build", "//:no_srcs");
assertEquals("Successful build should exit with 0.", 0, buildResult2.getExitCode());
File outputFile = workspace.getFile("buck-out/gen/lib__no_srcs__output/no_srcs.jar");
assertTrue(outputFile.isFile());
assertEquals(
"The content of the output file will be 'Hello World!' if it is read from the build cache.",
"Hello world!\n",
Files.toString(outputFile, Charsets.UTF_8));
}
@Test
public void testFileChangeThatDoesNotModifyAbiAvoidsRebuild() throws IOException {
workspace = TestDataHelper.createProjectWorkspaceForScenario(
this, "rulekey_changed_while_abi_stable", tmp);
workspace.setUp();
// Run `buck build`.
ProcessResult buildResult = workspace.runBuckCommand("build", "//:biz");
assertEquals("Successful build should exit with 0.", 0, buildResult.getExitCode());
String utilRuleKey = getContents("buck-out/bin/.success/util");
String utilRuleKeyNoDeps = getContents("buck-out/gen/lib__util__abi/rule_key_no_deps");
String utilAbi = getContents("buck-out/gen/lib__util__abi/abi");
String utilAbiForDeps = getContents("buck-out/gen/lib__util__abi/abi_deps");
String bizRuleKey = getContents("buck-out/bin/.success/biz");
String bizRuleKeyNoDeps = getContents("buck-out/gen/lib__biz__abi/rule_key_no_deps");
String bizAbi = getContents("buck-out/gen/lib__biz__abi/abi");
String bizAbiForDeps = getContents("buck-out/gen/lib__biz__abi/abi_deps");
long utilJarSize = workspace.getFile("buck-out/gen/lib__util__output/util.jar").length();
long bizJarLastModified = workspace.getFile("buck-out/gen/lib__biz__output/biz.jar").lastModified();
// TODO(mbolin): Run uber-biz.jar and verify it prints "Hello World!\n".
// Edit Util.java in a way that does not affect its ABI.
String originalUtilJava = getContents("Util.java");
String replacementContents = originalUtilJava.replace("Hello World", "Hola Mundo");
Files.write(replacementContents, workspace.getFile("Util.java"), Charsets.UTF_8);
// Run `buck build` again.
ProcessResult buildResult2 = workspace.runBuckCommand("build", "//:biz");
assertEquals("Successful build should exit with 0.", 0, buildResult2.getExitCode());
assertThat(utilRuleKey, not(equalTo(getContents("buck-out/bin/.success/util"))));
assertThat(utilRuleKeyNoDeps, not(equalTo(getContents("buck-out/gen/lib__util__abi/rule_key_no_deps"))));
assertEquals(utilAbi, getContents("buck-out/gen/lib__util__abi/abi"));
assertEquals(utilAbiForDeps, getContents("buck-out/gen/lib__util__abi/abi_deps"));
assertThat(bizRuleKey, not(equalTo(getContents("buck-out/bin/.success/biz"))));
assertEquals(bizRuleKeyNoDeps, getContents("buck-out/gen/lib__biz__abi/rule_key_no_deps"));
assertEquals(bizAbi, getContents("buck-out/gen/lib__biz__abi/abi"));
assertEquals(bizAbiForDeps, getContents("buck-out/gen/lib__biz__abi/abi_deps"));
assertThat(
"util.jar should have been rewritten, so its file size should have changed.",
utilJarSize,
not(equalTo(workspace.getFile("buck-out/gen/lib__util__output/util.jar").length())));
assertEquals(
"biz.jar should not have been rewritten, so its last-modified time should be the same.",
bizJarLastModified,
workspace.getFile("buck-out/gen/lib__biz__output/biz.jar").lastModified());
// TODO(mbolin): Run uber-biz.jar and verify it prints "Hola Mundo!\n".
// TODO(mbolin): This last scenario that is being tested would be better as a unit test.
// Run `buck build` one last time. This ensures that a dependency java_library() rule (:util)
// that is built via BuildRuleSuccess.Type.MATCHING_DEPS_ABI_AND_RULE_KEY_NO_DEPS does not
// explode when its dependent rule (:biz) invokes the dependency's getAbiKey() method as part of
// its own getAbiKeyForDeps().
ProcessResult buildResult3 = workspace.runBuckCommand("build", "//:biz");
assertEquals("Successful build should exit with 0.", 0, buildResult3.getExitCode());
}
/**
* Asserts that the specified file exists and returns its contents.
*/
private String getContents(String relativePathToFile) throws IOException {
File file = workspace.getFile(relativePathToFile);
assertTrue(relativePathToFile + " should exist and be an ordinary file.", file.exists());
String content = Strings.nullToEmpty(Files.toString(file, Charsets.UTF_8)).trim();
assertFalse(relativePathToFile + " should not be empty.", content.isEmpty());
return content;
}
}