blob: 935ce4e5895f5768a2926542e67e518acdace823 [file] [log] [blame]
Liz Kammer8d62a4f2021-04-08 09:47:28 -04001package android
2
3import (
4 "os"
5 "path/filepath"
6 "reflect"
Yu Liu8d82ac52022-05-17 15:13:28 -07007 "strings"
Liz Kammer8d62a4f2021-04-08 09:47:28 -04008 "testing"
Chris Parsonsf874e462022-05-10 13:50:12 -04009
10 "android/soong/bazel/cquery"
Liz Kammer8d62a4f2021-04-08 09:47:28 -040011)
12
Yu Liu8d82ac52022-05-17 15:13:28 -070013var testConfig = TestConfig("out", nil, "", nil)
14
Liz Kammer8d62a4f2021-04-08 09:47:28 -040015func TestRequestResultsAfterInvokeBazel(t *testing.T) {
16 label := "//foo:bar"
Liz Kammer0940b892022-03-18 15:55:04 -040017 cfg := configKey{"arm64_armv8-a", Android}
Liz Kammer8d62a4f2021-04-08 09:47:28 -040018 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
Liz Kammer0940b892022-03-18 15:55:04 -040019 bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `//foo:bar|arm64_armv8-a|android>>out/foo/bar.txt`,
Liz Kammer8d62a4f2021-04-08 09:47:28 -040020 })
Chris Parsonsf874e462022-05-10 13:50:12 -040021 bazelContext.QueueBazelRequest(label, cquery.GetOutputFiles, cfg)
Yu Liu8d82ac52022-05-17 15:13:28 -070022 err := bazelContext.InvokeBazel(testConfig)
Liz Kammer8d62a4f2021-04-08 09:47:28 -040023 if err != nil {
24 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
25 }
Chris Parsonsf874e462022-05-10 13:50:12 -040026 g, err := bazelContext.GetOutputFiles(label, cfg)
27 if err != nil {
28 t.Errorf("Expected cquery results after running InvokeBazel(), but got err %v", err)
Liz Kammer8d62a4f2021-04-08 09:47:28 -040029 } else if w := []string{"out/foo/bar.txt"}; !reflect.DeepEqual(w, g) {
30 t.Errorf("Expected output %s, got %s", w, g)
31 }
32}
33
34func TestInvokeBazelWritesBazelFiles(t *testing.T) {
35 bazelContext, baseDir := testBazelContext(t, map[bazelCommand]string{})
Yu Liu8d82ac52022-05-17 15:13:28 -070036 err := bazelContext.InvokeBazel(testConfig)
Liz Kammer8d62a4f2021-04-08 09:47:28 -040037 if err != nil {
38 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
39 }
Lukacs T. Berki3069dd92021-05-11 16:54:29 +020040 if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "main.bzl")); os.IsNotExist(err) {
Liz Kammer8d62a4f2021-04-08 09:47:28 -040041 t.Errorf("Expected main.bzl to exist, but it does not")
42 } else if err != nil {
43 t.Errorf("Unexpected error stating main.bzl %s", err)
44 }
45
Lukacs T. Berki3069dd92021-05-11 16:54:29 +020046 if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "BUILD.bazel")); os.IsNotExist(err) {
Liz Kammer8d62a4f2021-04-08 09:47:28 -040047 t.Errorf("Expected BUILD.bazel to exist, but it does not")
48 } else if err != nil {
49 t.Errorf("Unexpected error stating BUILD.bazel %s", err)
50 }
51
Liz Kammer286c9fa2021-04-21 08:46:34 -040052 if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "WORKSPACE.bazel")); os.IsNotExist(err) {
Liz Kammer8d62a4f2021-04-08 09:47:28 -040053 t.Errorf("Expected WORKSPACE.bazel to exist, but it does not")
54 } else if err != nil {
55 t.Errorf("Unexpected error stating WORKSPACE.bazel %s", err)
56 }
57}
58
59func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {
Usta Shresthaacd5a0c2022-06-22 11:20:50 -040060 type testCase struct {
61 input string
62 command string
63 }
64
65 var testCases = []testCase{
66 {`
Liz Kammer8d62a4f2021-04-08 09:47:28 -040067{
68 "artifacts": [{
69 "id": 1,
70 "pathFragmentId": 1
71 }, {
72 "id": 2,
73 "pathFragmentId": 2
74 }],
75 "actions": [{
76 "targetId": 1,
77 "actionKey": "x",
78 "mnemonic": "x",
79 "arguments": ["touch", "foo"],
80 "inputDepSetIds": [1],
81 "outputIds": [1],
82 "primaryOutputId": 1
83 }],
84 "depSetOfFiles": [{
85 "id": 1,
86 "directArtifactIds": [1, 2]
87 }],
88 "pathFragments": [{
89 "id": 1,
90 "label": "one"
91 }, {
92 "id": 2,
93 "label": "two"
94 }]
95}`,
Usta Shresthaacd5a0c2022-06-22 11:20:50 -040096 "cd 'er' && rm -f one && touch foo",
97 }, {`
98{
99 "artifacts": [{
100 "id": 1,
101 "pathFragmentId": 10
102 }, {
103 "id": 2,
104 "pathFragmentId": 20
105 }],
106 "actions": [{
107 "targetId": 100,
108 "actionKey": "x",
109 "mnemonic": "x",
110 "arguments": ["bogus", "command"],
111 "outputIds": [1, 2],
112 "primaryOutputId": 1
113 }],
114 "pathFragments": [{
115 "id": 10,
116 "label": "one",
117 "parentId": 30
118 }, {
119 "id": 20,
120 "label": "one.d",
121 "parentId": 30
122 }, {
123 "id": 30,
124 "label": "parent"
125 }]
126}`,
127 `cd 'er' && rm -f parent/one && bogus command && sed -i'' -E 's@(^|\s|")bazel-out/@\1bo/@g' 'parent/one.d'`,
128 },
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400129 }
130
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400131 for _, testCase := range testCases {
132 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
133 bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: testCase.input})
134
135 err := bazelContext.InvokeBazel(testConfig)
136 if err != nil {
137 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
138 }
139
140 got := bazelContext.BuildStatementsToRegister()
141 if want := 1; len(got) != want {
142 t.Errorf("expected %d registered build statements, but got %#v", want, got)
143 }
144
145 cmd := RuleBuilderCommand{}
146 createCommand(&cmd, got[0], "er", "bo", PathContextForTesting(TestConfig("out", nil, "", nil)))
147 if actual := cmd.buf.String(); testCase.command != actual {
148 t.Errorf("expected: [%s], actual: [%s]", testCase.command, actual)
149 }
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400150 }
151}
152
Yu Liu8d82ac52022-05-17 15:13:28 -0700153func TestCoverageFlagsAfterInvokeBazel(t *testing.T) {
154 testConfig.productVariables.ClangCoverage = boolPtr(true)
155
156 testConfig.productVariables.NativeCoveragePaths = []string{"foo1", "foo2"}
157 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1", "bar2"}
158 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1,+foo2,-bar1,-bar2`)
159
160 testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
161 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
162 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1,-bar1`)
163
164 testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
165 testConfig.productVariables.NativeCoverageExcludePaths = nil
166 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1`)
167
168 testConfig.productVariables.NativeCoveragePaths = nil
169 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
170 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=-bar1`)
171
172 testConfig.productVariables.ClangCoverage = boolPtr(false)
173 actual := verifyExtraFlags(t, testConfig, ``)
174 if strings.Contains(actual, "--collect_code_coverage") ||
175 strings.Contains(actual, "--instrumentation_filter=") {
176 t.Errorf("Expected code coverage disabled, but got %#v", actual)
177 }
178}
179
180func verifyExtraFlags(t *testing.T, config Config, expected string) string {
181 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
182
183 err := bazelContext.InvokeBazel(config)
184 if err != nil {
185 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
186 }
187
188 flags := bazelContext.bazelRunner.(*mockBazelRunner).extraFlags
189 if expected := 3; len(flags) != expected {
190 t.Errorf("Expected %d extra flags got %#v", expected, flags)
191 }
192
193 actual := flags[1]
194 if !strings.Contains(actual, expected) {
195 t.Errorf("Expected %#v got %#v", expected, actual)
196 }
197
198 return actual
199}
200
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400201func testBazelContext(t *testing.T, bazelCommandResults map[bazelCommand]string) (*bazelContext, string) {
202 t.Helper()
203 p := bazelPaths{
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +0200204 soongOutDir: t.TempDir(),
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400205 outputBase: "outputbase",
206 workspaceDir: "workspace_dir",
207 }
Lukacs T. Berki3069dd92021-05-11 16:54:29 +0200208 aqueryCommand := bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400209 if _, exists := bazelCommandResults[aqueryCommand]; !exists {
210 bazelCommandResults[aqueryCommand] = "{}\n"
211 }
212 runner := &mockBazelRunner{bazelCommandResults: bazelCommandResults}
213 return &bazelContext{
214 bazelRunner: runner,
215 paths: &p,
216 requests: map[cqueryKey]bool{},
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +0200217 }, p.soongOutDir
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400218}