platform_build_soong/etc/prebuilt_etc_test.go
Colin Cross 323dc60712 Make lots of tests run in parallel
Putting t.Parallel() in each test makes them run in parallel.
Additional t.Parallel() could be added to each subtest, although
that requires making a local copy of the loop variable for
table driven tests.

Test: m checkbuild
Change-Id: I5d9869ead441093f4d7c5757f2447385333a95a4
2020-10-06 15:12:22 -07:00

385 lines
9.9 KiB
Go

// Copyright 2018 Google Inc. All rights reserved.
//
// 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 etc
import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"testing"
"android/soong/android"
)
var buildDir string
func setUp() {
var err error
buildDir, err = ioutil.TempDir("", "soong_etc_test")
if err != nil {
panic(err)
}
}
func tearDown() {
os.RemoveAll(buildDir)
}
func TestMain(m *testing.M) {
run := func() int {
setUp()
defer tearDown()
return m.Run()
}
os.Exit(run())
}
func testPrebuiltEtcContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
fs := map[string][]byte{
"foo.conf": nil,
"bar.conf": nil,
"baz.conf": nil,
}
config := android.TestArchConfig(buildDir, nil, bp, fs)
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory)
ctx.Register(config)
return ctx, config
}
func testPrebuiltEtc(t *testing.T, bp string) (*android.TestContext, android.Config) {
t.Helper()
ctx, config := testPrebuiltEtcContext(t, bp)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
return ctx, config
}
func testPrebuiltEtcError(t *testing.T, pattern, bp string) {
t.Helper()
ctx, config := testPrebuiltEtcContext(t, bp)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
return
}
_, errs = ctx.PrepareBuildActions(config)
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
return
}
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}
func TestPrebuiltEtcVariants(t *testing.T) {
t.Parallel()
ctx, _ := testPrebuiltEtc(t, `
prebuilt_etc {
name: "foo.conf",
src: "foo.conf",
}
prebuilt_etc {
name: "bar.conf",
src: "bar.conf",
recovery_available: true,
}
prebuilt_etc {
name: "baz.conf",
src: "baz.conf",
recovery: true,
}
`)
foo_variants := ctx.ModuleVariantsForTests("foo.conf")
if len(foo_variants) != 1 {
t.Errorf("expected 1, got %#v", foo_variants)
}
bar_variants := ctx.ModuleVariantsForTests("bar.conf")
if len(bar_variants) != 2 {
t.Errorf("expected 2, got %#v", bar_variants)
}
baz_variants := ctx.ModuleVariantsForTests("baz.conf")
if len(baz_variants) != 1 {
t.Errorf("expected 1, got %#v", bar_variants)
}
}
func TestPrebuiltEtcOutputPath(t *testing.T) {
t.Parallel()
ctx, _ := testPrebuiltEtc(t, `
prebuilt_etc {
name: "foo.conf",
src: "foo.conf",
filename: "foo.installed.conf",
}
`)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
if p.outputFilePath.Base() != "foo.installed.conf" {
t.Errorf("expected foo.installed.conf, got %q", p.outputFilePath.Base())
}
}
func TestPrebuiltEtcGlob(t *testing.T) {
t.Parallel()
ctx, _ := testPrebuiltEtc(t, `
prebuilt_etc {
name: "my_foo",
src: "foo.*",
}
prebuilt_etc {
name: "my_bar",
src: "bar.*",
filename_from_src: true,
}
`)
p := ctx.ModuleForTests("my_foo", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
if p.outputFilePath.Base() != "my_foo" {
t.Errorf("expected my_foo, got %q", p.outputFilePath.Base())
}
p = ctx.ModuleForTests("my_bar", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
if p.outputFilePath.Base() != "bar.conf" {
t.Errorf("expected bar.conf, got %q", p.outputFilePath.Base())
}
}
func TestPrebuiltEtcAndroidMk(t *testing.T) {
t.Parallel()
ctx, config := testPrebuiltEtc(t, `
prebuilt_etc {
name: "foo",
src: "foo.conf",
owner: "abc",
filename_from_src: true,
required: ["modA", "moduleB"],
host_required: ["hostModA", "hostModB"],
target_required: ["targetModA"],
}
`)
expected := map[string][]string{
"LOCAL_MODULE": {"foo"},
"LOCAL_MODULE_CLASS": {"ETC"},
"LOCAL_MODULE_OWNER": {"abc"},
"LOCAL_INSTALLED_MODULE_STEM": {"foo.conf"},
"LOCAL_REQUIRED_MODULES": {"modA", "moduleB"},
"LOCAL_HOST_REQUIRED_MODULES": {"hostModA", "hostModB"},
"LOCAL_TARGET_REQUIRED_MODULES": {"targetModA"},
}
mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0]
for k, expectedValue := range expected {
if value, ok := entries.EntryMap[k]; ok {
if !reflect.DeepEqual(value, expectedValue) {
t.Errorf("Incorrect %s '%s', expected '%s'", k, value, expectedValue)
}
} else {
t.Errorf("No %s defined, saw %q", k, entries.EntryMap)
}
}
}
func TestPrebuiltEtcRelativeInstallPathInstallDirPath(t *testing.T) {
t.Parallel()
ctx, _ := testPrebuiltEtc(t, `
prebuilt_etc {
name: "foo.conf",
src: "foo.conf",
relative_install_path: "bar",
}
`)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
expected := buildDir + "/target/product/test_device/system/etc/bar"
if p.installDirPath.String() != expected {
t.Errorf("expected %q, got %q", expected, p.installDirPath.String())
}
}
func TestPrebuiltEtcCannotSetRelativeInstallPathAndSubDir(t *testing.T) {
t.Parallel()
testPrebuiltEtcError(t, "relative_install_path is set. Cannot set sub_dir", `
prebuilt_etc {
name: "foo.conf",
src: "foo.conf",
sub_dir: "bar",
relative_install_path: "bar",
}
`)
}
func TestPrebuiltEtcHost(t *testing.T) {
t.Parallel()
ctx, _ := testPrebuiltEtc(t, `
prebuilt_etc_host {
name: "foo.conf",
src: "foo.conf",
}
`)
buildOS := android.BuildOs.String()
p := ctx.ModuleForTests("foo.conf", buildOS+"_common").Module().(*PrebuiltEtc)
if !p.Host() {
t.Errorf("host bit is not set for a prebuilt_etc_host module.")
}
}
func TestPrebuiltUserShareInstallDirPath(t *testing.T) {
t.Parallel()
ctx, _ := testPrebuiltEtc(t, `
prebuilt_usr_share {
name: "foo.conf",
src: "foo.conf",
sub_dir: "bar",
}
`)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
expected := buildDir + "/target/product/test_device/system/usr/share/bar"
if p.installDirPath.String() != expected {
t.Errorf("expected %q, got %q", expected, p.installDirPath.String())
}
}
func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) {
t.Parallel()
ctx, config := testPrebuiltEtc(t, `
prebuilt_usr_share_host {
name: "foo.conf",
src: "foo.conf",
sub_dir: "bar",
}
`)
buildOS := android.BuildOs.String()
p := ctx.ModuleForTests("foo.conf", buildOS+"_common").Module().(*PrebuiltEtc)
expected := filepath.Join(buildDir, "host", config.PrebuiltOS(), "usr", "share", "bar")
if p.installDirPath.String() != expected {
t.Errorf("expected %q, got %q", expected, p.installDirPath.String())
}
}
func TestPrebuiltFontInstallDirPath(t *testing.T) {
t.Parallel()
ctx, _ := testPrebuiltEtc(t, `
prebuilt_font {
name: "foo.conf",
src: "foo.conf",
}
`)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
expected := buildDir + "/target/product/test_device/system/fonts"
if p.installDirPath.String() != expected {
t.Errorf("expected %q, got %q", expected, p.installDirPath.String())
}
}
func TestPrebuiltFirmwareDirPath(t *testing.T) {
t.Parallel()
targetPath := buildDir + "/target/product/test_device"
tests := []struct {
description string
config string
expectedPath string
}{{
description: "prebuilt: system firmware",
config: `
prebuilt_firmware {
name: "foo.conf",
src: "foo.conf",
}`,
expectedPath: filepath.Join(targetPath, "system/etc/firmware"),
}, {
description: "prebuilt: vendor firmware",
config: `
prebuilt_firmware {
name: "foo.conf",
src: "foo.conf",
soc_specific: true,
sub_dir: "sub_dir",
}`,
expectedPath: filepath.Join(targetPath, "vendor/firmware/sub_dir"),
}}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
ctx, _ := testPrebuiltEtc(t, tt.config)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
if p.installDirPath.String() != tt.expectedPath {
t.Errorf("expected %q, got %q", tt.expectedPath, p.installDirPath)
}
})
}
}
func TestPrebuiltDSPDirPath(t *testing.T) {
t.Parallel()
targetPath := filepath.Join(buildDir, "/target/product/test_device")
tests := []struct {
description string
config string
expectedPath string
}{{
description: "prebuilt: system dsp",
config: `
prebuilt_dsp {
name: "foo.conf",
src: "foo.conf",
}`,
expectedPath: filepath.Join(targetPath, "system/etc/dsp"),
}, {
description: "prebuilt: vendor dsp",
config: `
prebuilt_dsp {
name: "foo.conf",
src: "foo.conf",
soc_specific: true,
sub_dir: "sub_dir",
}`,
expectedPath: filepath.Join(targetPath, "vendor/dsp/sub_dir"),
}}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
ctx, _ := testPrebuiltEtc(t, tt.config)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a").Module().(*PrebuiltEtc)
if p.installDirPath.String() != tt.expectedPath {
t.Errorf("expected %q, got %q", tt.expectedPath, p.installDirPath)
}
})
}
}