/* * Copyright 2014-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.jvm.java.abi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.facebook.buck.io.ProjectFilesystem; import com.facebook.buck.testutil.integration.TestDataHelper; import com.google.common.hash.Hashing; import com.google.common.io.ByteSource; import com.google.common.io.ByteStreams; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public class StubJarIntegrationTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); private Path testDataDir; private ProjectFilesystem filesystem; @Before public void createWorkspace() throws InterruptedException, IOException { Path dir = TestDataHelper.getTestDataDirectory(this); testDataDir = dir.resolve("sample").toAbsolutePath(); filesystem = new ProjectFilesystem(temp.newFolder().toPath()); } @Test public void shouldBuildAbiJar() throws IOException { Path out = Paths.get("junit-abi.jar"); Path regularJar = testDataDir.resolve("junit.jar"); new StubJar(regularJar).writeTo(filesystem, out); // We assume that the lack of an exception indicates that the abi jar is correct. See MirrorTest // for why this is so. assertTrue(filesystem.getFileSize(out) > 0); assertTrue(filesystem.getFileSize(out) < filesystem.getFileSize(regularJar)); } @Test public void shouldBuildAbiJarFromAbiJarWeCreated() throws IOException { Path mid = Paths.get("junit-mid.jar"); Path source = testDataDir.resolve("junit.jar"); new StubJar(source).writeTo(filesystem, mid); Path out = Paths.get("junit-abi.jar"); new StubJar(filesystem.resolve(mid)).writeTo(filesystem, out); assertTrue(filesystem.getFileSize(out) > 0); assertEquals(filesystem.getFileSize(mid), filesystem.getFileSize(out)); } @Test public void shouldBuildAbiJarFromAThirdPartyStubbedJar() throws IOException { Path out = Paths.get("android-abi.jar"); Path source = testDataDir.resolve("android.jar"); new StubJar(source).writeTo(filesystem, out); assertTrue(filesystem.getFileSize(out) > 0); assertTrue(filesystem.getFileSize(out) < filesystem.getFileSize(source)); } @Test public void shouldBuildAbiJarEvenIfAsmWouldChokeOnAFrame() throws IOException { Path out = Paths.get("unity-abi.jar"); Path source = testDataDir.resolve("unity.jar"); new StubJar(source).writeTo(filesystem, out); assertTrue(filesystem.getFileSize(out) > 0); assertTrue(filesystem.getFileSize(out) < filesystem.getFileSize(source)); } @Test public void abiJarManifestShouldContainHashesOfItsFiles() throws IOException { Path out = Paths.get("junit-abi.jar"); Path regularJar = testDataDir.resolve("junit.jar"); new StubJar(regularJar).writeTo(filesystem, out); try (JarFile stubJar = new JarFile(filesystem.resolve(out).toFile())) { Manifest manifest = stubJar.getManifest(); Enumeration<JarEntry> entries = stubJar.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); if (JarFile.MANIFEST_NAME.equals(entry.getName())) { continue; } else if (entry.getName().endsWith("/")) { assertNull(manifest.getAttributes(entry.getName())); continue; } String seenDigest = manifest.getAttributes(entry.getName()).getValue("Murmur3-128-Digest"); String expectedDigest; try (InputStream inputStream = stubJar.getInputStream(entry)) { ByteSource byteSource = ByteSource.wrap(ByteStreams.toByteArray(inputStream)); expectedDigest = byteSource.hash(Hashing.murmur3_128()).toString(); } assertEquals( String.format("Digest mismatch for %s", entry.getName()), expectedDigest, seenDigest); } } } }