test.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Copyright 2017 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package python
  15. import (
  16. "fmt"
  17. "github.com/google/blueprint/proptools"
  18. "android/soong/android"
  19. "android/soong/tradefed"
  20. )
  21. // This file contains the module types for building Python test.
  22. func init() {
  23. registerPythonTestComponents(android.InitRegistrationContext)
  24. }
  25. func registerPythonTestComponents(ctx android.RegistrationContext) {
  26. ctx.RegisterModuleType("python_test_host", PythonTestHostFactory)
  27. ctx.RegisterModuleType("python_test", PythonTestFactory)
  28. }
  29. func NewTest(hod android.HostOrDeviceSupported) *PythonTestModule {
  30. return &PythonTestModule{PythonBinaryModule: *NewBinary(hod)}
  31. }
  32. func PythonTestHostFactory() android.Module {
  33. return NewTest(android.HostSupported).init()
  34. }
  35. func PythonTestFactory() android.Module {
  36. module := NewTest(android.HostAndDeviceSupported)
  37. module.multilib = android.MultilibBoth
  38. return module.init()
  39. }
  40. type TestProperties struct {
  41. // the name of the test configuration (for example "AndroidTest.xml") that should be
  42. // installed with the module.
  43. Test_config *string `android:"path,arch_variant"`
  44. // the name of the test configuration template (for example "AndroidTestTemplate.xml") that
  45. // should be installed with the module.
  46. Test_config_template *string `android:"path,arch_variant"`
  47. // list of files or filegroup modules that provide data that should be installed alongside
  48. // the test
  49. Data []string `android:"path,arch_variant"`
  50. // list of java modules that provide data that should be installed alongside the test.
  51. Java_data []string
  52. // Test options.
  53. Test_options TestOptions
  54. // list of device binary modules that should be installed alongside the test
  55. // This property adds 64bit AND 32bit variants of the dependency
  56. Data_device_bins_both []string `android:"arch_variant"`
  57. }
  58. type TestOptions struct {
  59. android.CommonTestOptions
  60. // Runner for the test. Supports "tradefed" and "mobly" (for multi-device tests). Default is "tradefed".
  61. Runner *string
  62. // Metadata to describe the test configuration.
  63. Metadata []Metadata
  64. }
  65. type Metadata struct {
  66. Name string
  67. Value string
  68. }
  69. type PythonTestModule struct {
  70. PythonBinaryModule
  71. testProperties TestProperties
  72. testConfig android.Path
  73. data []android.DataPath
  74. }
  75. func (p *PythonTestModule) init() android.Module {
  76. p.AddProperties(&p.properties, &p.protoProperties)
  77. p.AddProperties(&p.binaryProperties)
  78. p.AddProperties(&p.testProperties)
  79. android.InitAndroidArchModule(p, p.hod, p.multilib)
  80. android.InitDefaultableModule(p)
  81. android.InitBazelModule(p)
  82. if p.isTestHost() && p.testProperties.Test_options.Unit_test == nil {
  83. p.testProperties.Test_options.Unit_test = proptools.BoolPtr(true)
  84. }
  85. return p
  86. }
  87. func (p *PythonTestModule) isTestHost() bool {
  88. return p.hod == android.HostSupported
  89. }
  90. var dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
  91. // python_test_host DepsMutator uses this method to add multilib dependencies of
  92. // data_device_bin_both
  93. func (p *PythonTestModule) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext, filter string) {
  94. if len(p.testProperties.Data_device_bins_both) < 1 {
  95. return
  96. }
  97. var maybeAndroidTarget *android.Target
  98. androidTargetList := android.FirstTarget(ctx.Config().Targets[android.Android], filter)
  99. if len(androidTargetList) > 0 {
  100. maybeAndroidTarget = &androidTargetList[0]
  101. }
  102. if maybeAndroidTarget != nil {
  103. ctx.AddFarVariationDependencies(
  104. maybeAndroidTarget.Variations(),
  105. dataDeviceBinsTag,
  106. p.testProperties.Data_device_bins_both...,
  107. )
  108. }
  109. }
  110. func (p *PythonTestModule) DepsMutator(ctx android.BottomUpMutatorContext) {
  111. p.PythonBinaryModule.DepsMutator(ctx)
  112. if p.isTestHost() {
  113. p.addDataDeviceBinsDeps(ctx, "lib32")
  114. p.addDataDeviceBinsDeps(ctx, "lib64")
  115. }
  116. }
  117. func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  118. // We inherit from only the library's GenerateAndroidBuildActions, and then
  119. // just use buildBinary() so that the binary is not installed into the location
  120. // it would be for regular binaries.
  121. p.PythonLibraryModule.GenerateAndroidBuildActions(ctx)
  122. p.buildBinary(ctx)
  123. var configs []tradefed.Option
  124. for _, metadata := range p.testProperties.Test_options.Metadata {
  125. configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: metadata.Name, Value: metadata.Value})
  126. }
  127. runner := proptools.StringDefault(p.testProperties.Test_options.Runner, "tradefed")
  128. if runner == "tradefed" {
  129. p.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
  130. TestConfigProp: p.testProperties.Test_config,
  131. TestConfigTemplateProp: p.testProperties.Test_config_template,
  132. TestSuites: p.binaryProperties.Test_suites,
  133. OptionsForAutogenerated: configs,
  134. AutoGenConfig: p.binaryProperties.Auto_gen_config,
  135. DeviceTemplate: "${PythonBinaryHostTestConfigTemplate}",
  136. HostTemplate: "${PythonBinaryHostTestConfigTemplate}",
  137. })
  138. } else if runner == "mobly" {
  139. if p.testProperties.Test_config != nil || p.testProperties.Test_config_template != nil || p.binaryProperties.Auto_gen_config != nil {
  140. panic(fmt.Errorf("cannot set test_config, test_config_template or auto_gen_config for mobly test"))
  141. }
  142. for _, testSuite := range p.binaryProperties.Test_suites {
  143. if testSuite == "cts" {
  144. configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: "cts"})
  145. break
  146. }
  147. }
  148. p.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
  149. OptionsForAutogenerated: configs,
  150. DeviceTemplate: "${PythonBinaryHostMoblyTestConfigTemplate}",
  151. HostTemplate: "${PythonBinaryHostMoblyTestConfigTemplate}",
  152. })
  153. } else {
  154. panic(fmt.Errorf("unknown python test runner '%s', should be 'tradefed' or 'mobly'", runner))
  155. }
  156. p.installedDest = ctx.InstallFile(installDir(ctx, "nativetest", "nativetest64", ctx.ModuleName()), p.installSource.Base(), p.installSource)
  157. for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Data) {
  158. p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath})
  159. }
  160. if p.isTestHost() && len(p.testProperties.Data_device_bins_both) > 0 {
  161. ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
  162. p.data = append(p.data, android.DataPath{SrcPath: android.OutputFileForModule(ctx, dep, "")})
  163. })
  164. }
  165. // Emulate the data property for java_data dependencies.
  166. for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
  167. for _, javaDataSrcPath := range android.OutputFilesForModule(ctx, javaData, "") {
  168. p.data = append(p.data, android.DataPath{SrcPath: javaDataSrcPath})
  169. }
  170. }
  171. }
  172. func (p *PythonTestModule) AndroidMkEntries() []android.AndroidMkEntries {
  173. entriesList := p.PythonBinaryModule.AndroidMkEntries()
  174. if len(entriesList) != 1 {
  175. panic("Expected 1 entry")
  176. }
  177. entries := &entriesList[0]
  178. entries.Class = "NATIVE_TESTS"
  179. entries.ExtraEntries = append(entries.ExtraEntries,
  180. func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
  181. //entries.AddCompatibilityTestSuites(p.binaryProperties.Test_suites...)
  182. if p.testConfig != nil {
  183. entries.SetString("LOCAL_FULL_TEST_CONFIG", p.testConfig.String())
  184. }
  185. entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !BoolDefault(p.binaryProperties.Auto_gen_config, true))
  186. entries.AddStrings("LOCAL_TEST_DATA", android.AndroidMkDataPaths(p.data)...)
  187. p.testProperties.Test_options.SetAndroidMkEntries(entries)
  188. })
  189. return entriesList
  190. }