diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/binary.go | 13 | ||||
| -rw-r--r-- | python/python.go | 5 | ||||
| -rw-r--r-- | python/python_test.go | 97 | ||||
| -rw-r--r-- | python/scripts/main.py | 90 | ||||
| -rw-r--r-- | python/test.go | 32 |
5 files changed, 164 insertions, 73 deletions
diff --git a/python/binary.go b/python/binary.go index f894299f9..fc38b157a 100644 --- a/python/binary.go +++ b/python/binary.go @@ -115,6 +115,12 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.SetOutputFiles(android.Paths{p.installSource}, "") + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + }) + moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"EXECUTABLES"} moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) @@ -166,8 +172,11 @@ func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { } p.androidMkSharedLibs = sharedLibs - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, + android.SetProvider(ctx, android.TestSuiteSharedLibsInfoProvider, android.TestSuiteSharedLibsInfo{ + MakeNames: p.androidMkSharedLibs, + }) + android.SetProvider(ctx, android.MakeNameInfoProvider, android.MakeNameInfo{ + Name: ctx.ModuleName(), }) } diff --git a/python/python.go b/python/python.go index de21e39bd..7af8d9d18 100644 --- a/python/python.go +++ b/python/python.go @@ -108,7 +108,6 @@ type BaseProperties struct { // list of the Python libraries compatible both with Python2 and Python3. Libs []string `android:"arch_variant"` - // TODO: b/403060602 - add unit tests for this property and related code // list of shared libraries that should be packaged with the python code for this module. Shared_libs []string `android:"arch_variant"` @@ -681,7 +680,7 @@ func (p *PythonLibraryModule) collectPathsFromTransitiveDeps(ctx android.ModuleC destToPyData[path.dest] = path.src.String() } - seen := make(map[android.Module]bool) + seen := make(map[android.ModuleProxy]bool) var result android.Paths @@ -727,7 +726,7 @@ func (p *PythonLibraryModule) collectPathsFromTransitiveDeps(ctx android.ModuleC } func (p *PythonLibraryModule) collectSharedLibDeps(ctx android.ModuleContext) android.Paths { - seen := make(map[android.Module]bool) + seen := make(map[android.ModuleProxy]bool) var result android.Paths diff --git a/python/python_test.go b/python/python_test.go index 5f971cdd1..696c27ff1 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -23,8 +23,6 @@ import ( "android/soong/android" "android/soong/cc" - - "github.com/google/blueprint" ) type pyModule struct { @@ -37,7 +35,7 @@ type pyModule struct { var ( buildNamePrefix = "soong_python_test" - moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_]*": ` + moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_\-]*": ` pkgPathErrTemplate = moduleVariantErrTemplate + "pkg_path: %q must be a relative path contained in par file." badIdentifierErrTemplate = moduleVariantErrTemplate + @@ -46,9 +44,11 @@ var ( "found two files to be placed at the same location within zip %q." + " First file: in module %s at path %q." + " Second file: in module %s at path %q." - badSrcFileExtErr = moduleVariantErrTemplate + `srcs: found non \(.py\|.proto\) file: %q!` - badDataFileExtErr = moduleVariantErrTemplate + `data: found \(.py\) file: %q!` - bpFile = "Android.bp" + badSrcFileExtErr = moduleVariantErrTemplate + `srcs: found non \(.py\|.proto\) file: %q!` + badDataFileExtErr = moduleVariantErrTemplate + `data: found \(.py\) file: %q!` + sharedLibErrTemplate = moduleVariantErrTemplate + + "shared_libs: shared_libs is not supported for device builds" + bpFile = "Android.bp" data = []struct { desc string @@ -206,6 +206,27 @@ var ( "lib1", "dir/c/file1.py"), }, }, + { + desc: "device module with shared libs", + mockFiles: map[string][]byte{ + filepath.Join("dir", bpFile): []byte( + `python_library { + name: "lib1", + srcs: [ + "file1.py", + ], + shared_libs: [ + "clib1", + ], + }`, + ), + "dir/file1.py": nil, + }, + errors: []string{ + fmt.Sprintf(sharedLibErrTemplate, + "dir/Android.bp:6:18", "lib1"), + }, + }, } ) @@ -268,7 +289,7 @@ func TestTestOnlyProvider(t *testing.T) { // marked as test-only are marked as test-only. actualTestOnly := []string{} - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m android.Module) { if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok { if provider.TestOnly { actualTestOnly = append(actualTestOnly, m.Name()) @@ -312,6 +333,68 @@ func TestInvalidTestOnlyTargets(t *testing.T) { } } +func TestSharedLib(t *testing.T) { + ctx := android.GroupFixturePreparers( + android.PrepareForTestWithDefaults, + android.PrepareForTestWithArchMutator, + android.PrepareForTestWithAllowMissingDependencies, + cc.PrepareForTestWithCcDefaultModules, + PrepareForTestWithPythonBuildComponents, + ).RunTestWithBp( + t, + `python_library_host { + name: "py-lib-host", + srcs: ["py-lib-host.py"], + shared_libs: ["clib-host"], + } + + cc_library_shared { + name: "clib-host", + host_supported: true, + shared_libs: ["clib-host-2"], + } + + cc_library_shared { + name: "clib-host-2", + host_supported: true, + }`, + ) + if len(ctx.Errs) > 0 { + t.Errorf("Expected got: %s, want: 0 errs", ctx.Errs) + } + + mod, modOk := ctx.ModuleForTests(t, "py-lib-host", ctx.Config.BuildOSTarget.String()).Module().(*PythonLibraryModule) + if !modOk { + t.Fatalf("py-lib-host is not Python library!") + } + // ensure the shared lib is included in the data path mappings + dataPathMappings := mod.getDataPathMappings() + if len(dataPathMappings) != 1 { + t.Fatalf("expected 1 data file, got: %d", len(dataPathMappings)) + } + android.AssertStringMatches( + t, + "data path included shared lib", + dataPathMappings[0].dest, + "clib-host(.so|.dylib)", + ) + // ensure any dependencies of the shared lib are included in the bundle shared + // libs + android.AssertStringMatches( + t, + "shared libs", + mod.getBundleSharedLibs()[0].String(), + "clib-host-2(.so|.dylib)$", + ) + android.AssertStringMatches( + t, + "shared libs", + mod.getBundleSharedLibs()[1].String(), + "libc\\+\\+(.so|.dylib)$", + ) + +} + func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) { module := ctx.ModuleForTests(t, name, variant) diff --git a/python/scripts/main.py b/python/scripts/main.py index 35cdfc47e..a3d8f65a2 100644 --- a/python/scripts/main.py +++ b/python/scripts/main.py @@ -1,48 +1,52 @@ +# It's important that we use a function here, as any global variables we make in this script will +# also be available in the real entrypoint run by runpy._run_module_as_main. +def _soong_main(): + import os + import runpy + import shutil + import sys + import tempfile + import zipfile -import os -import runpy -import shutil -import sys -import tempfile -import zipfile + from pathlib import PurePath -from pathlib import PurePath + sys.argv[0] = __loader__.archive + # Set sys.executable to None. The real executable is available as + # sys.argv[0], and too many things assume sys.executable is a regular Python + # binary, which isn't available. By setting it to None we get clear errors + # when people try to use it. + sys.executable = None -sys.argv[0] = __loader__.archive - -# Set sys.executable to None. The real executable is available as -# sys.argv[0], and too many things assume sys.executable is a regular Python -# binary, which isn't available. By setting it to None we get clear errors -# when people try to use it. -sys.executable = None - -# Extract the shared libraries from the zip file into a temporary directory. -# This works around the limitations of dynamic linker. Some Python libraries -# reference the .so files relatively and so extracting only the .so files -# does not work, so we extract the entire parent directory of the .so files to a -# tempdir and then add that to sys.path. -tempdir = None -with zipfile.ZipFile(__loader__.archive) as z: - # any root so files or root directories that contain so files will be - # extracted to the tempdir so the linker load them, this minimizes the - # number of files that need to be extracted to a tempdir - extract_paths = {} - for member in z.infolist(): - if member.filename.endswith('.so'): - extract_paths[PurePath(member.filename).parts[0]] = member.filename - if extract_paths: - tempdir = tempfile.mkdtemp() + # Extract the shared libraries from the zip file into a temporary directory. + # This works around the limitations of dynamic linker. Some Python libraries + # reference the .so files relatively and so extracting only the .so files + # does not work, so we extract the entire parent directory of the .so files to a + # tempdir and then add that to sys.path. + tempdir = None + with zipfile.ZipFile(__loader__.archive) as z: + # any root so files or root directories that contain so files will be + # extracted to the tempdir so the linker load them, this minimizes the + # number of files that need to be extracted to a tempdir + extract_paths = {} for member in z.infolist(): - if not PurePath(member.filename).parts[0] in extract_paths.keys(): - continue - if member.is_dir(): - os.makedirs(os.path.join(tempdir, member.filename)) - else: - z.extract(member, tempdir) - sys.path.insert(0, tempdir) -try: - runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) -finally: - if tempdir is not None: - shutil.rmtree(tempdir) + if member.filename.endswith('.so'): + extract_paths[PurePath(member.filename).parts[0]] = member.filename + if extract_paths: + tempdir = tempfile.mkdtemp() + for member in z.infolist(): + if not PurePath(member.filename).parts[0] in extract_paths.keys(): + continue + if member.is_dir(): + os.makedirs(os.path.join(tempdir, member.filename)) + else: + z.extract(member, tempdir) + sys.path.insert(0, tempdir) + try: + runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) + finally: + if tempdir is not None: + shutil.rmtree(tempdir) + +if __name__ == "__main__": + _soong_main() diff --git a/python/test.go b/python/test.go index df62ab794..d6670c3c4 100644 --- a/python/test.go +++ b/python/test.go @@ -215,25 +215,21 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext installedData := ctx.InstallTestData(installDir, p.data) p.installedDest = ctx.InstallFile(installDir, p.installSource.Base(), p.installSource, installedData...) - // TODO: Remove the special case for kati - if !ctx.Config().KatiEnabled() { - // Install the test config in testcases/ directory for atest. - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()) - if ctx.PrimaryArch() { - if p.testConfig != nil { - ctx.InstallFile(testCases, ctx.ModuleName()+".config", p.testConfig) - } - dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") - if dynamicConfig.Valid() { - ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) - } - } - // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch - testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) - installedData := ctx.InstallTestData(testCases, p.data) - ctx.InstallFile(testCases, p.installSource.Base(), p.installSource, installedData...) + configFileSuffix := "" + // ATS 2.0 is the test harness for mobly tests and the test config is for ATS 2.0. + // Add "v2" suffix to test config name to distinguish it from the config for TF. + if proptools.String(p.testProperties.Test_options.Runner) == "mobly" { + configFileSuffix = "v2" } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + ConfigFile: p.testConfig, + ConfigFileSuffix: configFileSuffix, + Data: p.data, + NeedsArchFolder: true, + }) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"NATIVE_TESTS"} |
