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 etc 16 17import ( 18 "io/ioutil" 19 "os" 20 "path/filepath" 21 "reflect" 22 "testing" 23 24 "android/soong/android" 25) 26 27var buildDir string 28 29func setUp() { 30 var err error 31 buildDir, err = ioutil.TempDir("", "soong_etc_test") 32 if err != nil { 33 panic(err) 34 } 35} 36 37func tearDown() { 38 os.RemoveAll(buildDir) 39} 40 41func TestMain(m *testing.M) { 42 run := func() int { 43 setUp() 44 defer tearDown() 45 46 return m.Run() 47 } 48 49 os.Exit(run()) 50} 51 52func testPrebuiltEtc(t *testing.T, bp string) (*android.TestContext, android.Config) { 53 fs := map[string][]byte{ 54 "foo.conf": nil, 55 "bar.conf": nil, 56 "baz.conf": nil, 57 } 58 59 config := android.TestArchConfig(buildDir, nil, bp, fs) 60 61 ctx := android.NewTestArchContext() 62 ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory) 63 ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory) 64 ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory) 65 ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory) 66 ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory) 67 ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory) 68 ctx.Register(config) 69 _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) 70 android.FailIfErrored(t, errs) 71 _, errs = ctx.PrepareBuildActions(config) 72 android.FailIfErrored(t, errs) 73 74 return ctx, config 75} 76 77func TestPrebuiltEtcVariants(t *testing.T) { 78 ctx, _ := testPrebuiltEtc(t, ` 79 prebuilt_etc { 80 name: "foo.conf", 81 src: "foo.conf", 82 } 83 prebuilt_etc { 84 name: "bar.conf", 85 src: "bar.conf", 86 recovery_available: true, 87 } 88 prebuilt_etc { 89 name: "baz.conf", 90 src: "baz.conf", 91 recovery: true, 92 } 93 `) 94 95 foo_variants := ctx.ModuleVariantsForTests("foo.conf") 96 if len(foo_variants) != 1 { 97 t.Errorf("expected 1, got %#v", foo_variants) 98 } 99 100 bar_variants := ctx.ModuleVariantsForTests("bar.conf") 101 if len(bar_variants) != 2 { 102 t.Errorf("expected 2, got %#v", bar_variants) 103 } 104 105 baz_variants := ctx.ModuleVariantsForTests("baz.conf") 106 if len(baz_variants) != 1 { 107 t.Errorf("expected 1, got %#v", bar_variants) 108 } 109} 110 111func TestPrebuiltEtcOutputPath(t *testing.T) { 112 ctx, _ := testPrebuiltEtc(t, ` 113 prebuilt_etc { 114 name: "foo.conf", 115 src: "foo.conf", 116 filename: "foo.installed.conf", 117 } 118 `) 119 120 p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc) 121 if p.outputFilePath.Base() != "foo.installed.conf" { 122 t.Errorf("expected foo.installed.conf, got %q", p.outputFilePath.Base()) 123 } 124} 125 126func TestPrebuiltEtcGlob(t *testing.T) { 127 ctx, _ := testPrebuiltEtc(t, ` 128 prebuilt_etc { 129 name: "my_foo", 130 src: "foo.*", 131 } 132 prebuilt_etc { 133 name: "my_bar", 134 src: "bar.*", 135 filename_from_src: true, 136 } 137 `) 138 139 p := ctx.ModuleForTests("my_foo", "android_arm64_armv8-a").Module().(*PrebuiltEtc) 140 if p.outputFilePath.Base() != "my_foo" { 141 t.Errorf("expected my_foo, got %q", p.outputFilePath.Base()) 142 } 143 144 p = ctx.ModuleForTests("my_bar", "android_arm64_armv8-a").Module().(*PrebuiltEtc) 145 if p.outputFilePath.Base() != "bar.conf" { 146 t.Errorf("expected bar.conf, got %q", p.outputFilePath.Base()) 147 } 148} 149 150func TestPrebuiltEtcAndroidMk(t *testing.T) { 151 ctx, config := testPrebuiltEtc(t, ` 152 prebuilt_etc { 153 name: "foo", 154 src: "foo.conf", 155 owner: "abc", 156 filename_from_src: true, 157 required: ["modA", "moduleB"], 158 host_required: ["hostModA", "hostModB"], 159 target_required: ["targetModA"], 160 } 161 `) 162 163 expected := map[string][]string{ 164 "LOCAL_MODULE": {"foo"}, 165 "LOCAL_MODULE_CLASS": {"ETC"}, 166 "LOCAL_MODULE_OWNER": {"abc"}, 167 "LOCAL_INSTALLED_MODULE_STEM": {"foo.conf"}, 168 "LOCAL_REQUIRED_MODULES": {"modA", "moduleB"}, 169 "LOCAL_HOST_REQUIRED_MODULES": {"hostModA", "hostModB"}, 170 "LOCAL_TARGET_REQUIRED_MODULES": {"targetModA"}, 171 } 172 173 mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*PrebuiltEtc) 174 entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0] 175 for k, expectedValue := range expected { 176 if value, ok := entries.EntryMap[k]; ok { 177 if !reflect.DeepEqual(value, expectedValue) { 178 t.Errorf("Incorrect %s '%s', expected '%s'", k, value, expectedValue) 179 } 180 } else { 181 t.Errorf("No %s defined, saw %q", k, entries.EntryMap) 182 } 183 } 184} 185 186func TestPrebuiltEtcHost(t *testing.T) { 187 ctx, _ := testPrebuiltEtc(t, ` 188 prebuilt_etc_host { 189 name: "foo.conf", 190 src: "foo.conf", 191 } 192 `) 193 194 buildOS := android.BuildOs.String() 195 p := ctx.ModuleForTests("foo.conf", buildOS+"_common").Module().(*PrebuiltEtc) 196 if !p.Host() { 197 t.Errorf("host bit is not set for a prebuilt_etc_host module.") 198 } 199} 200 201func TestPrebuiltUserShareInstallDirPath(t *testing.T) { 202 ctx, _ := testPrebuiltEtc(t, ` 203 prebuilt_usr_share { 204 name: "foo.conf", 205 src: "foo.conf", 206 sub_dir: "bar", 207 } 208 `) 209 210 p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc) 211 expected := buildDir + "/target/product/test_device/system/usr/share/bar" 212 if p.installDirPath.String() != expected { 213 t.Errorf("expected %q, got %q", expected, p.installDirPath.String()) 214 } 215} 216 217func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) { 218 ctx, config := testPrebuiltEtc(t, ` 219 prebuilt_usr_share_host { 220 name: "foo.conf", 221 src: "foo.conf", 222 sub_dir: "bar", 223 } 224 `) 225 226 buildOS := android.BuildOs.String() 227 p := ctx.ModuleForTests("foo.conf", buildOS+"_common").Module().(*PrebuiltEtc) 228 expected := filepath.Join(buildDir, "host", config.PrebuiltOS(), "usr", "share", "bar") 229 if p.installDirPath.String() != expected { 230 t.Errorf("expected %q, got %q", expected, p.installDirPath.String()) 231 } 232} 233 234func TestPrebuiltFontInstallDirPath(t *testing.T) { 235 ctx, _ := testPrebuiltEtc(t, ` 236 prebuilt_font { 237 name: "foo.conf", 238 src: "foo.conf", 239 } 240 `) 241 242 p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc) 243 expected := buildDir + "/target/product/test_device/system/fonts" 244 if p.installDirPath.String() != expected { 245 t.Errorf("expected %q, got %q", expected, p.installDirPath.String()) 246 } 247} 248 249func TestPrebuiltFirmwareDirPath(t *testing.T) { 250 targetPath := buildDir + "/target/product/test_device" 251 tests := []struct { 252 description string 253 config string 254 expectedPath string 255 }{{ 256 description: "prebuilt: system firmware", 257 config: ` 258 prebuilt_firmware { 259 name: "foo.conf", 260 src: "foo.conf", 261 }`, 262 expectedPath: filepath.Join(targetPath, "system/etc/firmware"), 263 }, { 264 description: "prebuilt: vendor firmware", 265 config: ` 266 prebuilt_firmware { 267 name: "foo.conf", 268 src: "foo.conf", 269 soc_specific: true, 270 sub_dir: "sub_dir", 271 }`, 272 expectedPath: filepath.Join(targetPath, "vendor/firmware/sub_dir"), 273 }} 274 for _, tt := range tests { 275 t.Run(tt.description, func(t *testing.T) { 276 ctx, _ := testPrebuiltEtc(t, tt.config) 277 p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc) 278 if p.installDirPath.String() != tt.expectedPath { 279 t.Errorf("expected %q, got %q", tt.expectedPath, p.installDirPath) 280 } 281 }) 282 } 283} 284