blob: 5271f8d9e1b95de8ae9df05152089608c824c58c [file] [log] [blame]
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +01001#!/bin/bash -eu
2
3# This test exercises the bootstrapping process of the build system
4# in a source tree that only contains enough files for Bazel and Soong to work.
5
Lukacs T. Berki3b730c42021-04-08 13:21:13 +02006source "$(dirname "$0")/lib.sh"
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +01007
8function test_smoke {
9 setup
10 run_soong
11}
12
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +010013function test_null_build() {
14 setup
15 run_soong
16 local bootstrap_mtime1=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
17 local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
18 run_soong
19 local bootstrap_mtime2=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
20 local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
21
22 if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then
23 # Bootstrapping is always done. It doesn't take a measurable amount of time.
24 fail "Bootstrap Ninja file did not change on null build"
25 fi
26
27 if [[ "$output_mtime1" != "$output_mtime2" ]]; then
28 fail "Output Ninja file changed on null build"
29 fi
30}
31
32function test_soong_build_rebuilt_if_blueprint_changes() {
33 setup
34 run_soong
35 local mtime1=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
36
37 sed -i 's/pluginGenSrcCmd/pluginGenSrcCmd2/g' build/blueprint/bootstrap/bootstrap.go
38
39 run_soong
40 local mtime2=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
41
42 if [[ "$mtime1" == "$mtime2" ]]; then
43 fail "Bootstrap Ninja file did not change"
44 fi
45}
46
47function test_change_android_bp() {
48 setup
49 mkdir -p a
50 cat > a/Android.bp <<'EOF'
51python_binary_host {
52 name: "my_little_binary_host",
53 srcs: ["my_little_binary_host.py"]
54}
55EOF
56 touch a/my_little_binary_host.py
57 run_soong
58
59 grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja || fail "module not found"
60
61 cat > a/Android.bp <<'EOF'
62python_binary_host {
63 name: "my_great_binary_host",
64 srcs: ["my_great_binary_host.py"]
65}
66EOF
67 touch a/my_great_binary_host.py
68 run_soong
69
70 grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja && fail "old module found"
71 grep -q "^# Module:.*my_great_binary_host" out/soong/build.ninja || fail "new module not found"
72}
73
74
75function test_add_android_bp() {
76 setup
77 run_soong
78 local mtime1=$(stat -c "%y" out/soong/build.ninja)
79
80 mkdir -p a
81 cat > a/Android.bp <<'EOF'
82python_binary_host {
83 name: "my_little_binary_host",
84 srcs: ["my_little_binary_host.py"]
85}
86EOF
87 touch a/my_little_binary_host.py
88 run_soong
89
90 local mtime2=$(stat -c "%y" out/soong/build.ninja)
91 if [[ "$mtime1" == "$mtime2" ]]; then
92 fail "Output Ninja file did not change"
93 fi
94
95 grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "New module not in output"
96
97 run_soong
98}
99
100function test_delete_android_bp() {
101 setup
102 mkdir -p a
103 cat > a/Android.bp <<'EOF'
104python_binary_host {
105 name: "my_little_binary_host",
106 srcs: ["my_little_binary_host.py"]
107}
108EOF
109 touch a/my_little_binary_host.py
110 run_soong
111
112 grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "Module not in output"
113
114 rm a/Android.bp
115 run_soong
116
117 grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja && fail "Old module in output"
118}
119
120function test_add_file_to_glob() {
121 setup
122
123 mkdir -p a
124 cat > a/Android.bp <<'EOF'
125python_binary_host {
126 name: "my_little_binary_host",
127 srcs: ["*.py"],
128}
129EOF
130 touch a/my_little_binary_host.py
131 run_soong
132 local mtime1=$(stat -c "%y" out/soong/build.ninja)
133
134 touch a/my_little_library.py
135 run_soong
136
137 local mtime2=$(stat -c "%y" out/soong/build.ninja)
138 if [[ "$mtime1" == "$mtime2" ]]; then
139 fail "Output Ninja file did not change"
140 fi
141
142 grep -q my_little_library.py out/soong/build.ninja || fail "new file is not in output"
143}
144
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100145function test_soong_build_rerun_iff_environment_changes() {
146 setup
147
148 mkdir -p cherry
149 cat > cherry/Android.bp <<'EOF'
150bootstrap_go_package {
151 name: "cherry",
152 pkgPath: "android/soong/cherry",
153 deps: [
154 "blueprint",
155 "soong",
156 "soong-android",
157 ],
158 srcs: [
159 "cherry.go",
160 ],
161 pluginFor: ["soong_build"],
162}
163EOF
164
165 cat > cherry/cherry.go <<'EOF'
166package cherry
167
168import (
169 "android/soong/android"
170 "github.com/google/blueprint"
171)
172
173var (
174 pctx = android.NewPackageContext("cherry")
175)
176
177func init() {
178 android.RegisterSingletonType("cherry", CherrySingleton)
179}
180
181func CherrySingleton() android.Singleton {
182 return &cherrySingleton{}
183}
184
185type cherrySingleton struct{}
186
187func (p *cherrySingleton) GenerateBuildActions(ctx android.SingletonContext) {
188 cherryRule := ctx.Rule(pctx, "cherry",
189 blueprint.RuleParams{
190 Command: "echo CHERRY IS " + ctx.Config().Getenv("CHERRY") + " > ${out}",
191 CommandDeps: []string{},
192 Description: "Cherry",
193 })
194
195 outputFile := android.PathForOutput(ctx, "cherry", "cherry.txt")
196 var deps android.Paths
197
198 ctx.Build(pctx, android.BuildParams{
199 Rule: cherryRule,
200 Output: outputFile,
201 Inputs: deps,
202 })
203}
204EOF
205
206 export CHERRY=TASTY
207 run_soong
208 grep -q "CHERRY IS TASTY" out/soong/build.ninja \
209 || fail "first value of environment variable is not used"
210
211 export CHERRY=RED
212 run_soong
213 grep -q "CHERRY IS RED" out/soong/build.ninja \
214 || fail "second value of environment variable not used"
215 local mtime1=$(stat -c "%y" out/soong/build.ninja)
216
217 run_soong
218 local mtime2=$(stat -c "%y" out/soong/build.ninja)
219 if [[ "$mtime1" != "$mtime2" ]]; then
220 fail "Output Ninja file changed when environment variable did not"
221 fi
222
223}
224
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100225function test_add_file_to_soong_build() {
226 setup
227 run_soong
228 local mtime1=$(stat -c "%y" out/soong/build.ninja)
229
230 mkdir -p a
231 cat > a/Android.bp <<'EOF'
232bootstrap_go_package {
233 name: "picard-soong-rules",
234 pkgPath: "android/soong/picard",
235 deps: [
236 "blueprint",
237 "soong",
238 "soong-android",
239 ],
240 srcs: [
241 "picard.go",
242 ],
243 pluginFor: ["soong_build"],
244}
245EOF
246
247 cat > a/picard.go <<'EOF'
248package picard
249
250import (
251 "android/soong/android"
252 "github.com/google/blueprint"
253)
254
255var (
256 pctx = android.NewPackageContext("picard")
257)
258
259func init() {
260 android.RegisterSingletonType("picard", PicardSingleton)
261}
262
263func PicardSingleton() android.Singleton {
264 return &picardSingleton{}
265}
266
267type picardSingleton struct{}
268
269func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) {
270 picardRule := ctx.Rule(pctx, "picard",
271 blueprint.RuleParams{
272 Command: "echo Make it so. > ${out}",
273 CommandDeps: []string{},
274 Description: "Something quotable",
275 })
276
277 outputFile := android.PathForOutput(ctx, "picard", "picard.txt")
278 var deps android.Paths
279
280 ctx.Build(pctx, android.BuildParams{
281 Rule: picardRule,
282 Output: outputFile,
283 Inputs: deps,
284 })
285}
286
287EOF
288
289 run_soong
290 local mtime2=$(stat -c "%y" out/soong/build.ninja)
291 if [[ "$mtime1" == "$mtime2" ]]; then
292 fail "Output Ninja file did not change"
293 fi
294
295 grep -q "Make it so" out/soong/build.ninja || fail "New action not present"
296}
297
Colin Crossc02504e2021-04-08 10:34:16 -0700298# Tests a glob in a build= statement in an Android.bp file, which is interpreted
299# during bootstrapping.
300function test_glob_during_bootstrapping() {
301 setup
302
303 mkdir -p a
304 cat > a/Android.bp <<'EOF'
305build=["foo*.bp"]
306EOF
307 cat > a/fooa.bp <<'EOF'
308bootstrap_go_package {
309 name: "picard-soong-rules",
310 pkgPath: "android/soong/picard",
311 deps: [
312 "blueprint",
313 "soong",
314 "soong-android",
315 ],
316 srcs: [
317 "picard.go",
318 ],
319 pluginFor: ["soong_build"],
320}
321EOF
322
323 cat > a/picard.go <<'EOF'
324package picard
325
326import (
327 "android/soong/android"
328 "github.com/google/blueprint"
329)
330
331var (
332 pctx = android.NewPackageContext("picard")
333)
334
335func init() {
336 android.RegisterSingletonType("picard", PicardSingleton)
337}
338
339func PicardSingleton() android.Singleton {
340 return &picardSingleton{}
341}
342
343type picardSingleton struct{}
344
345var Message = "Make it so."
346
347func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) {
348 picardRule := ctx.Rule(pctx, "picard",
349 blueprint.RuleParams{
350 Command: "echo " + Message + " > ${out}",
351 CommandDeps: []string{},
352 Description: "Something quotable",
353 })
354
355 outputFile := android.PathForOutput(ctx, "picard", "picard.txt")
356 var deps android.Paths
357
358 ctx.Build(pctx, android.BuildParams{
359 Rule: picardRule,
360 Output: outputFile,
361 Inputs: deps,
362 })
363}
364
365EOF
366
367 run_soong
368 local mtime1=$(stat -c "%y" out/soong/build.ninja)
369
370 grep -q "Make it so" out/soong/build.ninja || fail "Original action not present"
371
372 cat > a/foob.bp <<'EOF'
373bootstrap_go_package {
374 name: "worf-soong-rules",
375 pkgPath: "android/soong/worf",
376 deps: [
377 "blueprint",
378 "soong",
379 "soong-android",
380 "picard-soong-rules",
381 ],
382 srcs: [
383 "worf.go",
384 ],
385 pluginFor: ["soong_build"],
386}
387EOF
388
389 cat > a/worf.go <<'EOF'
390package worf
391
392import "android/soong/picard"
393
394func init() {
395 picard.Message = "Engage."
396}
397EOF
398
399 run_soong
400 local mtime2=$(stat -c "%y" out/soong/build.ninja)
401 if [[ "$mtime1" == "$mtime2" ]]; then
402 fail "Output Ninja file did not change"
403 fi
404
405 grep -q "Engage" out/soong/build.ninja || fail "New action not present"
406
407 grep -q "Make it so" out/soong/build.ninja && fail "Original action still present"
408}
409
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100410function test_null_build_after_docs {
411 setup
412 run_soong
413 local mtime1=$(stat -c "%y" out/soong/build.ninja)
414
415 prebuilts/build-tools/linux-x86/bin/ninja -f out/soong/build.ninja soong_docs
416 run_soong
417 local mtime2=$(stat -c "%y" out/soong/build.ninja)
418
419 if [[ "$mtime1" != "$mtime2" ]]; then
420 fail "Output Ninja file changed on null build"
421 fi
422}
423
Lukacs T. Berki97bb9f12021-04-01 18:28:45 +0200424function test_dump_json_module_graph() {
425 setup
426 SOONG_DUMP_JSON_MODULE_GRAPH="$MOCK_TOP/modules.json" run_soong
427 if [[ ! -r "$MOCK_TOP/modules.json" ]]; then
428 fail "JSON file was not created"
429 fi
430}
431
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100432test_smoke
433test_null_build
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100434test_null_build_after_docs
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100435test_soong_build_rebuilt_if_blueprint_changes
436test_add_file_to_glob
437test_add_android_bp
438test_change_android_bp
439test_delete_android_bp
440test_add_file_to_soong_build
Colin Crossc02504e2021-04-08 10:34:16 -0700441test_glob_during_bootstrapping
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100442test_soong_build_rerun_iff_environment_changes
Lukacs T. Berki97bb9f12021-04-01 18:28:45 +0200443test_dump_json_module_graph