Use OutputFilesProvider in module_test
In the context of incremental soong, the output files inter-module-communication will be through OutputFilesProvider. The OutputFileProducer interface will be deprecated. Test: CI Bug: 339477385 Change-Id: Iaf0b039b17d34e1a696f2c87df2f0db39307fc6d
This commit is contained in:
@@ -2491,18 +2491,9 @@ func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string)
|
|||||||
if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
|
if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
|
||||||
return outputFilesFromProvider, err
|
return outputFilesFromProvider, err
|
||||||
}
|
}
|
||||||
// TODO: add error when outputFilesFromProvider and err are both nil after
|
if sourceFileProducer, ok := module.(SourceFileProducer); ok {
|
||||||
// OutputFileProducer and SourceFileProducer are deprecated.
|
|
||||||
if outputFileProducer, ok := module.(OutputFileProducer); ok {
|
|
||||||
paths, err := outputFileProducer.OutputFiles(tag)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to get output file from module %q at tag %q: %s",
|
|
||||||
pathContextName(ctx, module), tag, err.Error())
|
|
||||||
}
|
|
||||||
return paths, nil
|
|
||||||
} else if sourceFileProducer, ok := module.(SourceFileProducer); ok {
|
|
||||||
if tag != "" {
|
if tag != "" {
|
||||||
return nil, fmt.Errorf("module %q is a SourceFileProducer, not an OutputFileProducer, and so does not support tag %q", pathContextName(ctx, module), tag)
|
return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag)
|
||||||
}
|
}
|
||||||
paths := sourceFileProducer.Srcs()
|
paths := sourceFileProducer.Srcs()
|
||||||
return paths, nil
|
return paths, nil
|
||||||
@@ -2521,7 +2512,12 @@ func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module,
|
|||||||
var outputFiles OutputFilesInfo
|
var outputFiles OutputFilesInfo
|
||||||
fromProperty := false
|
fromProperty := false
|
||||||
|
|
||||||
if mctx, isMctx := ctx.(ModuleContext); isMctx {
|
type OutputFilesProviderModuleContext interface {
|
||||||
|
OtherModuleProviderContext
|
||||||
|
Module() Module
|
||||||
|
}
|
||||||
|
|
||||||
|
if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
|
||||||
if mctx.Module() != module {
|
if mctx.Module() != module {
|
||||||
outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
|
outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
|
||||||
} else {
|
} else {
|
||||||
@@ -2535,7 +2531,6 @@ func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module,
|
|||||||
// TODO: Add a check for skipped context
|
// TODO: Add a check for skipped context
|
||||||
|
|
||||||
if outputFiles.isEmpty() {
|
if outputFiles.isEmpty() {
|
||||||
// TODO: Add a check for param module not having OutputFilesProvider set
|
|
||||||
return nil, OutputFilesProviderNotSet
|
return nil, OutputFilesProviderNotSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -935,31 +935,54 @@ func TestSetAndroidMkEntriesWithTestOptions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeBlueprintModule struct{}
|
|
||||||
|
|
||||||
func (fakeBlueprintModule) Name() string { return "foo" }
|
|
||||||
|
|
||||||
func (fakeBlueprintModule) GenerateBuildActions(blueprint.ModuleContext) {}
|
|
||||||
|
|
||||||
type sourceProducerTestModule struct {
|
type sourceProducerTestModule struct {
|
||||||
fakeBlueprintModule
|
ModuleBase
|
||||||
source Path
|
props struct {
|
||||||
|
// A represents the source file
|
||||||
|
A string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sourceProducerTestModule) Srcs() Paths { return Paths{s.source} }
|
func sourceProducerTestModuleFactory() Module {
|
||||||
|
module := &sourceProducerTestModule{}
|
||||||
type outputFileProducerTestModule struct {
|
module.AddProperties(&module.props)
|
||||||
fakeBlueprintModule
|
InitAndroidModule(module)
|
||||||
output map[string]Path
|
return module
|
||||||
error map[string]error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o outputFileProducerTestModule) OutputFiles(tag string) (Paths, error) {
|
func (s sourceProducerTestModule) GenerateAndroidBuildActions(ModuleContext) {}
|
||||||
return PathsIfNonNil(o.output[tag]), o.error[tag]
|
|
||||||
|
func (s sourceProducerTestModule) Srcs() Paths { return PathsForTesting(s.props.A) }
|
||||||
|
|
||||||
|
type outputFilesTestModule struct {
|
||||||
|
ModuleBase
|
||||||
|
props struct {
|
||||||
|
// A represents the tag
|
||||||
|
A string
|
||||||
|
// B represents the output file for tag A
|
||||||
|
B string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func outputFilesTestModuleFactory() Module {
|
||||||
|
module := &outputFilesTestModule{}
|
||||||
|
module.AddProperties(&module.props)
|
||||||
|
InitAndroidModule(module)
|
||||||
|
return module
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o outputFilesTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
|
if o.props.A != "" || o.props.B != "" {
|
||||||
|
ctx.SetOutputFiles(PathsForTesting(o.props.B), o.props.A)
|
||||||
|
}
|
||||||
|
// This is to simulate the case that some module uses an object to set its
|
||||||
|
// OutputFilesProvider, but the object itself is empty.
|
||||||
|
ctx.SetOutputFiles(Paths{}, "missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
type pathContextAddMissingDependenciesWrapper struct {
|
type pathContextAddMissingDependenciesWrapper struct {
|
||||||
PathContext
|
PathContext
|
||||||
|
OtherModuleProviderContext
|
||||||
missingDeps []string
|
missingDeps []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -970,52 +993,87 @@ func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module bluepr
|
|||||||
return module.Name()
|
return module.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *pathContextAddMissingDependenciesWrapper) Module() Module { return nil }
|
||||||
|
|
||||||
func TestOutputFileForModule(t *testing.T) {
|
func TestOutputFileForModule(t *testing.T) {
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
name string
|
name string
|
||||||
module blueprint.Module
|
bp string
|
||||||
tag string
|
tag string
|
||||||
env map[string]string
|
|
||||||
config func(*config)
|
|
||||||
expected string
|
expected string
|
||||||
missingDeps []string
|
missingDeps []string
|
||||||
|
env map[string]string
|
||||||
|
config func(*config)
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "SourceFileProducer",
|
name: "SourceFileProducer",
|
||||||
module: &sourceProducerTestModule{source: PathForTesting("foo.txt")},
|
bp: `spt_module {
|
||||||
expected: "foo.txt",
|
name: "test_module",
|
||||||
|
a: "spt.txt",
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
tag: "",
|
||||||
|
expected: "spt.txt",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OutputFileProducer",
|
name: "OutputFileProviderEmptyStringTag",
|
||||||
module: &outputFileProducerTestModule{output: map[string]Path{"": PathForTesting("foo.txt")}},
|
bp: `oft_module {
|
||||||
expected: "foo.txt",
|
name: "test_module",
|
||||||
|
a: "",
|
||||||
|
b: "empty.txt",
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
tag: "",
|
||||||
|
expected: "empty.txt",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OutputFileProducer_tag",
|
name: "OutputFileProviderTag",
|
||||||
module: &outputFileProducerTestModule{output: map[string]Path{"foo": PathForTesting("foo.txt")}},
|
bp: `oft_module {
|
||||||
|
name: "test_module",
|
||||||
|
a: "foo",
|
||||||
|
b: "foo.txt",
|
||||||
|
}
|
||||||
|
`,
|
||||||
tag: "foo",
|
tag: "foo",
|
||||||
expected: "foo.txt",
|
expected: "foo.txt",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OutputFileProducer_AllowMissingDependencies",
|
name: "OutputFileAllowMissingDependencies",
|
||||||
|
bp: `oft_module {
|
||||||
|
name: "test_module",
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
tag: "missing",
|
||||||
|
expected: "missing_output_file/test_module",
|
||||||
|
missingDeps: []string{"test_module"},
|
||||||
config: func(config *config) {
|
config: func(config *config) {
|
||||||
config.TestProductVariables.Allow_missing_dependencies = boolPtr(true)
|
config.TestProductVariables.Allow_missing_dependencies = boolPtr(true)
|
||||||
},
|
},
|
||||||
module: &outputFileProducerTestModule{},
|
|
||||||
missingDeps: []string{"foo"},
|
|
||||||
expected: "missing_output_file/foo",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range testcases {
|
for _, tt := range testcases {
|
||||||
config := TestConfig(buildDir, tt.env, "", nil)
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if tt.config != nil {
|
result := GroupFixturePreparers(
|
||||||
tt.config(config.config)
|
PrepareForTestWithDefaults,
|
||||||
}
|
FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
||||||
ctx := &pathContextAddMissingDependenciesWrapper{
|
ctx.RegisterModuleType("spt_module", sourceProducerTestModuleFactory)
|
||||||
PathContext: PathContextForTesting(config),
|
ctx.RegisterModuleType("oft_module", outputFilesTestModuleFactory)
|
||||||
}
|
}),
|
||||||
got := OutputFileForModule(ctx, tt.module, tt.tag)
|
FixtureWithRootAndroidBp(tt.bp),
|
||||||
AssertPathRelativeToTopEquals(t, "expected source path", tt.expected, got)
|
).RunTest(t)
|
||||||
AssertArrayString(t, "expected missing deps", tt.missingDeps, ctx.missingDeps)
|
|
||||||
|
config := TestConfig(buildDir, tt.env, tt.bp, nil)
|
||||||
|
if tt.config != nil {
|
||||||
|
tt.config(config.config)
|
||||||
|
}
|
||||||
|
ctx := &pathContextAddMissingDependenciesWrapper{
|
||||||
|
PathContext: PathContextForTesting(config),
|
||||||
|
OtherModuleProviderContext: result.TestContext.OtherModuleProviderAdaptor(),
|
||||||
|
}
|
||||||
|
got := OutputFileForModule(ctx, result.ModuleForTests("test_module", "").Module(), tt.tag)
|
||||||
|
AssertPathRelativeToTopEquals(t, "expected output path", tt.expected, got)
|
||||||
|
AssertArrayString(t, "expected missing deps", tt.missingDeps, ctx.missingDeps)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user