| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * 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.android.jack.resource; |
| |
| import com.android.jack.library.FileType; |
| import com.android.jack.library.FileTypeDoesNotExistException; |
| import com.android.jack.library.InputJackLibrary; |
| import com.android.jack.shrob.obfuscation.NameProviderFactory; |
| import com.android.jack.test.junit.KnownIssue; |
| import com.android.jack.test.toolchain.AbstractTestTools; |
| import com.android.jack.test.toolchain.IToolchain; |
| import com.android.jack.test.toolchain.IncrementalToolchain; |
| import com.android.jack.test.toolchain.JackApiToolchainBase; |
| import com.android.jack.test.toolchain.JackBasedToolchain; |
| import com.android.jack.test.toolchain.JillApiToolchainBase; |
| import com.android.sched.util.file.WrongPermissionException; |
| import com.android.sched.vfs.InputVFile; |
| import com.android.sched.vfs.VPath; |
| |
| import junit.framework.Assert; |
| |
| import org.junit.Test; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.StringReader; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipFile; |
| |
| import javax.annotation.Nonnull; |
| |
| /** |
| * JUnit tests for resource support. |
| */ |
| public class ResourceTests { |
| |
| @Nonnull |
| private static final String COMMON_PATH = "com/android/jack/resource/test001/jack/"; |
| @Nonnull |
| private static final String JACK_FILE_PATH = "jayce/" + COMMON_PATH |
| + "IrrelevantForTest.jayce"; |
| @Nonnull |
| private static final String DEX_FILE_PATH = "dex/" + COMMON_PATH |
| + "IrrelevantForTest.dex"; |
| @Nonnull |
| private static final String RESOURCE1_SHORTPATH = "Resource1"; |
| @Nonnull |
| private static final String RESOURCE2_SHORTPATH = "Resource2"; |
| @Nonnull |
| private static final String RESOURCE3_SHORTPATH = "pack/Resource3"; |
| @Nonnull |
| private static final String RESOURCE4_SHORTPATH = "pack/Resource4"; |
| |
| @Nonnull |
| private static final File FILE = |
| AbstractTestTools.getTestRootDir("com.android.jack.resource.test001.jack"); |
| |
| |
| |
| @Test |
| public void testJackArchiveToDexDir() throws Exception { |
| // compile source file to a Jack archive and add resources |
| File jackAr = createJackArchiveWithResources(); |
| |
| // compile Jack archive to a dex dir |
| File dexDir = AbstractTestTools.createTempDir(); |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); |
| toolchain.libToExe(jackAr, dexDir, /* zipFile = */ false); |
| |
| // check that resources are contained in dex dir |
| checkResourceContentFromDir(dexDir, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromDir(dexDir, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromDir(dexDir, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromDir(dexDir, RESOURCE4_SHORTPATH, "Res4"); |
| } |
| |
| @Test |
| public void testJackArchiveToDexArchive() throws Exception { |
| // compile source file to a Jack archive and add resources |
| File jackAr = createJackArchiveWithResources(); |
| |
| // compile Jack archive to dex archive |
| File dexAr = AbstractTestTools.createTempFile("resourcetestdex", ".zip"); |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); |
| toolchain.libToExe(jackAr, dexAr, /* zipFile = */ true); |
| |
| // check that resources are contained in dex archive |
| ZipFile zipFile = new ZipFile(dexAr); |
| checkResourceContentFromZip(zipFile, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromZip(zipFile, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromZip(zipFile, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromZip(zipFile, RESOURCE4_SHORTPATH, "Res4"); |
| } |
| |
| @Test |
| public void testJackDirToDexArchive() throws Exception { |
| // compile source file to a Jack dir |
| File jackFolder = AbstractTestTools.createTempDir(); |
| List<Class<? extends IToolchain>> exclude = new ArrayList<Class<? extends IToolchain>>(); |
| exclude.add(JillApiToolchainBase.class); |
| JackBasedToolchain toolchain = |
| AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class,exclude); |
| toolchain.addResourceDir(new File(FILE, "rsc")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()) |
| .srcToLib( |
| jackFolder, |
| /* zipFiles = */ false, |
| FILE); |
| |
| // compile Jack dir to dex archive |
| File dexAr = AbstractTestTools.createTempFile("resourcetestdex", ".zip"); |
| toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); |
| toolchain.libToExe(jackFolder, dexAr, /* zipFile = */ true); |
| |
| // check that resources are contained in dex archive |
| ZipFile zipFile = new ZipFile(dexAr); |
| checkResourceContentFromZip(zipFile, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromZip(zipFile, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromZip(zipFile, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromZip(zipFile, RESOURCE4_SHORTPATH, "Res4"); |
| } |
| |
| @Test |
| public void testJackArchiveToJackArchive() throws Exception { |
| // compile source file to a Jack archive and add resources |
| File jackAr = createJackArchiveWithResources(); |
| |
| // run shrobbing from Jack archive to Jack archive |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); |
| File shrobbedJackAr = |
| AbstractTestTools.createTempFile("shrobbedJackAr", toolchain.getLibraryExtension()); |
| toolchain.addProguardFlags(new File(FILE, "proguard.flags")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()); |
| toolchain.libToLib(jackAr, shrobbedJackAr, /* zipFiles = */ true); |
| |
| // check that resources are contained in dex archive |
| InputJackLibrary shrobbedLib = null; |
| try { |
| shrobbedLib = AbstractTestTools.getInputJackLibrary(shrobbedJackAr); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE4_SHORTPATH, "Res4"); |
| } finally { |
| if (shrobbedLib != null) { |
| shrobbedLib.close(); |
| } |
| } |
| } |
| |
| @Test |
| public void testJackDirToJackArchive() throws Exception { |
| // compile source file to a Jack dir |
| File jackFolder = AbstractTestTools.createTempDir(); |
| List<Class<? extends IToolchain>> exclude = new ArrayList<Class<? extends IToolchain>>(); |
| exclude.add(JillApiToolchainBase.class); |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, exclude); |
| toolchain.addResourceDir(new File(FILE, "rsc")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()) |
| .srcToLib( |
| jackFolder, |
| /* zipFiles = */ false, |
| FILE); |
| |
| // run shrobbing from Jack dir to Jack archive |
| toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, exclude); |
| File shrobbedJackAr = |
| AbstractTestTools.createTempFile("shrobbedJackAr", toolchain.getLibraryExtension()); |
| toolchain.addProguardFlags(new File(FILE, "proguard.flags")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()); |
| toolchain.libToLib(jackFolder, shrobbedJackAr, /* zipFiles = */ true); |
| |
| // check that resources are contained in Jack archive |
| InputJackLibrary shrobbedLib = null; |
| try { |
| shrobbedLib = AbstractTestTools.getInputJackLibrary(shrobbedJackAr); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE4_SHORTPATH, "Res4"); |
| } finally { |
| if (shrobbedLib != null) { |
| shrobbedLib.close(); |
| } |
| } |
| } |
| |
| @Test |
| @KnownIssue(candidate=IncrementalToolchain.class) |
| public void testJackArchiveToJackDir() throws Exception { |
| // compile source file to a Jack archive and add resources |
| File jackAr = createJackArchiveWithResources(); |
| |
| // run shrobbing from Jack archive to Jack dir |
| File shrobbedJackDir = AbstractTestTools.createTempDir(); |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); |
| toolchain.addProguardFlags(new File(FILE, "proguard.flags")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()); |
| toolchain.libToLib(jackAr, shrobbedJackDir, /* zipFiles = */ false); |
| |
| // check that resources are contained in Jack dir |
| InputJackLibrary shrobbedLib = null; |
| try { |
| shrobbedLib = AbstractTestTools.getInputJackLibrary(shrobbedJackDir); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE4_SHORTPATH, "Res4"); |
| } finally { |
| if (shrobbedLib != null) { |
| shrobbedLib.close(); |
| } |
| } |
| } |
| |
| @Test |
| @KnownIssue(candidate=IncrementalToolchain.class) |
| public void testJackDirToJackDir() throws Exception { |
| // compile source file to a Jack dir |
| File jackFolder = AbstractTestTools.createTempDir(); |
| List<Class<? extends IToolchain>> exclude = new ArrayList<Class<? extends IToolchain>>(); |
| exclude.add(JillApiToolchainBase.class); |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, exclude); |
| toolchain.addResourceDir(new File(FILE, "rsc")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()) |
| .srcToLib( |
| jackFolder, |
| /* zipFiles = */ false, |
| FILE); |
| |
| // run shrobbing from Jack dir to Jack dir |
| File shrobbedJackDir = AbstractTestTools.createTempDir(); |
| toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); |
| toolchain.addProguardFlags(new File(FILE, "proguard.flags")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()); |
| toolchain.libToLib(jackFolder, shrobbedJackDir, /* zipFiles = */ false); |
| |
| // check that resources are contained in Jack dir |
| InputJackLibrary shrobbedLib = null; |
| try { |
| shrobbedLib = AbstractTestTools.getInputJackLibrary(shrobbedJackDir); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromLib(shrobbedLib, RESOURCE4_SHORTPATH, "Res4"); |
| } finally { |
| if (shrobbedLib != null) { |
| shrobbedLib.close(); |
| } |
| } |
| } |
| |
| @Test |
| public void testJackDirToDexDir() throws Exception { |
| // compile source file to a Jack dir |
| File jackFolder = AbstractTestTools.createTempDir(); |
| List<Class<? extends IToolchain>> exclude = new ArrayList<Class<? extends IToolchain>>(); |
| exclude.add(JillApiToolchainBase.class); |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, exclude); |
| toolchain.addResourceDir(new File(FILE, "rsc")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()) |
| .srcToLib( |
| jackFolder, |
| /* zipFiles = */ false, |
| FILE); |
| |
| // compile Jack dir to a dex dir |
| File dexDir = AbstractTestTools.createTempDir(); |
| toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, exclude); |
| toolchain.libToExe(jackFolder, dexDir, /* zipFile = */ false); |
| |
| // check that resources are contained in dex dir |
| checkResourceContentFromDir(dexDir, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromDir(dexDir, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromDir(dexDir, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromDir(dexDir, RESOURCE4_SHORTPATH, "Res4"); |
| } |
| |
| @Test |
| public void testJackToDexInSameDir() throws Exception { |
| // compile source file to a Jack dir |
| File jackFolder = AbstractTestTools.createTempDir(); |
| List<Class<? extends IToolchain>> exclude = new ArrayList<Class<? extends IToolchain>>(); |
| exclude.add(JillApiToolchainBase.class); |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, exclude); |
| toolchain.addResourceDir(new File(FILE, "rsc")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()) |
| .srcToLib( |
| jackFolder, |
| /* zipFiles = */ false, |
| FILE); |
| |
| // compile Jack dir to same dir |
| File dexDir = jackFolder; |
| AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, exclude) |
| .libToExe(jackFolder, dexDir, /* zipFile = */ false); |
| |
| // check that resources are contained in dex dir |
| checkResourceContentFromDir(dexDir, RESOURCE1_SHORTPATH, "Res1"); |
| checkResourceContentFromDir(dexDir, RESOURCE2_SHORTPATH, "Res2"); |
| checkResourceContentFromDir(dexDir, RESOURCE3_SHORTPATH, "Res3"); |
| checkResourceContentFromDir(dexDir, RESOURCE4_SHORTPATH, "Res4"); |
| } |
| |
| @Test |
| public void testResourceContentAdaptation() throws Exception { |
| // compile source file to a Jack dir |
| File jackOutputFolder = AbstractTestTools.createTempDir(); |
| //String testName = "resource/test003"; |
| File testFolder = AbstractTestTools.getTestRootDir("com.android.jack.resource.test003"); |
| File jackTestFolder = |
| AbstractTestTools.getTestRootDir("com.android.jack.resource.test003.jack"); |
| File rscFolder = new File(jackTestFolder, "rsc"); |
| String resource1LongPath = "com/android/jack/resource/test003/jack/A"; |
| String resource2LongPath = "com/android/jack/resource/test003/jack/A.txt"; |
| JackBasedToolchain toolchain = |
| AbstractTestTools.getCandidateToolchain(JackApiToolchainBase.class); |
| toolchain.addResourceDir(rscFolder).addToClasspath(toolchain.getDefaultBootClasspath()) |
| .srcToLib( |
| jackOutputFolder, |
| /* zipFiles = */ false, |
| testFolder); |
| |
| // check that resources are contained in Jack dir and check their contents |
| InputJackLibrary lib = null; |
| try { |
| lib = AbstractTestTools.getInputJackLibrary(jackOutputFolder); |
| InputVFile candidateFile1 = lib.getFile(FileType.RSC, new VPath(resource1LongPath, '/')); |
| InputVFile candidateFile2 = lib.getFile(FileType.RSC, new VPath(resource2LongPath, '/')); |
| checkResourceContent(candidateFile1, new File(rscFolder, resource1LongPath)); |
| checkResourceContent(candidateFile2, new File(rscFolder, resource2LongPath)); |
| } finally { |
| if (lib != null) { |
| lib.close(); |
| } |
| } |
| |
| toolchain = AbstractTestTools.getCandidateToolchain(JackApiToolchainBase.class); |
| toolchain.addProperty(NameProviderFactory.NAMEPROVIDER.getName(), "rot13"); |
| File shrobbedJackDir = AbstractTestTools.createTempDir(); |
| toolchain.addProguardFlags(new File(testFolder, "proguard.flags001")); |
| toolchain.libToLib(jackOutputFolder, shrobbedJackDir, /* zipFiles = */ false); |
| |
| // check that resources are contained in Jack dir and check their contents |
| InputJackLibrary shrobbedLib = null; |
| try { |
| shrobbedLib = AbstractTestTools.getInputJackLibrary(shrobbedJackDir); |
| File referenceFile = new File(testFolder, "refs/A.txt"); |
| InputVFile candidateFile1 = shrobbedLib.getFile(FileType.RSC, |
| new VPath("pbz/naqebvq/wnpx/erfbhepr/grfg003/wnpx/A", '/')); |
| InputVFile candidateFile2 = shrobbedLib.getFile(FileType.RSC, |
| new VPath("pbz/naqebvq/wnpx/erfbhepr/grfg003/wnpx/N.txt", '/')); |
| checkResourceContent(candidateFile1, referenceFile); |
| checkResourceContent(candidateFile2, referenceFile); |
| } finally { |
| if (shrobbedLib != null) { |
| shrobbedLib.close(); |
| } |
| } |
| } |
| |
| @Nonnull |
| private File createJackArchiveWithResources() throws Exception { |
| // compile source file to a Jack file |
| JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); |
| File jackAr = AbstractTestTools.createTempFile("resourcetestjack", toolchain.getLibraryExtension()); |
| toolchain.addResourceDir(new File(FILE, "rsc")); |
| toolchain.addToClasspath(toolchain.getDefaultBootClasspath()) |
| .srcToLib( |
| jackAr, |
| /* zipFiles = */ true, |
| FILE); |
| |
| return jackAr; |
| } |
| |
| private void checkResourceContentFromZip(@Nonnull ZipFile zipFile, @Nonnull String entryName, |
| @Nonnull String expectedContent) throws IOException { |
| ZipEntry entry = zipFile.getEntry(entryName); |
| Assert.assertNotNull(entry); |
| BufferedReader candidateReader = null; |
| BufferedReader referenceReader = null; |
| try { |
| InputStream in = zipFile.getInputStream(entry); |
| candidateReader = new BufferedReader(new InputStreamReader(in)); |
| referenceReader = new BufferedReader(new StringReader(expectedContent)); |
| compareReadLines(referenceReader, candidateReader); |
| } finally { |
| if (candidateReader != null) { |
| candidateReader.close(); |
| } |
| if (referenceReader != null) { |
| referenceReader.close(); |
| } |
| } |
| } |
| |
| public static void checkResourceContentFromLib(@Nonnull InputJackLibrary lib, |
| @Nonnull String path, @Nonnull String expectedContent) |
| throws IOException, FileTypeDoesNotExistException, WrongPermissionException { |
| InputVFile rescFile = lib.getFile(FileType.RSC, new VPath(path, '/')); |
| BufferedReader candidateReader = null; |
| BufferedReader referenceReader = null; |
| try { |
| candidateReader = new BufferedReader(new InputStreamReader(rescFile.getInputStream())); |
| referenceReader = new BufferedReader(new StringReader(expectedContent)); |
| compareReadLines(referenceReader, candidateReader); |
| } finally { |
| if (candidateReader != null) { |
| candidateReader.close(); |
| } |
| if (referenceReader != null) { |
| referenceReader.close(); |
| } |
| } |
| } |
| |
| public static void checkResourceContentFromDir(@Nonnull File dir, @Nonnull String path, |
| @Nonnull String expectedContent) throws IOException { |
| assert dir.isDirectory(); |
| File file = new File(dir, path); |
| Assert.assertTrue(file.exists()); |
| BufferedReader candidateReader = null; |
| BufferedReader referenceReader = null; |
| try { |
| InputStream in = new FileInputStream(file); |
| candidateReader = new BufferedReader(new InputStreamReader(in)); |
| referenceReader = new BufferedReader(new StringReader(expectedContent)); |
| compareReadLines(referenceReader, candidateReader); |
| } finally { |
| if (candidateReader != null) { |
| candidateReader.close(); |
| } |
| if (referenceReader != null) { |
| referenceReader.close(); |
| } |
| } |
| } |
| |
| |
| private static void checkResourceContent(@Nonnull InputVFile candidateFile, |
| @Nonnull File referenceFile) throws IOException, WrongPermissionException { |
| BufferedReader candidateReader = null; |
| BufferedReader referenceReader = null; |
| try { |
| candidateReader = new BufferedReader(new InputStreamReader(candidateFile.getInputStream())); |
| referenceReader = |
| new BufferedReader(new InputStreamReader(new FileInputStream(referenceFile))); |
| compareReadLines(referenceReader, candidateReader); |
| } finally { |
| if (candidateReader != null) { |
| candidateReader.close(); |
| } |
| if (referenceReader != null) { |
| referenceReader.close(); |
| } |
| } |
| } |
| |
| private static void compareReadLines(@Nonnull BufferedReader referenceReader, |
| @Nonnull BufferedReader candidateReader) throws IOException { |
| String referenceLine = referenceReader.readLine(); |
| while (referenceLine != null) { |
| String candidateLine = candidateReader.readLine(); |
| Assert.assertEquals(referenceLine, candidateLine); |
| referenceLine = referenceReader.readLine(); |
| } |
| Assert.assertNull(candidateReader.readLine()); |
| } |
| } |