blob: e4ffe1680dc98110f3cf5f110e681ce4f75ace51 [file] [log] [blame]
Jingwen Chen8c1b97e2021-02-18 03:21:34 -05001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package bp2build
16
17import (
18 "android/soong/android"
19 "android/soong/cc"
20 "fmt"
21 "strings"
22 "testing"
23)
24
25func TestCcObjectBp2Build(t *testing.T) {
26 testCases := []struct {
27 description string
28 moduleTypeUnderTest string
29 moduleTypeUnderTestFactory android.ModuleFactory
30 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
31 blueprint string
32 expectedBazelTargets []string
33 filesystem map[string]string
34 }{
35 {
36 description: "simple cc_object generates cc_object with include header dep",
37 moduleTypeUnderTest: "cc_object",
38 moduleTypeUnderTestFactory: cc.ObjectFactory,
39 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
40 filesystem: map[string]string{
41 "a/b/foo.h": "",
42 "a/b/bar.h": "",
43 "a/b/c.c": "",
44 },
45 blueprint: `cc_object {
46 name: "foo",
47 local_include_dirs: ["include"],
48 cflags: [
49 "-Wno-gcc-compat",
50 "-Wall",
51 "-Werror",
52 ],
53 srcs: [
54 "a/b/*.h",
55 "a/b/c.c"
56 ],
57
58 bazel_module: { bp2build_available: true },
59}
60`,
61 expectedBazelTargets: []string{`cc_object(
62 name = "foo",
63 copts = [
64 "-fno-addrsig",
65 "-Wno-gcc-compat",
66 "-Wall",
67 "-Werror",
68 ],
69 local_include_dirs = [
70 "include",
71 ],
72 srcs = [
73 "a/b/bar.h",
74 "a/b/foo.h",
75 "a/b/c.c",
76 ],
77)`,
78 },
79 },
80 {
81 description: "simple cc_object with defaults",
82 moduleTypeUnderTest: "cc_object",
83 moduleTypeUnderTestFactory: cc.ObjectFactory,
84 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
85 blueprint: `cc_object {
86 name: "foo",
87 local_include_dirs: ["include"],
88 srcs: [
89 "a/b/*.h",
90 "a/b/c.c"
91 ],
92
93 defaults: ["foo_defaults"],
94 bazel_module: { bp2build_available: true },
95}
96
97cc_defaults {
98 name: "foo_defaults",
99 defaults: ["foo_bar_defaults"],
100 // TODO(b/178130668): handle configurable attributes that depend on the platform
101 arch: {
102 x86: {
103 cflags: ["-fPIC"],
104 },
105 x86_64: {
106 cflags: ["-fPIC"],
107 },
108 },
109}
110
111cc_defaults {
112 name: "foo_bar_defaults",
113 cflags: [
114 "-Wno-gcc-compat",
115 "-Wall",
116 "-Werror",
117 ],
118}
119`,
120 expectedBazelTargets: []string{`cc_object(
121 name = "foo",
122 copts = [
123 "-Wno-gcc-compat",
124 "-Wall",
125 "-Werror",
126 "-fno-addrsig",
127 ],
128 local_include_dirs = [
129 "include",
130 ],
131 srcs = [
132 "a/b/c.c",
133 ],
134)`,
135 },
136 },
137 }
138
139 dir := "."
140 for _, testCase := range testCases {
141 filesystem := make(map[string][]byte)
142 toParse := []string{
143 "Android.bp",
144 }
145 for f, content := range testCase.filesystem {
146 if strings.HasSuffix(f, "Android.bp") {
147 toParse = append(toParse, f)
148 }
149 filesystem[f] = []byte(content)
150 }
151 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
152 ctx := android.NewTestContext(config)
153 // Always register cc_defaults module factory
154 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
155
156 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
157 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
158 ctx.RegisterForBazelConversion()
159
160 _, errs := ctx.ParseFileList(dir, toParse)
161 if Errored(t, testCase.description, errs) {
162 continue
163 }
164 _, errs = ctx.ResolveDependencies(config)
165 if Errored(t, testCase.description, errs) {
166 continue
167 }
168
169 bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
170 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
171 fmt.Println(bazelTargets)
172 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
173 } else {
174 for i, target := range bazelTargets {
175 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
176 t.Errorf(
177 "%s: Expected generated Bazel target to be '%s', got '%s'",
178 testCase.description,
179 w,
180 g,
181 )
182 }
183 }
184 }
185 }
186}