package org.eclipse.buckminster.jarprocessor.test; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.eclipse.buckminster.jarprocessor.RecursiveConditioner; import org.eclipse.buckminster.jarprocessor.RecursivePacker; import org.eclipse.buckminster.jarprocessor.RecursiveUnpacker; import org.eclipse.buckminster.runtime.IOUtils; import org.junit.Test; public class TestRecursivePack extends AbstractTest { static final class StreamGobblerRedirector extends Thread { private final InputStream is; private final PrintStream os; StreamGobblerRedirector(InputStream is, PrintStream os) { this.is = is; this.os = os; } @Override public void run() { try { final InputStreamReader isr = new InputStreamReader(is); final BufferedReader bufferedReader = new BufferedReader(isr); String readLine; while ((readLine = bufferedReader.readLine()) != null) os.println(readLine); } catch (IOException ioe) { ioe.printStackTrace(); } } } private static Map<String, Long> verify(File file) throws Exception { HashMap<String, Long> crcMap = new HashMap<String, Long>(); verify(crcMap, file); return crcMap; } private static void verify(Map<String, Long> crcMap, File file) throws Exception { JarFile verifier = new JarFile(file, true); for (Enumeration<JarEntry> entries = verifier.entries(); entries .hasMoreElements();) { JarEntry entry = entries.nextElement(); entry.getCertificates(); crcMap.put(entry.getName(), entry.getSize()); if (entry.getName().endsWith(".jar")) { InputStream input = verifier.getInputStream(entry); File temp = File.createTempFile("nested", ".jar"); try { OutputStream out = new FileOutputStream(temp); IOUtils.copy(input, out, null); out.close(); verify(crcMap, temp); } finally { temp.delete(); IOUtils.close(input); } } } verifier.close(); File javaHome = new File(System.getProperty("java.home")); if("jre".equals(javaHome.getName())) javaHome = javaHome.getParentFile(); File javaBin = new File(javaHome, "bin"); File jarsignerExe = new File(javaBin, "jarsigner"); boolean jarsignerOK = jarsignerExe.canExecute(); if(!jarsignerOK) { jarsignerExe = new File(javaBin, "jarsigner.exe"); jarsignerOK = jarsignerExe.canExecute(); } assertTrue("Unable to find jarsigner executable", jarsignerOK); Process jarsigner = Runtime.getRuntime().exec(new String[] { jarsignerExe.getAbsolutePath(), "-verify", file.getAbsolutePath() }); final StreamGobblerRedirector errorGobbler = new StreamGobblerRedirector(jarsigner.getErrorStream(), System.err); final StreamGobblerRedirector outputGobbler = new StreamGobblerRedirector(jarsigner.getInputStream(), System.out); errorGobbler.start(); outputGobbler.start(); final int returnCode = jarsigner.waitFor(); System.err.flush(); System.out.flush(); assertEquals("jarsigner failed exit code != 0 when verifying " + file.getAbsolutePath(), 0, returnCode); } private static void assertEqualNames(Collection<String> ns1, Collection<String> ns2) { for (String n1 : ns1) assertTrue("Expected \'" + n1 + "\' is missing", ns2.contains(n1)); for (String n2 : ns2) assertTrue("Found \'" + n2 + "\' unexpectedly", ns1.contains(n2)); } @Test public void testPackFile() throws Exception { File originalJar = getTestJar("jdtstuff.jar"); Map<String, Long> originalCrcMap = verify(originalJar); File outputFolder = getTestFolder("testPackFile"); File tmpFolder = new File(outputFolder, "temp"); tmpFolder.mkdirs(); File conditionedJarFile = new File(outputFolder, originalJar.getName()); RecursiveConditioner conditioner = new RecursiveConditioner(tmpFolder, null); conditioner.condition(originalJar, conditionedJarFile); Map<String, Long> conditionedCrcMap = verify(conditionedJarFile); assertEqualNames(originalCrcMap.keySet(), conditionedCrcMap.keySet()); RecursivePacker packer = new RecursivePacker(tmpFolder, null, true); packer.pack(conditionedJarFile, outputFolder, false); RecursiveUnpacker unpacker = new RecursiveUnpacker(tmpFolder, null); unpacker.unpack(new File(outputFolder, "jdtstuff.jar.pack.gz"), outputFolder, true); File unpacked = new File(outputFolder, "jdtstuff.jar"); Map<String, Long> unpackedCrcMap = verify(unpacked); assertEqualNames(conditionedCrcMap.keySet(), unpackedCrcMap.keySet()); for (Entry<String, Long> entry : conditionedCrcMap.entrySet()) { Long ucrc = unpackedCrcMap.get(entry.getKey()); assertEquals("2: CRC for " + entry.getKey() + " differ", entry .getValue(), ucrc); } } @Test public void testPdeCoreFile() throws Exception { File originalJar = getTestJar("pdestuff.jar"); Map<String, Long> originalCrcMap = verify(originalJar); File outputFolder = getTestFolder("testPackFile"); File tmpFolder = new File(outputFolder, "temp"); tmpFolder.mkdirs(); File conditionedJarFile = new File(outputFolder, originalJar.getName()); RecursiveConditioner conditioner = new RecursiveConditioner(tmpFolder, null); conditioner.condition(originalJar, conditionedJarFile); Map<String, Long> conditionedCrcMap = verify(conditionedJarFile); assertEqualNames(originalCrcMap.keySet(), conditionedCrcMap.keySet()); RecursivePacker packer = new RecursivePacker(tmpFolder, null, true); packer.pack(conditionedJarFile, outputFolder, false); RecursiveUnpacker unpacker = new RecursiveUnpacker(tmpFolder, null); unpacker.unpack(new File(outputFolder, "pdestuff.jar.pack.gz"), outputFolder, true); File unpacked = new File(outputFolder, "pdestuff.jar"); Map<String, Long> unpackedCrcMap = verify(unpacked); assertEqualNames(conditionedCrcMap.keySet(), unpackedCrcMap.keySet()); for (Entry<String, Long> entry : conditionedCrcMap.entrySet()) { Long ucrc = unpackedCrcMap.get(entry.getKey()); assertEquals("2: CRC for " + entry.getKey() + " differ", entry .getValue(), ucrc); } } }