blob: ec2541b3d47553f7f39499567c3cdc1f1d99e153 [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{
Sasha Smundake3cf1ab2022-06-30 11:36:18 -070068 "artifacts": [
69 { "id": 1, "pathFragmentId": 1 },
70 { "id": 2, "pathFragmentId": 2 }],
Liz Kammer8d62a4f2021-04-08 09:47:28 -040071 "actions": [{
72 "targetId": 1,
73 "actionKey": "x",
74 "mnemonic": "x",
75 "arguments": ["touch", "foo"],
76 "inputDepSetIds": [1],
77 "outputIds": [1],
78 "primaryOutputId": 1
79 }],
Sasha Smundake3cf1ab2022-06-30 11:36:18 -070080 "depSetOfFiles": [
81 { "id": 1, "directArtifactIds": [1, 2] }],
82 "pathFragments": [
83 { "id": 1, "label": "one" },
84 { "id": 2, "label": "two" }]
Liz Kammer8d62a4f2021-04-08 09:47:28 -040085}`,
Usta Shresthaef922252022-06-02 14:23:02 -040086 "cd 'test/exec_root' && rm -f 'one' && touch foo",
Usta Shresthaacd5a0c2022-06-22 11:20:50 -040087 }, {`
88{
Sasha Smundake3cf1ab2022-06-30 11:36:18 -070089 "artifacts": [
90 { "id": 1, "pathFragmentId": 10 },
91 { "id": 2, "pathFragmentId": 20 }],
Usta Shresthaacd5a0c2022-06-22 11:20:50 -040092 "actions": [{
93 "targetId": 100,
94 "actionKey": "x",
95 "mnemonic": "x",
96 "arguments": ["bogus", "command"],
97 "outputIds": [1, 2],
98 "primaryOutputId": 1
99 }],
Sasha Smundake3cf1ab2022-06-30 11:36:18 -0700100 "pathFragments": [
101 { "id": 10, "label": "one", "parentId": 30 },
102 { "id": 20, "label": "one.d", "parentId": 30 },
103 { "id": 30, "label": "parent" }]
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400104}`,
Usta Shresthaef922252022-06-02 14:23:02 -0400105 `cd 'test/exec_root' && rm -f 'parent/one' && bogus command && sed -i'' -E 's@(^|\s|")bazel-out/@\1test/bazel_out/@g' 'parent/one.d'`,
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400106 },
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400107 }
108
Usta Shresthaef922252022-06-02 14:23:02 -0400109 for i, testCase := range testCases {
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400110 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
111 bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: testCase.input})
112
113 err := bazelContext.InvokeBazel(testConfig)
114 if err != nil {
Usta Shresthaef922252022-06-02 14:23:02 -0400115 t.Fatalf("testCase #%d: did not expect error invoking Bazel, but got %s", i+1, err)
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400116 }
117
118 got := bazelContext.BuildStatementsToRegister()
119 if want := 1; len(got) != want {
Sasha Smundake3cf1ab2022-06-30 11:36:18 -0700120 t.Fatalf("expected %d registered build statements, but got %#v", want, got)
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400121 }
122
123 cmd := RuleBuilderCommand{}
Usta Shresthaef922252022-06-02 14:23:02 -0400124 createCommand(&cmd, got[0], "test/exec_root", "test/bazel_out", PathContextForTesting(TestConfig("out", nil, "", nil)))
125 if actual, expected := cmd.buf.String(), testCase.command; expected != actual {
126 t.Errorf("expected: [%s], actual: [%s]", expected, actual)
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400127 }
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400128 }
129}
130
Yu Liu8d82ac52022-05-17 15:13:28 -0700131func TestCoverageFlagsAfterInvokeBazel(t *testing.T) {
132 testConfig.productVariables.ClangCoverage = boolPtr(true)
133
134 testConfig.productVariables.NativeCoveragePaths = []string{"foo1", "foo2"}
135 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1", "bar2"}
136 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1,+foo2,-bar1,-bar2`)
137
138 testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
139 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
140 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1,-bar1`)
141
142 testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
143 testConfig.productVariables.NativeCoverageExcludePaths = nil
144 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1`)
145
146 testConfig.productVariables.NativeCoveragePaths = nil
147 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
148 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=-bar1`)
149
150 testConfig.productVariables.ClangCoverage = boolPtr(false)
151 actual := verifyExtraFlags(t, testConfig, ``)
152 if strings.Contains(actual, "--collect_code_coverage") ||
153 strings.Contains(actual, "--instrumentation_filter=") {
154 t.Errorf("Expected code coverage disabled, but got %#v", actual)
155 }
156}
157
158func verifyExtraFlags(t *testing.T, config Config, expected string) string {
159 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
160
161 err := bazelContext.InvokeBazel(config)
162 if err != nil {
163 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
164 }
165
166 flags := bazelContext.bazelRunner.(*mockBazelRunner).extraFlags
167 if expected := 3; len(flags) != expected {
168 t.Errorf("Expected %d extra flags got %#v", expected, flags)
169 }
170
171 actual := flags[1]
172 if !strings.Contains(actual, expected) {
173 t.Errorf("Expected %#v got %#v", expected, actual)
174 }
175
176 return actual
177}
178
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400179func testBazelContext(t *testing.T, bazelCommandResults map[bazelCommand]string) (*bazelContext, string) {
180 t.Helper()
181 p := bazelPaths{
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +0200182 soongOutDir: t.TempDir(),
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400183 outputBase: "outputbase",
184 workspaceDir: "workspace_dir",
185 }
Lukacs T. Berki3069dd92021-05-11 16:54:29 +0200186 aqueryCommand := bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400187 if _, exists := bazelCommandResults[aqueryCommand]; !exists {
188 bazelCommandResults[aqueryCommand] = "{}\n"
189 }
190 runner := &mockBazelRunner{bazelCommandResults: bazelCommandResults}
191 return &bazelContext{
192 bazelRunner: runner,
193 paths: &p,
194 requests: map[cqueryKey]bool{},
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +0200195 }, p.soongOutDir
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400196}