From 5dfa79934c3ab4b710fbea48278eff35a442e869 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 25 Dec 2014 12:21:12 -0600 Subject: [PATCH] [tests] adds tests for shared resources & framework tagging --- .../java/brut/androlib/SharedLibraryTest.java | 103 ++++++++++++++++++ .../brut/apktool/shared_libraries/client.apk | Bin 0 -> 9068 bytes .../brut/apktool/shared_libraries/library.apk | Bin 0 -> 13715 bytes 3 files changed, 103 insertions(+) create mode 100644 brut.apktool/apktool-lib/src/test/java/brut/androlib/SharedLibraryTest.java create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/shared_libraries/client.apk create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/shared_libraries/library.apk diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/SharedLibraryTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/SharedLibraryTest.java new file mode 100644 index 00000000..98c2face --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/SharedLibraryTest.java @@ -0,0 +1,103 @@ +/** + * Copyright 2014 Ryszard Wiśniewski + * Copyright 2014 Connor Tumbleson + * + * 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 brut.androlib; + +import brut.androlib.res.util.ExtFile; +import brut.common.BrutException; +import brut.directory.DirectoryException; +import brut.util.OS; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.assertTrue; + +public class SharedLibraryTest { + + @BeforeClass + public static void beforeClass() throws BrutException { + sTmpDir = new ExtFile(OS.createTempDirectory()); + TestUtils.copyResourceDir(SharedLibraryTest.class, "brut/apktool/shared_libraries/", sTmpDir); + } + + @AfterClass + public static void afterClass() throws BrutException { + //OS.rmdir(sTmpDir); + } + + @Test + public void isFrameworkTaggingWorking() throws AndrolibException { + String apkName = "library.apk"; + + ApkOptions apkOptions = new ApkOptions(); + apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); + apkOptions.frameworkTag = "building"; + + new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + apkName)); + + assertTrue(fileExists("2-building.apk")); + } + + @Test + public void isFrameworkInstallingWorking() throws AndrolibException { + String apkName = "library.apk"; + + ApkOptions apkOptions = new ApkOptions(); + apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); + + new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + apkName)); + + assertTrue(fileExists("2.apk")); + } + + @Test + public void isSharedResourceDecodingWorking() throws IOException, BrutException { + String framework = "library.apk"; + String client = "client.apk"; + + + ApkOptions apkOptions = new ApkOptions(); + apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); + apkOptions.frameworkTag = "shared"; + + new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + framework)); + + assertTrue(fileExists("2-shared.apk")); + + ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + client)); + apkDecoder.setOutDir(new File(sTmpDir + File.separator + client + ".out")); + apkDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation); + apkDecoder.setFrameworkTag(apkOptions.frameworkTag); + apkDecoder.decode(); + + ExtFile testApk = new ExtFile(sTmpDir, client + ".out"); + new Androlib(apkOptions).build(testApk, null); + + assertTrue(fileExists(client + ".out" + File.separator + "dist" + File.separator + client)); + } + + private boolean fileExists(String filepath) { + return Files.exists(Paths.get(sTmpDir.getAbsolutePath() + File.separator + filepath)); + } + + private static ExtFile sTmpDir; +} diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/shared_libraries/client.apk b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/shared_libraries/client.apk new file mode 100644 index 0000000000000000000000000000000000000000..d85e8e3347359f8cbc6356c0c43e228880c3119b GIT binary patch literal 9068 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 bpS6Ld>5eKE>U#=c9^iuTfNcX(0G0Y*+!?_! literal 0 HcmV?d00001