• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 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	"io/ioutil"
19	"os"
20	"strings"
21	"testing"
22
23	"android/soong/android"
24)
25
26func setUp() {
27	var err error
28	buildDir, err = ioutil.TempDir("", "bazel_queryview_test")
29	if err != nil {
30		panic(err)
31	}
32}
33
34func tearDown() {
35	os.RemoveAll(buildDir)
36}
37
38func TestMain(m *testing.M) {
39	run := func() int {
40		setUp()
41		defer tearDown()
42
43		return m.Run()
44	}
45
46	os.Exit(run())
47}
48
49func TestGenerateModuleRuleShims(t *testing.T) {
50	moduleTypeFactories := map[string]android.ModuleFactory{
51		"custom":          customModuleFactoryBase,
52		"custom_test":     customTestModuleFactoryBase,
53		"custom_defaults": customDefaultsModuleFactoryBasic,
54	}
55	ruleShims := CreateRuleShims(moduleTypeFactories)
56
57	if len(ruleShims) != 1 {
58		t.Errorf("Expected to generate 1 rule shim, but got %d", len(ruleShims))
59	}
60
61	ruleShim := ruleShims["bp2build"]
62	expectedRules := []string{
63		"custom",
64		"custom_defaults",
65		"custom_test_",
66	}
67
68	if len(ruleShim.rules) != len(expectedRules) {
69		t.Errorf("Expected %d rules, but got %d", len(expectedRules), len(ruleShim.rules))
70	}
71
72	for i, rule := range ruleShim.rules {
73		if rule != expectedRules[i] {
74			t.Errorf("Expected rule shim to contain %s, but got %s", expectedRules[i], rule)
75		}
76	}
77	expectedBzl := `load("//build/bazel/queryview_rules:providers.bzl", "SoongModuleInfo")
78
79def _custom_impl(ctx):
80    return [SoongModuleInfo()]
81
82custom = rule(
83    implementation = _custom_impl,
84    attrs = {
85        "soong_module_name": attr.string(mandatory = True),
86        "soong_module_variant": attr.string(),
87        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
88        "api": attr.string(),
89        "arch_paths": attr.string_list(),
90        "arch_paths_exclude": attr.string_list(),
91        # bazel_module start
92#         "label": attr.string(),
93#         "bp2build_available": attr.bool(),
94        # bazel_module end
95        "bool_prop": attr.bool(),
96        "bool_ptr_prop": attr.bool(),
97        "embedded_prop": attr.string(),
98        "int64_ptr_prop": attr.int(),
99        # nested_props start
100#         "nested_prop": attr.string(),
101        # nested_props end
102        # nested_props_ptr start
103#         "nested_prop": attr.string(),
104        # nested_props_ptr end
105        "one_to_many_prop": attr.bool(),
106        "other_embedded_prop": attr.string(),
107        "string_list_prop": attr.string_list(),
108        "string_literal_prop": attr.string(),
109        "string_prop": attr.string(),
110        "string_ptr_prop": attr.string(),
111    },
112)
113
114def _custom_defaults_impl(ctx):
115    return [SoongModuleInfo()]
116
117custom_defaults = rule(
118    implementation = _custom_defaults_impl,
119    attrs = {
120        "soong_module_name": attr.string(mandatory = True),
121        "soong_module_variant": attr.string(),
122        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
123        "api": attr.string(),
124        "arch_paths": attr.string_list(),
125        "arch_paths_exclude": attr.string_list(),
126        "bool_prop": attr.bool(),
127        "bool_ptr_prop": attr.bool(),
128        "embedded_prop": attr.string(),
129        "int64_ptr_prop": attr.int(),
130        # nested_props start
131#         "nested_prop": attr.string(),
132        # nested_props end
133        # nested_props_ptr start
134#         "nested_prop": attr.string(),
135        # nested_props_ptr end
136        "one_to_many_prop": attr.bool(),
137        "other_embedded_prop": attr.string(),
138        "string_list_prop": attr.string_list(),
139        "string_literal_prop": attr.string(),
140        "string_prop": attr.string(),
141        "string_ptr_prop": attr.string(),
142    },
143)
144
145def _custom_test__impl(ctx):
146    return [SoongModuleInfo()]
147
148custom_test_ = rule(
149    implementation = _custom_test__impl,
150    attrs = {
151        "soong_module_name": attr.string(mandatory = True),
152        "soong_module_variant": attr.string(),
153        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
154        "api": attr.string(),
155        "arch_paths": attr.string_list(),
156        "arch_paths_exclude": attr.string_list(),
157        "bool_prop": attr.bool(),
158        "bool_ptr_prop": attr.bool(),
159        "embedded_prop": attr.string(),
160        "int64_ptr_prop": attr.int(),
161        # nested_props start
162#         "nested_prop": attr.string(),
163        # nested_props end
164        # nested_props_ptr start
165#         "nested_prop": attr.string(),
166        # nested_props_ptr end
167        "one_to_many_prop": attr.bool(),
168        "other_embedded_prop": attr.string(),
169        "string_list_prop": attr.string_list(),
170        "string_literal_prop": attr.string(),
171        "string_prop": attr.string(),
172        "string_ptr_prop": attr.string(),
173        # test_prop start
174#         "test_string_prop": attr.string(),
175        # test_prop end
176    },
177)
178`
179
180	if ruleShim.content != expectedBzl {
181		t.Errorf(
182			"Expected the generated rule shim bzl to be:\n%s\nbut got:\n%s",
183			expectedBzl,
184			ruleShim.content)
185	}
186}
187
188func TestGenerateSoongModuleBzl(t *testing.T) {
189	ruleShims := map[string]RuleShim{
190		"file1": RuleShim{
191			rules:   []string{"a", "b"},
192			content: "irrelevant",
193		},
194		"file2": RuleShim{
195			rules:   []string{"c", "d"},
196			content: "irrelevant",
197		},
198	}
199	files := CreateBazelFiles(android.NullConfig("out", "out/soong"), ruleShims, make(map[string]BazelTargets), QueryView)
200
201	var actualSoongModuleBzl BazelFile
202	for _, f := range files {
203		if f.Basename == "soong_module.bzl" {
204			actualSoongModuleBzl = f
205		}
206	}
207
208	expectedLoad := `load("//build/bazel/queryview_rules:file1.bzl", "a", "b")
209load("//build/bazel/queryview_rules:file2.bzl", "c", "d")
210`
211	expectedRuleMap := `soong_module_rule_map = {
212    "a": a,
213    "b": b,
214    "c": c,
215    "d": d,
216}`
217	if !strings.Contains(actualSoongModuleBzl.Contents, expectedLoad) {
218		t.Errorf(
219			"Generated soong_module.bzl:\n\n%s\n\n"+
220				"Could not find the load statement in the generated soong_module.bzl:\n%s",
221			actualSoongModuleBzl.Contents,
222			expectedLoad)
223	}
224
225	if !strings.Contains(actualSoongModuleBzl.Contents, expectedRuleMap) {
226		t.Errorf(
227			"Generated soong_module.bzl:\n\n%s\n\n"+
228				"Could not find the module -> rule map in the generated soong_module.bzl:\n%s",
229			actualSoongModuleBzl.Contents,
230			expectedRuleMap)
231	}
232}
233