sh_binary_test.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package sh
  2. import (
  3. "os"
  4. "path/filepath"
  5. "strconv"
  6. "strings"
  7. "testing"
  8. "android/soong/android"
  9. "android/soong/cc"
  10. )
  11. func TestMain(m *testing.M) {
  12. os.Exit(m.Run())
  13. }
  14. var prepareForShTest = android.GroupFixturePreparers(
  15. cc.PrepareForTestWithCcBuildComponents,
  16. PrepareForTestWithShBuildComponents,
  17. android.FixtureMergeMockFs(android.MockFS{
  18. "test.sh": nil,
  19. "testdata/data1": nil,
  20. "testdata/sub/data2": nil,
  21. }),
  22. )
  23. // testShBinary runs tests using the prepareForShTest
  24. //
  25. // Do not add any new usages of this, instead use the prepareForShTest directly as it makes it much
  26. // easier to customize the test behavior.
  27. //
  28. // If it is necessary to customize the behavior of an existing test that uses this then please first
  29. // convert the test to using prepareForShTest first and then in a following change add the
  30. // appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
  31. // that it did not change the test behavior unexpectedly.
  32. //
  33. // deprecated
  34. func testShBinary(t *testing.T, bp string) (*android.TestContext, android.Config) {
  35. bp = bp + cc.GatherRequiredDepsForTest(android.Android)
  36. result := prepareForShTest.RunTestWithBp(t, bp)
  37. return result.TestContext, result.Config
  38. }
  39. func TestShTestSubDir(t *testing.T) {
  40. result := android.GroupFixturePreparers(
  41. prepareForShTest,
  42. android.FixtureModifyConfig(android.SetKatiEnabledForTests),
  43. ).RunTestWithBp(t, `
  44. sh_test {
  45. name: "foo",
  46. src: "test.sh",
  47. sub_dir: "foo_test"
  48. }
  49. `)
  50. mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
  51. entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
  52. expectedPath := "out/target/product/test_device/data/nativetest64/foo_test"
  53. actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0]
  54. android.AssertStringPathRelativeToTopEquals(t, "LOCAL_MODULE_PATH[0]", result.Config, expectedPath, actualPath)
  55. }
  56. func TestShTest(t *testing.T) {
  57. result := android.GroupFixturePreparers(
  58. prepareForShTest,
  59. android.FixtureModifyConfig(android.SetKatiEnabledForTests),
  60. ).RunTestWithBp(t, `
  61. sh_test {
  62. name: "foo",
  63. src: "test.sh",
  64. filename: "test.sh",
  65. data: [
  66. "testdata/data1",
  67. "testdata/sub/data2",
  68. ],
  69. }
  70. `)
  71. mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
  72. entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
  73. expectedPath := "out/target/product/test_device/data/nativetest64/foo"
  74. actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0]
  75. android.AssertStringPathRelativeToTopEquals(t, "LOCAL_MODULE_PATH[0]", result.Config, expectedPath, actualPath)
  76. expectedData := []string{":testdata/data1", ":testdata/sub/data2"}
  77. actualData := entries.EntryMap["LOCAL_TEST_DATA"]
  78. android.AssertDeepEquals(t, "LOCAL_TEST_DATA", expectedData, actualData)
  79. }
  80. func TestShTest_dataModules(t *testing.T) {
  81. ctx, config := testShBinary(t, `
  82. sh_test {
  83. name: "foo",
  84. src: "test.sh",
  85. host_supported: true,
  86. data_bins: ["bar"],
  87. data_libs: ["libbar"],
  88. }
  89. cc_binary {
  90. name: "bar",
  91. host_supported: true,
  92. shared_libs: ["libbar"],
  93. no_libcrt: true,
  94. nocrt: true,
  95. system_shared_libs: [],
  96. stl: "none",
  97. }
  98. cc_library {
  99. name: "libbar",
  100. host_supported: true,
  101. no_libcrt: true,
  102. nocrt: true,
  103. system_shared_libs: [],
  104. stl: "none",
  105. }
  106. `)
  107. buildOS := config.BuildOS.String()
  108. arches := []string{"android_arm64_armv8-a", buildOS + "_x86_64"}
  109. for _, arch := range arches {
  110. variant := ctx.ModuleForTests("foo", arch)
  111. libExt := ".so"
  112. if arch == "darwin_x86_64" {
  113. libExt = ".dylib"
  114. }
  115. relocated := variant.Output("relocated/lib64/libbar" + libExt)
  116. expectedInput := "out/soong/.intermediates/libbar/" + arch + "_shared/libbar" + libExt
  117. android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
  118. mod := variant.Module().(*ShTest)
  119. entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
  120. expectedData := []string{
  121. filepath.Join("out/soong/.intermediates/bar", arch, ":bar"),
  122. filepath.Join("out/soong/.intermediates/foo", arch, "relocated/:lib64/libbar"+libExt),
  123. }
  124. actualData := entries.EntryMap["LOCAL_TEST_DATA"]
  125. android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", config, expectedData, actualData)
  126. }
  127. }
  128. func TestShTestHost(t *testing.T) {
  129. ctx, _ := testShBinary(t, `
  130. sh_test_host {
  131. name: "foo",
  132. src: "test.sh",
  133. filename: "test.sh",
  134. data: [
  135. "testdata/data1",
  136. "testdata/sub/data2",
  137. ],
  138. test_options: {
  139. unit_test: true,
  140. },
  141. }
  142. `)
  143. buildOS := ctx.Config().BuildOS.String()
  144. mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest)
  145. if !mod.Host() {
  146. t.Errorf("host bit is not set for a sh_test_host module.")
  147. }
  148. entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
  149. actualData, _ := strconv.ParseBool(entries.EntryMap["LOCAL_IS_UNIT_TEST"][0])
  150. android.AssertBoolEquals(t, "LOCAL_IS_UNIT_TEST", true, actualData)
  151. }
  152. func TestShTestHost_dataDeviceModules(t *testing.T) {
  153. ctx, config := testShBinary(t, `
  154. sh_test_host {
  155. name: "foo",
  156. src: "test.sh",
  157. data_device_bins: ["bar"],
  158. data_device_libs: ["libbar"],
  159. }
  160. cc_binary {
  161. name: "bar",
  162. shared_libs: ["libbar"],
  163. no_libcrt: true,
  164. nocrt: true,
  165. system_shared_libs: [],
  166. stl: "none",
  167. }
  168. cc_library {
  169. name: "libbar",
  170. no_libcrt: true,
  171. nocrt: true,
  172. system_shared_libs: [],
  173. stl: "none",
  174. }
  175. `)
  176. buildOS := config.BuildOS.String()
  177. variant := ctx.ModuleForTests("foo", buildOS+"_x86_64")
  178. relocated := variant.Output("relocated/lib64/libbar.so")
  179. expectedInput := "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so"
  180. android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
  181. mod := variant.Module().(*ShTest)
  182. entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
  183. expectedData := []string{
  184. "out/soong/.intermediates/bar/android_arm64_armv8-a/:bar",
  185. // libbar has been relocated, and so has a variant that matches the host arch.
  186. "out/soong/.intermediates/foo/" + buildOS + "_x86_64/relocated/:lib64/libbar.so",
  187. }
  188. actualData := entries.EntryMap["LOCAL_TEST_DATA"]
  189. android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", config, expectedData, actualData)
  190. }
  191. func TestShTestHost_dataDeviceModulesAutogenTradefedConfig(t *testing.T) {
  192. ctx, config := testShBinary(t, `
  193. sh_test_host {
  194. name: "foo",
  195. src: "test.sh",
  196. data_device_bins: ["bar"],
  197. data_device_libs: ["libbar"],
  198. }
  199. cc_binary {
  200. name: "bar",
  201. shared_libs: ["libbar"],
  202. no_libcrt: true,
  203. nocrt: true,
  204. system_shared_libs: [],
  205. stl: "none",
  206. }
  207. cc_library {
  208. name: "libbar",
  209. no_libcrt: true,
  210. nocrt: true,
  211. system_shared_libs: [],
  212. stl: "none",
  213. }
  214. `)
  215. buildOS := config.BuildOS.String()
  216. fooModule := ctx.ModuleForTests("foo", buildOS+"_x86_64")
  217. expectedBinAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />`
  218. autogen := fooModule.Rule("autogen")
  219. if !strings.Contains(autogen.Args["extraConfigs"], expectedBinAutogenConfig) {
  220. t.Errorf("foo extraConfings %v does not contain %q", autogen.Args["extraConfigs"], expectedBinAutogenConfig)
  221. }
  222. }