Separate dist processing from make specific output
Previously, the GetDistForGoals(Module) func combined the processing of the dist properties with generating the make specific rules for generating that dist. That has a couple of problems: 1. It combines two pieces of functionality into one method which is bad practice. 2. It makes it hard to test because the make specific output ends up containing absolute paths to temporary directories created by the test. 3. It makes switching to a non-make output difficult and fragile as changing the output will also require changing the tests. This change adds an intermediate data structure to contain the result of the dist processing. That processing is done by the new method getDistContributions(Module) which returns the new intermediate structure. It also adds generateDistContributionsForMake(..) to generate the make output. The GetDistForGoals(Module) func uses them to implement the previous behavior. It adds identical tests to those in TestGetDistForGoals() but leaves those tests alone to show that this refactoring does not change the behavior. Follow up changes will clean up TestGetDistForGoals(). It also adds a test for generateDistContributionsForMake(..). Bug: 174226317 Test: m nothing m dist sdk - before and after this change, compare result to make sure that there are no significant differences. Change-Id: I458b7c8e4485bf66d3498f50df85a8d65fc2ee00
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -110,6 +111,27 @@ func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testin
|
||||
assertEqual([]string{"qux"}, m.data.Target_required)
|
||||
}
|
||||
|
||||
func TestGenerateDistContributionsForMake(t *testing.T) {
|
||||
dc := &distContributions{
|
||||
copiesForGoals: []*copiesForGoals{
|
||||
{
|
||||
goals: "my_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "one.out"),
|
||||
distCopyForTest("two.out", "other.out"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
makeOutput := generateDistContributionsForMake(dc)
|
||||
|
||||
assertStringEquals(t, `.PHONY: my_goal
|
||||
$(call dist-for-goals,my_goal,one.out:one.out)
|
||||
$(call dist-for-goals,my_goal,two.out:other.out)
|
||||
`, strings.Join(makeOutput, ""))
|
||||
}
|
||||
|
||||
func TestGetDistForGoals(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -293,3 +315,280 @@ func TestGetDistForGoals(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func distCopyForTest(from, to string) distCopy {
|
||||
return distCopy{PathForTesting(from), to}
|
||||
}
|
||||
|
||||
func TestGetDistContributions(t *testing.T) {
|
||||
compareContributions := func(d1 *distContributions, d2 *distContributions) error {
|
||||
if d1 == nil || d2 == nil {
|
||||
if d1 != d2 {
|
||||
return fmt.Errorf("pointer mismatch, expected both to be nil but they were %p and %p", d1, d2)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if expected, actual := len(d1.copiesForGoals), len(d2.copiesForGoals); expected != actual {
|
||||
return fmt.Errorf("length mismatch, expected %d found %d", expected, actual)
|
||||
}
|
||||
|
||||
for i, copies1 := range d1.copiesForGoals {
|
||||
copies2 := d2.copiesForGoals[i]
|
||||
if expected, actual := copies1.goals, copies2.goals; expected != actual {
|
||||
return fmt.Errorf("goals mismatch at position %d: expected %q found %q", i, expected, actual)
|
||||
}
|
||||
|
||||
if expected, actual := len(copies1.copies), len(copies2.copies); expected != actual {
|
||||
return fmt.Errorf("length mismatch in copy instructions at position %d, expected %d found %d", i, expected, actual)
|
||||
}
|
||||
|
||||
for j, c1 := range copies1.copies {
|
||||
c2 := copies2.copies[j]
|
||||
if expected, actual := NormalizePathForTesting(c1.from), NormalizePathForTesting(c2.from); expected != actual {
|
||||
return fmt.Errorf("paths mismatch at position %d.%d: expected %q found %q", i, j, expected, actual)
|
||||
}
|
||||
|
||||
if expected, actual := c1.dest, c2.dest; expected != actual {
|
||||
return fmt.Errorf("dest mismatch at position %d.%d: expected %q found %q", i, j, expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
formatContributions := func(d *distContributions) string {
|
||||
buf := &strings.Builder{}
|
||||
if d == nil {
|
||||
fmt.Fprint(buf, "nil")
|
||||
} else {
|
||||
for _, copiesForGoals := range d.copiesForGoals {
|
||||
fmt.Fprintf(buf, " Goals: %q {\n", copiesForGoals.goals)
|
||||
for _, c := range copiesForGoals.copies {
|
||||
fmt.Fprintf(buf, " %s -> %s\n", NormalizePathForTesting(c.from), c.dest)
|
||||
}
|
||||
fmt.Fprint(buf, " }\n")
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
testHelper := func(t *testing.T, name, bp string, expectedContributions *distContributions) {
|
||||
t.Helper()
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
config, module := buildConfigAndCustomModuleFoo(t, bp)
|
||||
entries := AndroidMkEntriesForTest(t, config, "", module)
|
||||
if len(entries) != 1 {
|
||||
t.Errorf("Expected a single AndroidMk entry, got %d", len(entries))
|
||||
}
|
||||
distContributions := entries[0].getDistContributions(module)
|
||||
|
||||
if err := compareContributions(expectedContributions, distContributions); err != nil {
|
||||
t.Errorf("%s\nExpected Contributions\n%sActualContributions\n%s",
|
||||
err,
|
||||
formatContributions(expectedContributions),
|
||||
formatContributions(distContributions))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
testHelper(t, "dist-without-tag", `
|
||||
custom {
|
||||
name: "foo",
|
||||
dist: {
|
||||
targets: ["my_goal"]
|
||||
}
|
||||
}
|
||||
`,
|
||||
&distContributions{
|
||||
copiesForGoals: []*copiesForGoals{
|
||||
{
|
||||
goals: "my_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "one.out"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
testHelper(t, "dist-with-tag", `
|
||||
custom {
|
||||
name: "foo",
|
||||
dist: {
|
||||
targets: ["my_goal"],
|
||||
tag: ".another-tag",
|
||||
}
|
||||
}
|
||||
`,
|
||||
&distContributions{
|
||||
copiesForGoals: []*copiesForGoals{
|
||||
{
|
||||
goals: "my_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("another.out", "another.out"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
testHelper(t, "dists-with-tag", `
|
||||
custom {
|
||||
name: "foo",
|
||||
dists: [
|
||||
{
|
||||
targets: ["my_goal"],
|
||||
tag: ".another-tag",
|
||||
},
|
||||
],
|
||||
}
|
||||
`,
|
||||
&distContributions{
|
||||
copiesForGoals: []*copiesForGoals{
|
||||
{
|
||||
goals: "my_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("another.out", "another.out"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
testHelper(t, "multiple-dists-with-and-without-tag", `
|
||||
custom {
|
||||
name: "foo",
|
||||
dists: [
|
||||
{
|
||||
targets: ["my_goal"],
|
||||
},
|
||||
{
|
||||
targets: ["my_second_goal", "my_third_goal"],
|
||||
},
|
||||
],
|
||||
}
|
||||
`,
|
||||
&distContributions{
|
||||
copiesForGoals: []*copiesForGoals{
|
||||
{
|
||||
goals: "my_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "one.out"),
|
||||
},
|
||||
},
|
||||
{
|
||||
goals: "my_second_goal my_third_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "one.out"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
testHelper(t, "dist-plus-dists-without-tags", `
|
||||
custom {
|
||||
name: "foo",
|
||||
dist: {
|
||||
targets: ["my_goal"],
|
||||
},
|
||||
dists: [
|
||||
{
|
||||
targets: ["my_second_goal", "my_third_goal"],
|
||||
},
|
||||
],
|
||||
}
|
||||
`,
|
||||
&distContributions{
|
||||
copiesForGoals: []*copiesForGoals{
|
||||
{
|
||||
goals: "my_second_goal my_third_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "one.out"),
|
||||
},
|
||||
},
|
||||
{
|
||||
goals: "my_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "one.out"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
testHelper(t, "dist-plus-dists-with-tags", `
|
||||
custom {
|
||||
name: "foo",
|
||||
dist: {
|
||||
targets: ["my_goal", "my_other_goal"],
|
||||
tag: ".multiple",
|
||||
},
|
||||
dists: [
|
||||
{
|
||||
targets: ["my_second_goal"],
|
||||
tag: ".multiple",
|
||||
},
|
||||
{
|
||||
targets: ["my_third_goal"],
|
||||
dir: "test/dir",
|
||||
},
|
||||
{
|
||||
targets: ["my_fourth_goal"],
|
||||
suffix: ".suffix",
|
||||
},
|
||||
{
|
||||
targets: ["my_fifth_goal"],
|
||||
dest: "new-name",
|
||||
},
|
||||
{
|
||||
targets: ["my_sixth_goal"],
|
||||
dest: "new-name",
|
||||
dir: "some/dir",
|
||||
suffix: ".suffix",
|
||||
},
|
||||
],
|
||||
}
|
||||
`,
|
||||
&distContributions{
|
||||
copiesForGoals: []*copiesForGoals{
|
||||
{
|
||||
goals: "my_second_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("two.out", "two.out"),
|
||||
distCopyForTest("three/four.out", "four.out"),
|
||||
},
|
||||
},
|
||||
{
|
||||
goals: "my_third_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "test/dir/one.out"),
|
||||
},
|
||||
},
|
||||
{
|
||||
goals: "my_fourth_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "one.suffix.out"),
|
||||
},
|
||||
},
|
||||
{
|
||||
goals: "my_fifth_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "new-name"),
|
||||
},
|
||||
},
|
||||
{
|
||||
goals: "my_sixth_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("one.out", "some/dir/new-name.suffix"),
|
||||
},
|
||||
},
|
||||
{
|
||||
goals: "my_goal my_other_goal",
|
||||
copies: []distCopy{
|
||||
distCopyForTest("two.out", "two.out"),
|
||||
distCopyForTest("three/four.out", "four.out"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user