1// Copyright 2018 Google Inc. 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 dexpreopt 16 17import ( 18 "android/soong/android" 19 "fmt" 20 "testing" 21) 22 23func testSystemModuleConfig(ctx android.PathContext, name string) *ModuleConfig { 24 return testModuleConfig(ctx, name, "system") 25} 26 27func testSystemProductModuleConfig(ctx android.PathContext, name string) *ModuleConfig { 28 return testModuleConfig(ctx, name, "system/product") 29} 30 31func testProductModuleConfig(ctx android.PathContext, name string) *ModuleConfig { 32 return testModuleConfig(ctx, name, "product") 33} 34 35func testModuleConfig(ctx android.PathContext, name, partition string) *ModuleConfig { 36 return &ModuleConfig{ 37 Name: name, 38 DexLocation: fmt.Sprintf("/%s/app/test/%s.apk", partition, name), 39 BuildPath: android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)), 40 DexPath: android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)), 41 UncompressedDex: false, 42 HasApkLibraries: false, 43 PreoptFlags: nil, 44 ProfileClassListing: android.OptionalPath{}, 45 ProfileIsTextListing: false, 46 EnforceUsesLibrariesStatusFile: android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)), 47 EnforceUsesLibraries: false, 48 ClassLoaderContexts: nil, 49 Archs: []android.ArchType{android.Arm}, 50 DexPreoptImagesDeps: []android.OutputPaths{android.OutputPaths{}}, 51 DexPreoptImageLocationsOnHost: []string{}, 52 PreoptBootClassPathDexFiles: nil, 53 PreoptBootClassPathDexLocations: nil, 54 PreoptExtractedApk: false, 55 NoCreateAppImage: false, 56 ForceCreateAppImage: false, 57 PresignedPrebuilt: false, 58 } 59} 60 61func TestDexPreopt(t *testing.T) { 62 config := android.TestConfig("out", nil, "", nil) 63 ctx := android.BuilderContextForTesting(config) 64 globalSoong := globalSoongConfigForTests() 65 global := GlobalConfigForTests(ctx) 66 module := testSystemModuleConfig(ctx, "test") 67 68 rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module) 69 if err != nil { 70 t.Fatal(err) 71 } 72 73 wantInstalls := android.RuleBuilderInstalls{ 74 {android.PathForOutput(ctx, "test/oat/arm/package.odex"), "/system/app/test/oat/arm/test.odex"}, 75 {android.PathForOutput(ctx, "test/oat/arm/package.vdex"), "/system/app/test/oat/arm/test.vdex"}, 76 } 77 78 if rule.Installs().String() != wantInstalls.String() { 79 t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs()) 80 } 81} 82 83func TestDexPreoptSystemOther(t *testing.T) { 84 config := android.TestConfig("out", nil, "", nil) 85 ctx := android.BuilderContextForTesting(config) 86 globalSoong := globalSoongConfigForTests() 87 global := GlobalConfigForTests(ctx) 88 systemModule := testSystemModuleConfig(ctx, "Stest") 89 systemProductModule := testSystemProductModuleConfig(ctx, "SPtest") 90 productModule := testProductModuleConfig(ctx, "Ptest") 91 92 global.HasSystemOther = true 93 94 type moduleTest struct { 95 module *ModuleConfig 96 expectedPartition string 97 } 98 tests := []struct { 99 patterns []string 100 moduleTests []moduleTest 101 }{ 102 { 103 patterns: []string{"app/%"}, 104 moduleTests: []moduleTest{ 105 {module: systemModule, expectedPartition: "system_other/system"}, 106 {module: systemProductModule, expectedPartition: "system/product"}, 107 {module: productModule, expectedPartition: "product"}, 108 }, 109 }, 110 // product/app/% only applies to product apps inside the system partition 111 { 112 patterns: []string{"app/%", "product/app/%"}, 113 moduleTests: []moduleTest{ 114 {module: systemModule, expectedPartition: "system_other/system"}, 115 {module: systemProductModule, expectedPartition: "system_other/system/product"}, 116 {module: productModule, expectedPartition: "product"}, 117 }, 118 }, 119 } 120 121 for _, test := range tests { 122 global.PatternsOnSystemOther = test.patterns 123 for _, mt := range test.moduleTests { 124 rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module) 125 if err != nil { 126 t.Fatal(err) 127 } 128 129 name := mt.module.Name 130 wantInstalls := android.RuleBuilderInstalls{ 131 {android.PathForOutput(ctx, name+"/oat/arm/package.odex"), fmt.Sprintf("/%s/app/test/oat/arm/%s.odex", mt.expectedPartition, name)}, 132 {android.PathForOutput(ctx, name+"/oat/arm/package.vdex"), fmt.Sprintf("/%s/app/test/oat/arm/%s.vdex", mt.expectedPartition, name)}, 133 } 134 135 if rule.Installs().String() != wantInstalls.String() { 136 t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs()) 137 } 138 } 139 } 140 141} 142 143func TestDexPreoptProfile(t *testing.T) { 144 config := android.TestConfig("out", nil, "", nil) 145 ctx := android.BuilderContextForTesting(config) 146 globalSoong := globalSoongConfigForTests() 147 global := GlobalConfigForTests(ctx) 148 module := testSystemModuleConfig(ctx, "test") 149 150 module.ProfileClassListing = android.OptionalPathForPath(android.PathForTesting("profile")) 151 152 rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module) 153 if err != nil { 154 t.Fatal(err) 155 } 156 157 wantInstalls := android.RuleBuilderInstalls{ 158 {android.PathForOutput(ctx, "test/profile.prof"), "/system/app/test/test.apk.prof"}, 159 {android.PathForOutput(ctx, "test/oat/arm/package.art"), "/system/app/test/oat/arm/test.art"}, 160 {android.PathForOutput(ctx, "test/oat/arm/package.odex"), "/system/app/test/oat/arm/test.odex"}, 161 {android.PathForOutput(ctx, "test/oat/arm/package.vdex"), "/system/app/test/oat/arm/test.vdex"}, 162 } 163 164 if rule.Installs().String() != wantInstalls.String() { 165 t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs()) 166 } 167} 168 169func TestDexPreoptConfigToJson(t *testing.T) { 170 config := android.TestConfig("out", nil, "", nil) 171 ctx := android.BuilderContextForTesting(config) 172 module := testSystemModuleConfig(ctx, "test") 173 data, err := moduleConfigToJSON(module) 174 if err != nil { 175 t.Errorf("Failed to convert module config data to JSON, %v", err) 176 } 177 parsed, err := ParseModuleConfig(ctx, data) 178 if err != nil { 179 t.Errorf("Failed to parse JSON, %v", err) 180 } 181 before := fmt.Sprintf("%v", module) 182 after := fmt.Sprintf("%v", parsed) 183 android.AssertStringEquals(t, "The result must be the same as the original after marshalling and unmarshalling it.", before, after) 184} 185