1// Copyright 2018 The Bazel Authors. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package shellapk 16 17import ( 18 "archive/zip" 19 "fmt" 20 "io/ioutil" 21 "os" 22 "path" 23 "path/filepath" 24 "strings" 25 "testing" 26) 27 28const ( 29 testDataBase = "src/tools/ak/shellapk/testdata" 30 pkgName = "com.example" 31 appName = "com.example.ExampleApplication" 32) 33 34func TestCreateShellApk(t *testing.T) { 35 tmpDir, err := ioutil.TempDir("", "shelltest") 36 if err != nil { 37 t.Fatalf("Error creating temp directory: %v", err) 38 } 39 defer os.RemoveAll(tmpDir) 40 out := filepath.Join(tmpDir, "shell.apk") 41 res := dataPath("res.zip") 42 nativeLib := dataPath("native_lib.zip") 43 jdk := strings.Split(os.Getenv("JAVA_HOME"), "/bin/")[0] 44 dexFile := dataPath("dexes.zip") 45 manifestPkgName := dataPath("manifest_package_name.txt") 46 inAppClassName := dataPath("app_name.txt") 47 manifest := dataPath("AndroidManifest.xml") 48 err = doWork( 49 out, 50 []string{res}, 51 nativeLib, 52 jdk, 53 dexFile, 54 manifestPkgName, 55 inAppClassName, 56 manifest, 57 "", // arsc 58 res, 59 "") // linkedNativeLib 60 if err != nil { 61 t.Fatalf("Error creating shell apk: %v", err) 62 } 63 64 if _, err := os.Stat(out); os.IsNotExist(err) { 65 t.Fatalf("Shell apk not created") 66 } 67 68 z, err := zip.OpenReader(out) 69 if err != nil { 70 t.Fatalf("Error opening output apk: %v", err) 71 } 72 defer z.Close() 73 74 if !zipContains(z, "AndroidManifest.xml") { 75 t.Fatalf("APK does not contain AndroidManifest.xml") 76 } 77 if !zipContains(z, "classes.dex") { 78 t.Fatalf("APK does not contain classes.dex") 79 } 80 if !zipContains(z, "lib/x86/libsample.so") { 81 t.Fatalf("APK does not contain native lib") 82 } 83 84 c, err := zipFileContents(z, "package_name.txt") 85 if err != nil { 86 t.Fatalf("Error opening package_name.txt: %v", err) 87 } 88 if c != pkgName { 89 t.Fatalf("package_name.txt invalid content. Got (%v) expected (%v)", c, pkgName) 90 } 91 92 c, err = zipFileContents(z, "app_name.txt") 93 if err != nil { 94 t.Fatalf("Error opening app_name.txt") 95 } 96 if c != appName { 97 t.Fatalf("app_name.txt invalid content. Got (%v) expected (%v)", c, appName) 98 } 99 100 resZip, err := zip.OpenReader(res) 101 if err != nil { 102 t.Fatalf("Error opening res zip: %v", err) 103 } 104 defer resZip.Close() 105 for _, f := range z.File { 106 if !zipContains(z, f.Name) { 107 t.Fatalf("APK does not contain resource %s", f.Name) 108 } 109 } 110} 111 112func dataPath(fn string) string { 113 return path.Join(os.Getenv("TEST_SRCDIR"), testDataBase, fn) 114} 115 116func zipContains(z *zip.ReadCloser, fn string) bool { 117 for _, f := range z.File { 118 if fn == f.Name { 119 return true 120 } 121 } 122 return false 123} 124 125func zipFileContents(z *zip.ReadCloser, fn string) (string, error) { 126 for _, f := range z.File { 127 if fn == f.Name { 128 rc, err := f.Open() 129 if err != nil { 130 return "", err 131 } 132 contents, err := ioutil.ReadAll(rc) 133 if err != nil { 134 return "", err 135 } 136 return string(contents), nil 137 } 138 } 139 return "", fmt.Errorf("Zip does not contain file") 140} 141