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