blob: 013e19c967d4f5d368b21e6824ae3b1861a18e80 [file] [log] [blame]
Liz Kammer8d62a4f2021-04-08 09:47:28 -04001package android
2
3import (
Jason Wu118fd2b2022-10-27 18:41:15 +00004 "encoding/json"
Liz Kammer8d62a4f2021-04-08 09:47:28 -04005 "os"
6 "path/filepath"
7 "reflect"
Yu Liu8d82ac52022-05-17 15:13:28 -07008 "strings"
Liz Kammer8d62a4f2021-04-08 09:47:28 -04009 "testing"
Chris Parsonsf874e462022-05-10 13:50:12 -040010
11 "android/soong/bazel/cquery"
Jason Wu118fd2b2022-10-27 18:41:15 +000012 analysis_v2_proto "prebuilts/bazel/common/proto/analysis_v2"
Jingwen Chenf3b1ec32022-11-07 15:02:48 +000013
14 "google.golang.org/protobuf/proto"
Liz Kammer8d62a4f2021-04-08 09:47:28 -040015)
16
Yu Liu8d82ac52022-05-17 15:13:28 -070017var testConfig = TestConfig("out", nil, "", nil)
18
Liz Kammer8d62a4f2021-04-08 09:47:28 -040019func TestRequestResultsAfterInvokeBazel(t *testing.T) {
Chris Parsons86dc2c22022-09-28 14:58:41 -040020 label := "@//foo:bar"
Liz Kammer0940b892022-03-18 15:55:04 -040021 cfg := configKey{"arm64_armv8-a", Android}
Liz Kammer8d62a4f2021-04-08 09:47:28 -040022 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
Chris Parsons86dc2c22022-09-28 14:58:41 -040023 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 -040024 })
Chris Parsonsf874e462022-05-10 13:50:12 -040025 bazelContext.QueueBazelRequest(label, cquery.GetOutputFiles, cfg)
Sasha Smundak4975c822022-11-16 15:28:18 -080026 err := bazelContext.InvokeBazel(testConfig, nil)
Liz Kammer8d62a4f2021-04-08 09:47:28 -040027 if err != nil {
28 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
29 }
Chris Parsonsf874e462022-05-10 13:50:12 -040030 g, err := bazelContext.GetOutputFiles(label, cfg)
31 if err != nil {
32 t.Errorf("Expected cquery results after running InvokeBazel(), but got err %v", err)
Liz Kammer8d62a4f2021-04-08 09:47:28 -040033 } else if w := []string{"out/foo/bar.txt"}; !reflect.DeepEqual(w, g) {
34 t.Errorf("Expected output %s, got %s", w, g)
35 }
36}
37
38func TestInvokeBazelWritesBazelFiles(t *testing.T) {
39 bazelContext, baseDir := testBazelContext(t, map[bazelCommand]string{})
Sasha Smundak4975c822022-11-16 15:28:18 -080040 err := bazelContext.InvokeBazel(testConfig, nil)
Liz Kammer8d62a4f2021-04-08 09:47:28 -040041 if err != nil {
42 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
43 }
Lukacs T. Berki3069dd92021-05-11 16:54:29 +020044 if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "main.bzl")); os.IsNotExist(err) {
Liz Kammer8d62a4f2021-04-08 09:47:28 -040045 t.Errorf("Expected main.bzl to exist, but it does not")
46 } else if err != nil {
47 t.Errorf("Unexpected error stating main.bzl %s", err)
48 }
49
Lukacs T. Berki3069dd92021-05-11 16:54:29 +020050 if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "BUILD.bazel")); os.IsNotExist(err) {
Liz Kammer8d62a4f2021-04-08 09:47:28 -040051 t.Errorf("Expected BUILD.bazel to exist, but it does not")
52 } else if err != nil {
53 t.Errorf("Unexpected error stating BUILD.bazel %s", err)
54 }
55
Liz Kammer286c9fa2021-04-21 08:46:34 -040056 if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "WORKSPACE.bazel")); os.IsNotExist(err) {
Liz Kammer8d62a4f2021-04-08 09:47:28 -040057 t.Errorf("Expected WORKSPACE.bazel to exist, but it does not")
58 } else if err != nil {
59 t.Errorf("Unexpected error stating WORKSPACE.bazel %s", err)
60 }
61}
62
63func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {
Usta Shresthaacd5a0c2022-06-22 11:20:50 -040064 type testCase struct {
65 input string
66 command string
67 }
68
69 var testCases = []testCase{
70 {`
Liz Kammer8d62a4f2021-04-08 09:47:28 -040071{
Jason Wu118fd2b2022-10-27 18:41:15 +000072 "artifacts": [
73 { "id": 1, "path_fragment_id": 1 },
74 { "id": 2, "path_fragment_id": 2 }],
75 "actions": [{
76 "target_Id": 1,
77 "action_Key": "x",
78 "mnemonic": "x",
79 "arguments": ["touch", "foo"],
80 "input_dep_set_ids": [1],
81 "output_Ids": [1],
82 "primary_output_id": 1
83 }],
84 "dep_set_of_files": [
85 { "id": 1, "direct_artifact_ids": [1, 2] }],
86 "path_fragments": [
87 { "id": 1, "label": "one" },
88 { "id": 2, "label": "two" }]
Liz Kammer8d62a4f2021-04-08 09:47:28 -040089}`,
Jingwen Chenf3b1ec32022-11-07 15:02:48 +000090 "cd 'test/exec_root' && rm -rf 'one' && touch foo",
Usta Shresthaacd5a0c2022-06-22 11:20:50 -040091 }, {`
92{
Jason Wu118fd2b2022-10-27 18:41:15 +000093 "artifacts": [
94 { "id": 1, "path_fragment_id": 10 },
95 { "id": 2, "path_fragment_id": 20 }],
96 "actions": [{
97 "target_Id": 100,
98 "action_Key": "x",
99 "mnemonic": "x",
100 "arguments": ["bogus", "command"],
101 "output_Ids": [1, 2],
102 "primary_output_id": 1
103 }],
104 "path_fragments": [
105 { "id": 10, "label": "one", "parent_id": 30 },
106 { "id": 20, "label": "one.d", "parent_id": 30 },
107 { "id": 30, "label": "parent" }]
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400108}`,
Jingwen Chenf3b1ec32022-11-07 15:02:48 +0000109 `cd 'test/exec_root' && rm -rf '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 -0400110 },
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400111 }
112
Usta Shresthaef922252022-06-02 14:23:02 -0400113 for i, testCase := range testCases {
Jason Wu118fd2b2022-10-27 18:41:15 +0000114 data, err := JsonToActionGraphContainer(testCase.input)
115 if err != nil {
116 t.Error(err)
117 }
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400118 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
Jason Wu118fd2b2022-10-27 18:41:15 +0000119 bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: string(data)})
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400120
Sasha Smundak4975c822022-11-16 15:28:18 -0800121 err = bazelContext.InvokeBazel(testConfig, nil)
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400122 if err != nil {
Usta Shresthaef922252022-06-02 14:23:02 -0400123 t.Fatalf("testCase #%d: did not expect error invoking Bazel, but got %s", i+1, err)
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400124 }
125
126 got := bazelContext.BuildStatementsToRegister()
127 if want := 1; len(got) != want {
Sasha Smundake3cf1ab2022-06-30 11:36:18 -0700128 t.Fatalf("expected %d registered build statements, but got %#v", want, got)
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400129 }
130
131 cmd := RuleBuilderCommand{}
Colin Crossd5c7ddb2022-12-06 16:27:17 -0800132 ctx := builderContextForTests{PathContextForTesting(TestConfig("out", nil, "", nil))}
133 createCommand(&cmd, got[0], "test/exec_root", "test/bazel_out", ctx)
Usta Shresthaef922252022-06-02 14:23:02 -0400134 if actual, expected := cmd.buf.String(), testCase.command; expected != actual {
135 t.Errorf("expected: [%s], actual: [%s]", expected, actual)
Usta Shresthaacd5a0c2022-06-22 11:20:50 -0400136 }
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400137 }
138}
139
Yu Liu8d82ac52022-05-17 15:13:28 -0700140func TestCoverageFlagsAfterInvokeBazel(t *testing.T) {
141 testConfig.productVariables.ClangCoverage = boolPtr(true)
142
143 testConfig.productVariables.NativeCoveragePaths = []string{"foo1", "foo2"}
144 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1", "bar2"}
145 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1,+foo2,-bar1,-bar2`)
146
147 testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
148 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
149 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1,-bar1`)
150
151 testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
152 testConfig.productVariables.NativeCoverageExcludePaths = nil
153 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+foo1`)
154
155 testConfig.productVariables.NativeCoveragePaths = nil
156 testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
157 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=-bar1`)
158
Wei Licbd181c2022-11-16 08:59:23 -0800159 testConfig.productVariables.NativeCoveragePaths = []string{"*"}
160 testConfig.productVariables.NativeCoverageExcludePaths = nil
161 verifyExtraFlags(t, testConfig, `--collect_code_coverage --instrumentation_filter=+.*`)
162
Yu Liu8d82ac52022-05-17 15:13:28 -0700163 testConfig.productVariables.ClangCoverage = boolPtr(false)
164 actual := verifyExtraFlags(t, testConfig, ``)
165 if strings.Contains(actual, "--collect_code_coverage") ||
166 strings.Contains(actual, "--instrumentation_filter=") {
167 t.Errorf("Expected code coverage disabled, but got %#v", actual)
168 }
169}
170
171func verifyExtraFlags(t *testing.T, config Config, expected string) string {
172 bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
173
Sasha Smundak4975c822022-11-16 15:28:18 -0800174 err := bazelContext.InvokeBazel(config, nil)
Yu Liu8d82ac52022-05-17 15:13:28 -0700175 if err != nil {
176 t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
177 }
178
179 flags := bazelContext.bazelRunner.(*mockBazelRunner).extraFlags
180 if expected := 3; len(flags) != expected {
181 t.Errorf("Expected %d extra flags got %#v", expected, flags)
182 }
183
184 actual := flags[1]
185 if !strings.Contains(actual, expected) {
186 t.Errorf("Expected %#v got %#v", expected, actual)
187 }
188
189 return actual
190}
191
Sasha Smundak39a301c2022-12-29 17:11:49 -0800192func testBazelContext(t *testing.T, bazelCommandResults map[bazelCommand]string) (*mixedBuildBazelContext, string) {
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400193 t.Helper()
194 p := bazelPaths{
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +0200195 soongOutDir: t.TempDir(),
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400196 outputBase: "outputbase",
197 workspaceDir: "workspace_dir",
198 }
Lukacs T. Berki3069dd92021-05-11 16:54:29 +0200199 aqueryCommand := bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400200 if _, exists := bazelCommandResults[aqueryCommand]; !exists {
Sasha Smundak4975c822022-11-16 15:28:18 -0800201 bazelCommandResults[aqueryCommand] = ""
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400202 }
203 runner := &mockBazelRunner{bazelCommandResults: bazelCommandResults}
Sasha Smundak39a301c2022-12-29 17:11:49 -0800204 return &mixedBuildBazelContext{
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400205 bazelRunner: runner,
206 paths: &p,
207 requests: map[cqueryKey]bool{},
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +0200208 }, p.soongOutDir
Liz Kammer8d62a4f2021-04-08 09:47:28 -0400209}
Jason Wu118fd2b2022-10-27 18:41:15 +0000210
211// Transform the json format to ActionGraphContainer
212func JsonToActionGraphContainer(inputString string) ([]byte, error) {
213 var aqueryProtoResult analysis_v2_proto.ActionGraphContainer
214 err := json.Unmarshal([]byte(inputString), &aqueryProtoResult)
215 if err != nil {
216 return []byte(""), err
217 }
218 data, _ := proto.Marshal(&aqueryProtoResult)
219 return data, err
220}