blob: 02a13f669a56b051e539698d7c393f66b61312cf [file] [log] [blame]
/*
* Copyright 2012-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.android;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.android.SmartDexingStep.DxPseudoRule;
import com.facebook.buck.android.SmartDexingStep.InputResolver;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.testutil.MoreAsserts;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.io.Files;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class SmartDexingStepTest {
@Rule
public TemporaryFolder tmpDir = new TemporaryFolder();
/**
* This test makes sure the input processing builds the correct pair of output filenames and
* input arguments that are ultimately passed to dx.
*/
@Test
public void testInputResolverWithMultipleOutputs() throws IOException {
File primaryOutDir = tmpDir.newFolder("primary-out");
File primaryOut = new File(primaryOutDir, "primary.jar");
Set<String> primaryIn = ImmutableSet.of("input/a.jar", "input/b.jar", "input/c.jar");
File secondaryOutDir = tmpDir.newFolder("secondary-out");
File secondaryInDir = tmpDir.newFolder("secondary-in");
File secondaryInFile = new File(secondaryInDir, "2.jar");
Files.write(new byte[]{0}, secondaryInFile);
InputResolver resolver = new InputResolver(
"primary-out/primary.jar",
primaryIn,
Optional.of("secondary-out"),
Optional.of("secondary-in"));
assertTrue("Expected secondary output", resolver.hasSecondaryOutput());
final ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmpDir.getRoot());
Multimap<File, File> outputToInputs = resolver.createOutputToInputs(DexStore.JAR,
projectFilesystem);
assertEquals("Expected 2 output artifacts", 2, outputToInputs.keySet().size());
MoreAsserts.assertIterablesEquals(
"Detected inconsistency with primary input arguments",
Iterables.transform(primaryIn, new Function<String, File>() {
@Override
public File apply(String input) {
return projectFilesystem.getFileForRelativePath(input);
}
}),
outputToInputs.get(primaryOut));
// Make sure that secondary-out/2.dex.jar came from secondary-in/2.jar.
File secondaryOutFile = new File(secondaryOutDir,
SmartDexingStep.transformInputToDexOutput(secondaryInFile, DexStore.JAR));
MoreAsserts.assertIterablesEquals(
"Detected inconsistency with secondary output arguments",
ImmutableSet.of(secondaryInFile),
outputToInputs.get(secondaryOutFile));
}
/**
* Tests whether pseudo rule cache detection is working properly.
*/
@Test
public void testDxPseudoRuleCaching() throws IOException {
ExecutionContext context = createMock(ExecutionContext.class);
replay(context);
File testIn = new File(tmpDir.getRoot(), "testIn");
ZipOutputStream zipOut = new ZipOutputStream(
new BufferedOutputStream(new FileOutputStream(testIn)));
try {
zipOut.putNextEntry(new ZipEntry("foobar"));
zipOut.write(new byte[] { 0 });
} finally {
zipOut.close();
}
File outputFile = tmpDir.newFile("out.dex");
Path outputHashFile = new File(tmpDir.getRoot(), "out.dex.hash").toPath();
Files.write("dummy", outputHashFile.toFile(), Charsets.UTF_8);
DxPseudoRule rule = new DxPseudoRule(context, ImmutableSet.of(testIn.toPath()),
outputFile.getPath(), outputHashFile);
assertFalse("'dummy' is not a matching input hash", rule.checkIsCached());
// Write the real hash into the output hash file and ensure that checkIsCached now
// yields true.
String actualHash = rule.hashInputs();
assertFalse(actualHash.isEmpty());
Files.write(actualHash, outputHashFile.toFile(), Charsets.UTF_8);
assertTrue("Matching input hash should be considered cached", rule.checkIsCached());
}
}