Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 489be090 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Move functionality to test install rules into testing.go."

parents 92a21ddb 1ebef5b7
Loading
Loading
Loading
Loading
+27 −84
Original line number Diff line number Diff line
@@ -15,12 +15,9 @@
package android

import (
	"bytes"
	"path/filepath"
	"runtime"
	"testing"

	mkparser "android/soong/androidmk/parser"
)

func TestSrcIsModule(t *testing.T) {
@@ -475,21 +472,10 @@ func TestInstallKatiEnabled(t *testing.T) {
		prepareForModuleTests,
		PrepareForTestWithArchMutator,
		FixtureModifyConfig(SetKatiEnabledForTests),
		FixtureRegisterWithContext(func(ctx RegistrationContext) {
			ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
		}),
		PrepareForTestWithMakevars,
	).RunTestWithBp(t, bp)

	installs := result.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting
	buf := bytes.NewBuffer(append([]byte(nil), installs...))
	parser := mkparser.NewParser("makevars", buf)

	nodes, errs := parser.Parse()
	if len(errs) > 0 {
		t.Fatalf("error parsing install rules: %s", errs[0])
	}

	rules := parseMkRules(t, result.Config, nodes)
	rules := result.InstallMakeRulesForTesting(t)

	module := func(name string, host bool) TestingModule {
		variant := "android_common"
@@ -501,121 +487,78 @@ func TestInstallKatiEnabled(t *testing.T) {

	outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }

	ruleForOutput := func(output string) installMakeRule {
	ruleForOutput := func(output string) InstallMakeRule {
		for _, rule := range rules {
			if rule.target == output {
			if rule.Target == output {
				return rule
			}
		}
		t.Fatalf("no make install rule for %s", output)
		return installMakeRule{}
		return InstallMakeRule{}
	}

	installRule := func(name string) installMakeRule {
	installRule := func(name string) InstallMakeRule {
		return ruleForOutput(filepath.Join("out/target/product/test_device/system", name))
	}

	symlinkRule := func(name string) installMakeRule {
	symlinkRule := func(name string) InstallMakeRule {
		return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name))
	}

	hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }

	hostInstallRule := func(name string) installMakeRule {
	hostInstallRule := func(name string) InstallMakeRule {
		return ruleForOutput(filepath.Join("out/host/linux-x86", name))
	}

	hostSymlinkRule := func(name string) installMakeRule {
	hostSymlinkRule := func(name string) InstallMakeRule {
		return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name))
	}

	assertDeps := func(rule installMakeRule, deps ...string) {
	assertDeps := func(rule InstallMakeRule, deps ...string) {
		t.Helper()
		AssertArrayString(t, "expected inputs", deps, rule.deps)
		AssertArrayString(t, "expected inputs", deps, rule.Deps)
	}

	assertOrderOnlys := func(rule installMakeRule, orderonlys ...string) {
	assertOrderOnlys := func(rule InstallMakeRule, orderonlys ...string) {
		t.Helper()
		AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.orderOnlyDeps)
		AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.OrderOnlyDeps)
	}

	// Check host install rule dependencies
	assertDeps(hostInstallRule("foo"),
		hostOutputRule("foo").Output.String(),
		hostInstallRule("bar").target,
		hostSymlinkRule("bar").target,
		hostInstallRule("baz").target,
		hostSymlinkRule("baz").target,
		hostInstallRule("qux").target,
		hostSymlinkRule("qux").target,
		hostInstallRule("bar").Target,
		hostSymlinkRule("bar").Target,
		hostInstallRule("baz").Target,
		hostSymlinkRule("baz").Target,
		hostInstallRule("qux").Target,
		hostSymlinkRule("qux").Target,
	)
	assertOrderOnlys(hostInstallRule("foo"))

	// Check host symlink rule dependencies.  Host symlinks must use a normal dependency, not an
	// order-only dependency, so that the tool gets updated when the symlink is depended on.
	assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").target)
	assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").Target)
	assertOrderOnlys(hostSymlinkRule("foo"))

	// Check device install rule dependencies
	assertDeps(installRule("foo"), outputRule("foo").Output.String())
	assertOrderOnlys(installRule("foo"),
		installRule("bar").target,
		symlinkRule("bar").target,
		installRule("baz").target,
		symlinkRule("baz").target,
		installRule("qux").target,
		symlinkRule("qux").target,
		installRule("bar").Target,
		symlinkRule("bar").Target,
		installRule("baz").Target,
		symlinkRule("baz").Target,
		installRule("qux").Target,
		symlinkRule("qux").Target,
	)

	// Check device symlink rule dependencies.  Device symlinks could use an order-only dependency,
	// but the current implementation uses a normal dependency.
	assertDeps(symlinkRule("foo"), installRule("foo").target)
	assertDeps(symlinkRule("foo"), installRule("foo").Target)
	assertOrderOnlys(symlinkRule("foo"))
}

type installMakeRule struct {
	target        string
	deps          []string
	orderOnlyDeps []string
}

func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []installMakeRule {
	var rules []installMakeRule
	for _, node := range nodes {
		if mkParserRule, ok := node.(*mkparser.Rule); ok {
			var rule installMakeRule

			if targets := mkParserRule.Target.Words(); len(targets) == 0 {
				t.Fatalf("no targets for rule %s", mkParserRule.Dump())
			} else if len(targets) > 1 {
				t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump())
			} else if !targets[0].Const() {
				t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump())
			} else {
				rule.target = normalizeStringRelativeToTop(config, targets[0].Value(nil))
			}

			prereqList := &rule.deps
			for _, prereq := range mkParserRule.Prerequisites.Words() {
				if !prereq.Const() {
					t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump())
				}

				if prereq.Value(nil) == "|" {
					prereqList = &rule.orderOnlyDeps
					continue
				}

				*prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil)))
			}

			rules = append(rules, rule)
		}
	}

	return rules
}

type PropsTestModuleEmbedded struct {
	Embedded_prop *string
}
+1 −1
Original line number Diff line number Diff line
@@ -46,8 +46,8 @@ var prepareForSingletonModuleTest = GroupFixturePreparers(
	PrepareForTestWithAndroidMk,
	FixtureRegisterWithContext(func(ctx RegistrationContext) {
		ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory)
		ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
	}),
	PrepareForTestWithMakevars,
)

func TestSingletonModule(t *testing.T) {
+63 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package android

import (
	"bytes"
	"fmt"
	"path/filepath"
	"regexp"
@@ -23,6 +24,8 @@ import (
	"sync"
	"testing"

	mkparser "android/soong/androidmk/parser"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)
@@ -115,6 +118,10 @@ var PrepareForTestWithNamespace = FixtureRegisterWithContext(func(ctx Registrati
	ctx.PreArchMutators(RegisterNamespaceMutator)
})

var PrepareForTestWithMakevars = FixtureRegisterWithContext(func(ctx RegistrationContext) {
	ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
})

// Test fixture preparer that will register most java build components.
//
// Singletons and mutators should only be added here if they are needed for a majority of java
@@ -602,6 +609,62 @@ func (ctx *TestContext) SingletonForTests(name string) TestingSingleton {
		"\nall singletons: %v", name, allSingletonNames))
}

type InstallMakeRule struct {
	Target        string
	Deps          []string
	OrderOnlyDeps []string
}

func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []InstallMakeRule {
	var rules []InstallMakeRule
	for _, node := range nodes {
		if mkParserRule, ok := node.(*mkparser.Rule); ok {
			var rule InstallMakeRule

			if targets := mkParserRule.Target.Words(); len(targets) == 0 {
				t.Fatalf("no targets for rule %s", mkParserRule.Dump())
			} else if len(targets) > 1 {
				t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump())
			} else if !targets[0].Const() {
				t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump())
			} else {
				rule.Target = normalizeStringRelativeToTop(config, targets[0].Value(nil))
			}

			prereqList := &rule.Deps
			for _, prereq := range mkParserRule.Prerequisites.Words() {
				if !prereq.Const() {
					t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump())
				}

				if prereq.Value(nil) == "|" {
					prereqList = &rule.OrderOnlyDeps
					continue
				}

				*prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil)))
			}

			rules = append(rules, rule)
		}
	}

	return rules
}

func (ctx *TestContext) InstallMakeRulesForTesting(t *testing.T) []InstallMakeRule {
	installs := ctx.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting
	buf := bytes.NewBuffer(append([]byte(nil), installs...))
	parser := mkparser.NewParser("makevars", buf)

	nodes, errs := parser.Parse()
	if len(errs) > 0 {
		t.Fatalf("error parsing install rules: %s", errs[0])
	}

	return parseMkRules(t, ctx.config, nodes)
}

func (ctx *TestContext) Config() Config {
	return ctx.config
}