Merge changes I5f2fd123,Ie8d8e229,Id2194f6b into main

* changes:
  Move RelativeToTop out of basePath
  Make PathForArbitraryOutput return an OutputPath
  Run TestClasspath subtests in parallel
This commit is contained in:
Colin Cross
2024-07-30 16:30:54 +00:00
committed by Gerrit Code Review
5 changed files with 47 additions and 31 deletions

View File

@@ -245,13 +245,13 @@ type Path interface {
// A standard build has the following structure: // A standard build has the following structure:
// ../top/ // ../top/
// out/ - make install files go here. // out/ - make install files go here.
// out/soong - this is the soongOutDir passed to NewTestConfig() // out/soong - this is the outDir passed to NewTestConfig()
// ... - the source files // ... - the source files
// //
// This function converts a path so that it appears relative to the ../top/ directory, i.e. // This function converts a path so that it appears relative to the ../top/ directory, i.e.
// * Make install paths, which have the pattern "soongOutDir/../<path>" are converted into the top // * Make install paths, which have the pattern "outDir/../<path>" are converted into the top
// relative path "out/<path>" // relative path "out/<path>"
// * Soong install paths and other writable paths, which have the pattern "soongOutDir/<path>" are // * Soong install paths and other writable paths, which have the pattern "outDir/soong/<path>" are
// converted into the top relative path "out/soong/<path>". // converted into the top relative path "out/soong/<path>".
// * Source paths are already relative to the top. // * Source paths are already relative to the top.
// * Phony paths are not relative to anything. // * Phony paths are not relative to anything.
@@ -261,8 +261,9 @@ type Path interface {
} }
const ( const (
OutDir = "out" testOutDir = "out"
OutSoongDir = OutDir + "/soong" testOutSoongSubDir = "/soong"
TestOutSoongDir = testOutDir + testOutSoongSubDir
) )
// WritablePath is a type of path that can be used as an output for build rules. // WritablePath is a type of path that can be used as an output for build rules.
@@ -1118,11 +1119,6 @@ func (p basePath) withRel(rel string) basePath {
return p return p
} }
func (p basePath) RelativeToTop() Path {
ensureTestOnly()
return p
}
// SourcePath is a Path representing a file path rooted from SrcDir // SourcePath is a Path representing a file path rooted from SrcDir
type SourcePath struct { type SourcePath struct {
basePath basePath
@@ -1135,6 +1131,11 @@ func (p SourcePath) withRel(rel string) SourcePath {
return p return p
} }
func (p SourcePath) RelativeToTop() Path {
ensureTestOnly()
return p
}
// safePathForSource is for paths that we expect are safe -- only for use by go // safePathForSource is for paths that we expect are safe -- only for use by go
// code that is embedding ninja variables in paths // code that is embedding ninja variables in paths
func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) { func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
@@ -1218,11 +1219,13 @@ func PathForSource(ctx PathContext, pathComponents ...string) SourcePath {
// PathForArbitraryOutput creates a path for the given components. Unlike PathForOutput, // PathForArbitraryOutput creates a path for the given components. Unlike PathForOutput,
// the path is relative to the root of the output folder, not the out/soong folder. // the path is relative to the root of the output folder, not the out/soong folder.
func PathForArbitraryOutput(ctx PathContext, pathComponents ...string) Path { func PathForArbitraryOutput(ctx PathContext, pathComponents ...string) Path {
p, err := validatePath(pathComponents...) path, err := validatePath(pathComponents...)
if err != nil { if err != nil {
reportPathError(ctx, err) reportPathError(ctx, err)
} }
return basePath{path: filepath.Join(ctx.Config().OutDir(), p)} fullPath := filepath.Join(ctx.Config().OutDir(), path)
path = fullPath[len(fullPath)-len(path):]
return OutputPath{basePath{path, ""}, ctx.Config().OutDir(), fullPath}
} }
// MaybeExistentPathForSource joins the provided path components and validates that the result // MaybeExistentPathForSource joins the provided path components and validates that the result
@@ -1325,8 +1328,8 @@ func (p SourcePath) OverlayPath(ctx ModuleMissingDepsPathContext, path Path) Opt
type OutputPath struct { type OutputPath struct {
basePath basePath
// The soong build directory, i.e. Config.SoongOutDir() // The base out directory for this path, either Config.SoongOutDir() or Config.OutDir()
soongOutDir string outDir string
fullPath string fullPath string
} }
@@ -1334,7 +1337,7 @@ type OutputPath struct {
func (p OutputPath) GobEncode() ([]byte, error) { func (p OutputPath) GobEncode() ([]byte, error) {
w := new(bytes.Buffer) w := new(bytes.Buffer)
encoder := gob.NewEncoder(w) encoder := gob.NewEncoder(w)
err := errors.Join(encoder.Encode(p.basePath), encoder.Encode(p.soongOutDir), encoder.Encode(p.fullPath)) err := errors.Join(encoder.Encode(p.basePath), encoder.Encode(p.outDir), encoder.Encode(p.fullPath))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1345,7 +1348,7 @@ func (p OutputPath) GobEncode() ([]byte, error) {
func (p *OutputPath) GobDecode(data []byte) error { func (p *OutputPath) GobDecode(data []byte) error {
r := bytes.NewBuffer(data) r := bytes.NewBuffer(data)
decoder := gob.NewDecoder(r) decoder := gob.NewDecoder(r)
err := errors.Join(decoder.Decode(&p.basePath), decoder.Decode(&p.soongOutDir), decoder.Decode(&p.fullPath)) err := errors.Join(decoder.Decode(&p.basePath), decoder.Decode(&p.outDir), decoder.Decode(&p.fullPath))
if err != nil { if err != nil {
return err return err
} }
@@ -1365,7 +1368,7 @@ func (p OutputPath) WithoutRel() OutputPath {
} }
func (p OutputPath) getSoongOutDir() string { func (p OutputPath) getSoongOutDir() string {
return p.soongOutDir return p.outDir
} }
func (p OutputPath) RelativeToTop() Path { func (p OutputPath) RelativeToTop() Path {
@@ -1373,8 +1376,13 @@ func (p OutputPath) RelativeToTop() Path {
} }
func (p OutputPath) outputPathRelativeToTop() OutputPath { func (p OutputPath) outputPathRelativeToTop() OutputPath {
p.fullPath = StringPathRelativeToTop(p.soongOutDir, p.fullPath) p.fullPath = StringPathRelativeToTop(p.outDir, p.fullPath)
p.soongOutDir = OutSoongDir if strings.HasSuffix(p.outDir, testOutSoongSubDir) {
p.outDir = TestOutSoongDir
} else {
// Handle the PathForArbitraryOutput case
p.outDir = testOutDir
}
return p return p
} }
@@ -1420,7 +1428,7 @@ func PathForOutput(ctx PathContext, pathComponents ...string) OutputPath {
return OutputPath{basePath{path, ""}, ctx.Config().soongOutDir, fullPath} return OutputPath{basePath{path, ""}, ctx.Config().soongOutDir, fullPath}
} }
// PathsForOutput returns Paths rooted from soongOutDir // PathsForOutput returns Paths rooted from outDir
func PathsForOutput(ctx PathContext, paths []string) WritablePaths { func PathsForOutput(ctx PathContext, paths []string) WritablePaths {
ret := make(WritablePaths, len(paths)) ret := make(WritablePaths, len(paths))
for i, path := range paths { for i, path := range paths {
@@ -1751,9 +1759,9 @@ func ensureTestOnly() {
func (p InstallPath) RelativeToTop() Path { func (p InstallPath) RelativeToTop() Path {
ensureTestOnly() ensureTestOnly()
if p.makePath { if p.makePath {
p.soongOutDir = OutDir p.soongOutDir = testOutDir
} else { } else {
p.soongOutDir = OutSoongDir p.soongOutDir = TestOutSoongDir
} }
p.fullPath = filepath.Join(p.soongOutDir, p.path) p.fullPath = filepath.Join(p.soongOutDir, p.path)
return p return p

View File

@@ -822,15 +822,15 @@ func newBaseTestingComponent(config Config, provider testBuildProvider) baseTest
// containing at most one instance of the temporary build directory at the start of the path while // 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. // this assumes that there can be any number at any position.
func normalizeStringRelativeToTop(config Config, s string) string { func normalizeStringRelativeToTop(config Config, s string) string {
// The soongOutDir usually looks something like: /tmp/testFoo2345/001 // The outDir usually looks something like: /tmp/testFoo2345/001
// //
// Replace any usage of the soongOutDir with out/soong, e.g. replace "/tmp/testFoo2345/001" with // Replace any usage of the outDir with out/soong, e.g. replace "/tmp/testFoo2345/001" with
// "out/soong". // "out/soong".
outSoongDir := filepath.Clean(config.soongOutDir) outSoongDir := filepath.Clean(config.soongOutDir)
re := regexp.MustCompile(`\Q` + outSoongDir + `\E\b`) re := regexp.MustCompile(`\Q` + outSoongDir + `\E\b`)
s = re.ReplaceAllString(s, "out/soong") s = re.ReplaceAllString(s, "out/soong")
// Replace any usage of the soongOutDir/.. with out, e.g. replace "/tmp/testFoo2345" with // Replace any usage of the outDir/.. with out, e.g. replace "/tmp/testFoo2345" with
// "out". This must come after the previous replacement otherwise this would replace // "out". This must come after the previous replacement otherwise this would replace
// "/tmp/testFoo2345/001" with "out/001" instead of "out/soong". // "/tmp/testFoo2345/001" with "out/001" instead of "out/soong".
outDir := filepath.Dir(outSoongDir) outDir := filepath.Dir(outSoongDir)
@@ -1234,8 +1234,14 @@ func StringPathRelativeToTop(soongOutDir string, path string) string {
} }
if isRel { if isRel {
if strings.HasSuffix(soongOutDir, testOutSoongSubDir) {
// The path is in the soong out dir so indicate that in the relative path. // The path is in the soong out dir so indicate that in the relative path.
return filepath.Join("out/soong", rel) return filepath.Join(TestOutSoongDir, rel)
} else {
// Handle the PathForArbitraryOutput case
return filepath.Join(testOutDir, rel)
}
} }
// Check to see if the path is relative to the top level out dir. // Check to see if the path is relative to the top level out dir.

View File

@@ -16,7 +16,6 @@ package filesystem
import ( import (
"os" "os"
"path/filepath"
"testing" "testing"
"android/soong/android" "android/soong/android"
@@ -147,8 +146,8 @@ func TestIncludeMakeBuiltFiles(t *testing.T) {
output := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img") output := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
stampFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/staging_dir.stamp") stampFile := "out/target/product/test_device/obj/PACKAGING/system_intermediates/staging_dir.stamp"
fileListFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/file_list.txt") fileListFile := "out/target/product/test_device/obj/PACKAGING/system_intermediates/file_list.txt"
android.AssertStringListContains(t, "deps of filesystem must include the staging dir stamp file", output.Implicits.Strings(), stampFile) android.AssertStringListContains(t, "deps of filesystem must include the staging dir stamp file", output.Implicits.Strings(), stampFile)
android.AssertStringListContains(t, "deps of filesystem must include the staging dir file list", output.Implicits.Strings(), fileListFile) android.AssertStringListContains(t, "deps of filesystem must include the staging dir file list", output.Implicits.Strings(), fileListFile)
} }

View File

@@ -56,7 +56,7 @@ func TestAndroidAppSet(t *testing.T) {
mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0] mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0]
actualInstallFile := mkEntries.EntryMap["LOCAL_APK_SET_INSTALL_FILE"] actualInstallFile := mkEntries.EntryMap["LOCAL_APK_SET_INSTALL_FILE"]
expectedInstallFile := []string{ expectedInstallFile := []string{
strings.Replace(params.ImplicitOutputs[0].String(), android.OutSoongDir, result.Config.SoongOutDir(), 1), strings.Replace(params.ImplicitOutputs[0].String(), android.TestOutSoongDir, result.Config.SoongOutDir(), 1),
} }
if !reflect.DeepEqual(actualInstallFile, expectedInstallFile) { if !reflect.DeepEqual(actualInstallFile, expectedInstallFile) {
t.Errorf("Unexpected LOCAL_APK_SET_INSTALL_FILE value: '%s', expected: '%s',", t.Errorf("Unexpected LOCAL_APK_SET_INSTALL_FILE value: '%s', expected: '%s',",

View File

@@ -388,7 +388,9 @@ func TestClasspath(t *testing.T) {
}, },
} }
t.Parallel()
t.Run("basic", func(t *testing.T) { t.Run("basic", func(t *testing.T) {
t.Parallel()
testClasspathTestCases(t, classpathTestcases, false) testClasspathTestCases(t, classpathTestcases, false)
}) })
@@ -404,6 +406,7 @@ func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase
} }
t.Run(testcase.name, func(t *testing.T) { t.Run(testcase.name, func(t *testing.T) {
t.Parallel()
moduleType := "java_library" moduleType := "java_library"
if testcase.moduleType != "" { if testcase.moduleType != "" {
moduleType = testcase.moduleType moduleType = testcase.moduleType