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

Commit 709e0e32 authored by Paul Duffin's avatar Paul Duffin
Browse files

Add TestingBuildParams.RelativeToTop()

The methods returns a copy of TestingBuildParams with every usage of a
path that is relative to the temporary test build directory with a path
relative to a notional top. Similar to how PathRelativeToTop does.

Bug: 182885307
Test: m nothing
Change-Id: I6ec20fc52ed76748138f0d48b4df80f765dfcfdc
parent 4e6e35c5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -697,7 +697,7 @@ func findModuleById(ctx *TestContext, id string) (module TestingModule) {
		testModule, ok := candidate.(*testModule)
		if ok {
			if testModule.properties.Id == id {
				module = newTestingModule(testModule)
				module = newTestingModule(ctx.config, testModule)
			}
		}
	}
+11 −13
Original line number Diff line number Diff line
@@ -562,46 +562,44 @@ func TestRuleBuilder_Build(t *testing.T) {
		AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat)

		wantImplicits := append([]string{"bar"}, extraImplicits...)
		AssertArrayString(t, "Implicits", wantImplicits, params.Implicits.Strings())
		AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits)

		AssertStringEquals(t, "Output", wantOutput, params.Output.String())
		AssertPathRelativeToTopEquals(t, "Output", wantOutput, params.Output)

		if len(params.ImplicitOutputs) != 0 {
			t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings())
		}

		AssertStringEquals(t, "Depfile", wantDepfile, params.Depfile.String())
		AssertPathRelativeToTopEquals(t, "Depfile", wantDepfile, params.Depfile)

		if params.Deps != blueprint.DepsGCC {
			t.Errorf("want Deps = %q, got %q", blueprint.DepsGCC, params.Deps)
		}
	}

	buildDir := result.Config.BuildDir()

	t.Run("module", func(t *testing.T) {
		outFile := filepath.Join(buildDir, ".intermediates", "foo", "gen", "foo")
		check(t, result.ModuleForTests("foo", "").Rule("rule"),
		outFile := "out/soong/.intermediates/foo/gen/foo"
		check(t, result.ModuleForTests("foo", "").Rule("rule").RelativeToTop(),
			"cp bar "+outFile,
			outFile, outFile+".d", true, nil, nil)
	})
	t.Run("sbox", func(t *testing.T) {
		outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox")
		outDir := "out/soong/.intermediates/foo_sbox"
		outFile := filepath.Join(outDir, "gen/foo_sbox")
		depFile := filepath.Join(outDir, "gen/foo_sbox.d")
		manifest := filepath.Join(outDir, "sbox.textproto")
		sbox := filepath.Join(buildDir, "host", result.Config.PrebuiltOS(), "bin/sbox")
		sandboxPath := shared.TempDirForOutDir(buildDir)
		sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox")
		sandboxPath := shared.TempDirForOutDir("out/soong")

		cmd := `rm -rf ` + outDir + `/gen && ` +
			sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest

		check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox"),
		check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox").RelativeToTop(),
			cmd, outFile, depFile, false, []string{manifest}, []string{sbox})
	})
	t.Run("singleton", func(t *testing.T) {
		outFile := filepath.Join(buildDir, "singleton/gen/baz")
		check(t, result.SingletonForTests("rule_builder_test").Rule("rule"),
		outFile := filepath.Join("out/soong/singleton/gen/baz")
		check(t, result.SingletonForTests("rule_builder_test").Rule("rule").RelativeToTop(),
			"cp bar "+outFile, outFile, outFile+".d", true, nil, nil)
	})
}
+105 −6
Original line number Diff line number Diff line
@@ -479,7 +479,7 @@ func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule {
		}
	}

	return newTestingModule(module)
	return newTestingModule(ctx.config, module)
}

func (ctx *TestContext) ModuleVariantsForTests(name string) []string {
@@ -499,7 +499,7 @@ func (ctx *TestContext) SingletonForTests(name string) TestingSingleton {
		n := ctx.SingletonName(s)
		if n == name {
			return TestingSingleton{
				baseTestingComponent: newBaseTestingComponent(s.(testBuildProvider)),
				baseTestingComponent: newBaseTestingComponent(ctx.config, s.(testBuildProvider)),
				singleton:            s.(*singletonAdaptor).Singleton,
			}
		}
@@ -522,19 +522,118 @@ type testBuildProvider interface {
type TestingBuildParams struct {
	BuildParams
	RuleParams blueprint.RuleParams

	config Config
}

// RelativeToTop creates a new instance of this which has had any usages of the current test's
// temporary and test specific build directory replaced with a path relative to the notional top.
//
// The parts of this structure which are changed are:
// * BuildParams
//   * Args
//   * Path instances are intentionally not modified, use AssertPathRelativeToTopEquals or
//     AssertPathsRelativeToTopEquals instead which do something similar.
//
// * RuleParams
//   * Command
//   * Depfile
//   * Rspfile
//   * RspfileContent
//   * SymlinkOutputs
//   * CommandDeps
//   * CommandOrderOnly
//
// See PathRelativeToTop for more details.
func (p TestingBuildParams) RelativeToTop() TestingBuildParams {
	// If this is not a valid params then just return it back. That will make it easy to use with the
	// Maybe...() methods.
	if p.Rule == nil {
		return p
	}
	if p.config.config == nil {
		panic("cannot call RelativeToTop() on a TestingBuildParams previously returned by RelativeToTop()")
	}
	// Take a copy of the build params and replace any args that contains test specific temporary
	// paths with paths relative to the top.
	bparams := p.BuildParams
	bparams.Args = normalizeStringMapRelativeToTop(p.config, bparams.Args)

	// Ditto for any fields in the RuleParams.
	rparams := p.RuleParams
	rparams.Command = normalizeStringRelativeToTop(p.config, rparams.Command)
	rparams.Depfile = normalizeStringRelativeToTop(p.config, rparams.Depfile)
	rparams.Rspfile = normalizeStringRelativeToTop(p.config, rparams.Rspfile)
	rparams.RspfileContent = normalizeStringRelativeToTop(p.config, rparams.RspfileContent)
	rparams.SymlinkOutputs = normalizeStringArrayRelativeToTop(p.config, rparams.SymlinkOutputs)
	rparams.CommandDeps = normalizeStringArrayRelativeToTop(p.config, rparams.CommandDeps)
	rparams.CommandOrderOnly = normalizeStringArrayRelativeToTop(p.config, rparams.CommandOrderOnly)

	return TestingBuildParams{
		BuildParams: bparams,
		RuleParams:  rparams,
	}
}

// baseTestingComponent provides functionality common to both TestingModule and TestingSingleton.
type baseTestingComponent struct {
	config   Config
	provider testBuildProvider
}

func newBaseTestingComponent(provider testBuildProvider) baseTestingComponent {
	return baseTestingComponent{provider}
func newBaseTestingComponent(config Config, provider testBuildProvider) baseTestingComponent {
	return baseTestingComponent{config, provider}
}

// A function that will normalize a string containing paths, e.g. ninja command, by replacing
// any references to the test specific temporary build directory that changes with each run to a
// fixed path relative to a notional top directory.
//
// This is similar to StringPathRelativeToTop except that assumes the string is a single path
// containing at most one instance of the temporary build directory at the start of the path while
// this assumes that there can be any number at any position.
func normalizeStringRelativeToTop(config Config, s string) string {
	// The buildDir usually looks something like: /tmp/testFoo2345/001
	//
	// Replace any usage of the buildDir with out/soong, e.g. replace "/tmp/testFoo2345/001" with
	// "out/soong".
	outSoongDir := filepath.Clean(config.buildDir)
	re := regexp.MustCompile(`\Q` + outSoongDir + `\E\b`)
	s = re.ReplaceAllString(s, "out/soong")

	// Replace any usage of the buildDir/.. with out, e.g. replace "/tmp/testFoo2345" with
	// "out". This must come after the previous replacement otherwise this would replace
	// "/tmp/testFoo2345/001" with "out/001" instead of "out/soong".
	outDir := filepath.Dir(outSoongDir)
	re = regexp.MustCompile(`\Q` + outDir + `\E\b`)
	s = re.ReplaceAllString(s, "out")

	return s
}

// normalizeStringArrayRelativeToTop creates a new slice constructed by applying
// normalizeStringRelativeToTop to each item in the slice.
func normalizeStringArrayRelativeToTop(config Config, slice []string) []string {
	newSlice := make([]string, len(slice))
	for i, s := range slice {
		newSlice[i] = normalizeStringRelativeToTop(config, s)
	}
	return newSlice
}

// normalizeStringMapRelativeToTop creates a new map constructed by applying
// normalizeStringRelativeToTop to each value in the map.
func normalizeStringMapRelativeToTop(config Config, m map[string]string) map[string]string {
	newMap := map[string]string{}
	for k, v := range m {
		newMap[k] = normalizeStringRelativeToTop(config, v)
	}
	return newMap
}

func (b baseTestingComponent) newTestingBuildParams(bparams BuildParams) TestingBuildParams {
	return TestingBuildParams{
		config:      b.config,
		BuildParams: bparams,
		RuleParams:  b.provider.RuleParamsForTests()[bparams.Rule],
	}
@@ -665,9 +764,9 @@ type TestingModule struct {
	module Module
}

func newTestingModule(module Module) TestingModule {
func newTestingModule(config Config, module Module) TestingModule {
	return TestingModule{
		newBaseTestingComponent(module),
		newBaseTestingComponent(config, module),
		module,
	}
}