| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 1 | package sh | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 2 |  | 
|  | 3 | import ( | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 4 | "io/ioutil" | 
|  | 5 | "os" | 
| Jaewoong Jung | 6e0eee5 | 2020-05-29 16:15:32 -0700 | [diff] [blame] | 6 | "path/filepath" | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 7 | "reflect" | 
|  | 8 | "testing" | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 9 |  | 
|  | 10 | "android/soong/android" | 
| Jaewoong Jung | 6e0eee5 | 2020-05-29 16:15:32 -0700 | [diff] [blame] | 11 | "android/soong/cc" | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 12 | ) | 
|  | 13 |  | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 14 | var buildDir string | 
|  | 15 |  | 
|  | 16 | func setUp() { | 
|  | 17 | var err error | 
|  | 18 | buildDir, err = ioutil.TempDir("", "soong_sh_test") | 
|  | 19 | if err != nil { | 
|  | 20 | panic(err) | 
|  | 21 | } | 
|  | 22 | } | 
|  | 23 |  | 
|  | 24 | func tearDown() { | 
|  | 25 | os.RemoveAll(buildDir) | 
|  | 26 | } | 
|  | 27 |  | 
|  | 28 | func TestMain(m *testing.M) { | 
|  | 29 | run := func() int { | 
|  | 30 | setUp() | 
|  | 31 | defer tearDown() | 
|  | 32 |  | 
|  | 33 | return m.Run() | 
|  | 34 | } | 
|  | 35 |  | 
|  | 36 | os.Exit(run()) | 
|  | 37 | } | 
|  | 38 |  | 
|  | 39 | func testShBinary(t *testing.T, bp string) (*android.TestContext, android.Config) { | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 40 | fs := map[string][]byte{ | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 41 | "test.sh":            nil, | 
|  | 42 | "testdata/data1":     nil, | 
|  | 43 | "testdata/sub/data2": nil, | 
|  | 44 | } | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 45 |  | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 46 | config := android.TestArchConfig(buildDir, nil, bp, fs) | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 47 |  | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 48 | ctx := android.NewTestArchContext() | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 49 | ctx.RegisterModuleType("sh_test", ShTestFactory) | 
|  | 50 | ctx.RegisterModuleType("sh_test_host", ShTestHostFactory) | 
| Jaewoong Jung | 6e0eee5 | 2020-05-29 16:15:32 -0700 | [diff] [blame] | 51 |  | 
|  | 52 | cc.RegisterRequiredBuildComponentsForTest(ctx) | 
|  | 53 |  | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 54 | ctx.Register(config) | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 55 | _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 56 | android.FailIfErrored(t, errs) | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 57 | _, errs = ctx.PrepareBuildActions(config) | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 58 | android.FailIfErrored(t, errs) | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 59 |  | 
|  | 60 | return ctx, config | 
|  | 61 | } | 
|  | 62 |  | 
| Jaewoong Jung | 4aedc86 | 2020-06-10 17:23:46 -0700 | [diff] [blame] | 63 | func TestShTestSubDir(t *testing.T) { | 
|  | 64 | ctx, config := testShBinary(t, ` | 
|  | 65 | sh_test { | 
|  | 66 | name: "foo", | 
|  | 67 | src: "test.sh", | 
|  | 68 | sub_dir: "foo_test" | 
|  | 69 | } | 
|  | 70 | `) | 
|  | 71 |  | 
|  | 72 | mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest) | 
|  | 73 |  | 
|  | 74 | entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0] | 
|  | 75 |  | 
|  | 76 | expectedPath := "/tmp/target/product/test_device/data/nativetest64/foo_test" | 
|  | 77 | actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0] | 
|  | 78 | if expectedPath != actualPath { | 
|  | 79 | t.Errorf("Unexpected LOCAL_MODULE_PATH expected: %q, actual: %q", expectedPath, actualPath) | 
|  | 80 | } | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | func TestShTest(t *testing.T) { | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 84 | ctx, config := testShBinary(t, ` | 
|  | 85 | sh_test { | 
|  | 86 | name: "foo", | 
|  | 87 | src: "test.sh", | 
|  | 88 | filename: "test.sh", | 
|  | 89 | data: [ | 
|  | 90 | "testdata/data1", | 
|  | 91 | "testdata/sub/data2", | 
|  | 92 | ], | 
|  | 93 | } | 
|  | 94 | `) | 
|  | 95 |  | 
|  | 96 | mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest) | 
|  | 97 |  | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 98 | entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0] | 
| Jaewoong Jung | 4aedc86 | 2020-06-10 17:23:46 -0700 | [diff] [blame] | 99 |  | 
|  | 100 | expectedPath := "/tmp/target/product/test_device/data/nativetest64/foo" | 
|  | 101 | actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0] | 
|  | 102 | if expectedPath != actualPath { | 
|  | 103 | t.Errorf("Unexpected LOCAL_MODULE_PATH expected: %q, actual: %q", expectedPath, actualPath) | 
|  | 104 | } | 
|  | 105 |  | 
|  | 106 | expectedData := []string{":testdata/data1", ":testdata/sub/data2"} | 
|  | 107 | actualData := entries.EntryMap["LOCAL_TEST_DATA"] | 
|  | 108 | if !reflect.DeepEqual(expectedData, actualData) { | 
|  | 109 | t.Errorf("Unexpected test data expected: %q, actual: %q", expectedData, actualData) | 
| Jaewoong Jung | 8eaeb09 | 2019-05-16 14:58:29 -0700 | [diff] [blame] | 110 | } | 
|  | 111 | } | 
| Jaewoong Jung | 61a8368 | 2019-07-01 09:08:50 -0700 | [diff] [blame] | 112 |  | 
| Jaewoong Jung | 6e0eee5 | 2020-05-29 16:15:32 -0700 | [diff] [blame] | 113 | func TestShTest_dataModules(t *testing.T) { | 
|  | 114 | ctx, config := testShBinary(t, ` | 
|  | 115 | sh_test { | 
|  | 116 | name: "foo", | 
|  | 117 | src: "test.sh", | 
|  | 118 | host_supported: true, | 
|  | 119 | data_bins: ["bar"], | 
|  | 120 | data_libs: ["libbar"], | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | cc_binary { | 
|  | 124 | name: "bar", | 
|  | 125 | host_supported: true, | 
|  | 126 | shared_libs: ["libbar"], | 
|  | 127 | no_libcrt: true, | 
|  | 128 | nocrt: true, | 
|  | 129 | system_shared_libs: [], | 
|  | 130 | stl: "none", | 
|  | 131 | } | 
|  | 132 |  | 
|  | 133 | cc_library { | 
|  | 134 | name: "libbar", | 
|  | 135 | host_supported: true, | 
|  | 136 | no_libcrt: true, | 
|  | 137 | nocrt: true, | 
|  | 138 | system_shared_libs: [], | 
|  | 139 | stl: "none", | 
|  | 140 | } | 
|  | 141 | `) | 
|  | 142 |  | 
|  | 143 | buildOS := android.BuildOs.String() | 
|  | 144 | arches := []string{"android_arm64_armv8-a", buildOS + "_x86_64"} | 
|  | 145 | for _, arch := range arches { | 
|  | 146 | variant := ctx.ModuleForTests("foo", arch) | 
|  | 147 |  | 
|  | 148 | libExt := ".so" | 
|  | 149 | if arch == "darwin_x86_64" { | 
|  | 150 | libExt = ".dylib" | 
|  | 151 | } | 
|  | 152 | relocated := variant.Output("relocated/lib64/libbar" + libExt) | 
|  | 153 | expectedInput := filepath.Join(buildDir, ".intermediates/libbar/"+arch+"_shared/libbar"+libExt) | 
|  | 154 | if relocated.Input.String() != expectedInput { | 
|  | 155 | t.Errorf("Unexpected relocation input, expected: %q, actual: %q", | 
|  | 156 | expectedInput, relocated.Input.String()) | 
|  | 157 | } | 
|  | 158 |  | 
|  | 159 | mod := variant.Module().(*ShTest) | 
|  | 160 | entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0] | 
|  | 161 | expectedData := []string{ | 
|  | 162 | filepath.Join(buildDir, ".intermediates/bar", arch, ":bar"), | 
|  | 163 | filepath.Join(buildDir, ".intermediates/foo", arch, "relocated/:lib64/libbar"+libExt), | 
|  | 164 | } | 
|  | 165 | actualData := entries.EntryMap["LOCAL_TEST_DATA"] | 
|  | 166 | if !reflect.DeepEqual(expectedData, actualData) { | 
|  | 167 | t.Errorf("Unexpected test data, expected: %q, actual: %q", expectedData, actualData) | 
|  | 168 | } | 
|  | 169 | } | 
|  | 170 | } | 
|  | 171 |  | 
| Jaewoong Jung | 61a8368 | 2019-07-01 09:08:50 -0700 | [diff] [blame] | 172 | func TestShTestHost(t *testing.T) { | 
|  | 173 | ctx, _ := testShBinary(t, ` | 
|  | 174 | sh_test_host { | 
|  | 175 | name: "foo", | 
|  | 176 | src: "test.sh", | 
|  | 177 | filename: "test.sh", | 
|  | 178 | data: [ | 
|  | 179 | "testdata/data1", | 
|  | 180 | "testdata/sub/data2", | 
|  | 181 | ], | 
|  | 182 | } | 
|  | 183 | `) | 
|  | 184 |  | 
| Jaewoong Jung | 4b79e98 | 2020-06-01 10:45:49 -0700 | [diff] [blame] | 185 | buildOS := android.BuildOs.String() | 
| Jaewoong Jung | 61a8368 | 2019-07-01 09:08:50 -0700 | [diff] [blame] | 186 | mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest) | 
|  | 187 | if !mod.Host() { | 
|  | 188 | t.Errorf("host bit is not set for a sh_test_host module.") | 
|  | 189 | } | 
|  | 190 | } | 
| Jaewoong Jung | 6e0eee5 | 2020-05-29 16:15:32 -0700 | [diff] [blame] | 191 |  | 
|  | 192 | func TestShTestHost_dataDeviceModules(t *testing.T) { | 
|  | 193 | ctx, config := testShBinary(t, ` | 
|  | 194 | sh_test_host { | 
|  | 195 | name: "foo", | 
|  | 196 | src: "test.sh", | 
|  | 197 | data_device_bins: ["bar"], | 
|  | 198 | data_device_libs: ["libbar"], | 
|  | 199 | } | 
|  | 200 |  | 
|  | 201 | cc_binary { | 
|  | 202 | name: "bar", | 
|  | 203 | shared_libs: ["libbar"], | 
|  | 204 | no_libcrt: true, | 
|  | 205 | nocrt: true, | 
|  | 206 | system_shared_libs: [], | 
|  | 207 | stl: "none", | 
|  | 208 | } | 
|  | 209 |  | 
|  | 210 | cc_library { | 
|  | 211 | name: "libbar", | 
|  | 212 | no_libcrt: true, | 
|  | 213 | nocrt: true, | 
|  | 214 | system_shared_libs: [], | 
|  | 215 | stl: "none", | 
|  | 216 | } | 
|  | 217 | `) | 
|  | 218 |  | 
|  | 219 | buildOS := android.BuildOs.String() | 
|  | 220 | variant := ctx.ModuleForTests("foo", buildOS+"_x86_64") | 
|  | 221 |  | 
|  | 222 | relocated := variant.Output("relocated/lib64/libbar.so") | 
|  | 223 | expectedInput := filepath.Join(buildDir, ".intermediates/libbar/android_arm64_armv8-a_shared/libbar.so") | 
|  | 224 | if relocated.Input.String() != expectedInput { | 
|  | 225 | t.Errorf("Unexpected relocation input, expected: %q, actual: %q", | 
|  | 226 | expectedInput, relocated.Input.String()) | 
|  | 227 | } | 
|  | 228 |  | 
|  | 229 | mod := variant.Module().(*ShTest) | 
|  | 230 | entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0] | 
|  | 231 | expectedData := []string{ | 
|  | 232 | filepath.Join(buildDir, ".intermediates/bar/android_arm64_armv8-a/:bar"), | 
|  | 233 | // libbar has been relocated, and so has a variant that matches the host arch. | 
|  | 234 | filepath.Join(buildDir, ".intermediates/foo/"+buildOS+"_x86_64/relocated/:lib64/libbar.so"), | 
|  | 235 | } | 
|  | 236 | actualData := entries.EntryMap["LOCAL_TEST_DATA"] | 
|  | 237 | if !reflect.DeepEqual(expectedData, actualData) { | 
|  | 238 | t.Errorf("Unexpected test data, expected: %q, actual: %q", expectedData, actualData) | 
|  | 239 | } | 
|  | 240 | } |