blob: f1ebca29646781057886c4c3c0752b44f66815b2 [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
Lukacs T. Berkif8e24282021-04-14 10:31:00 +0200117 if grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja; then
118 fail "Old module in output"
119 fi
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100120}
121
122function test_add_file_to_glob() {
123 setup
124
125 mkdir -p a
126 cat > a/Android.bp <<'EOF'
127python_binary_host {
128 name: "my_little_binary_host",
129 srcs: ["*.py"],
130}
131EOF
132 touch a/my_little_binary_host.py
133 run_soong
134 local mtime1=$(stat -c "%y" out/soong/build.ninja)
135
136 touch a/my_little_library.py
137 run_soong
138
139 local mtime2=$(stat -c "%y" out/soong/build.ninja)
140 if [[ "$mtime1" == "$mtime2" ]]; then
141 fail "Output Ninja file did not change"
142 fi
143
144 grep -q my_little_library.py out/soong/build.ninja || fail "new file is not in output"
145}
146
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100147function test_soong_build_rerun_iff_environment_changes() {
148 setup
149
150 mkdir -p cherry
151 cat > cherry/Android.bp <<'EOF'
152bootstrap_go_package {
153 name: "cherry",
154 pkgPath: "android/soong/cherry",
155 deps: [
156 "blueprint",
157 "soong",
158 "soong-android",
159 ],
160 srcs: [
161 "cherry.go",
162 ],
163 pluginFor: ["soong_build"],
164}
165EOF
166
167 cat > cherry/cherry.go <<'EOF'
168package cherry
169
170import (
171 "android/soong/android"
172 "github.com/google/blueprint"
173)
174
175var (
176 pctx = android.NewPackageContext("cherry")
177)
178
179func init() {
180 android.RegisterSingletonType("cherry", CherrySingleton)
181}
182
183func CherrySingleton() android.Singleton {
184 return &cherrySingleton{}
185}
186
187type cherrySingleton struct{}
188
189func (p *cherrySingleton) GenerateBuildActions(ctx android.SingletonContext) {
190 cherryRule := ctx.Rule(pctx, "cherry",
191 blueprint.RuleParams{
192 Command: "echo CHERRY IS " + ctx.Config().Getenv("CHERRY") + " > ${out}",
193 CommandDeps: []string{},
194 Description: "Cherry",
195 })
196
197 outputFile := android.PathForOutput(ctx, "cherry", "cherry.txt")
198 var deps android.Paths
199
200 ctx.Build(pctx, android.BuildParams{
201 Rule: cherryRule,
202 Output: outputFile,
203 Inputs: deps,
204 })
205}
206EOF
207
208 export CHERRY=TASTY
209 run_soong
210 grep -q "CHERRY IS TASTY" out/soong/build.ninja \
211 || fail "first value of environment variable is not used"
212
213 export CHERRY=RED
214 run_soong
215 grep -q "CHERRY IS RED" out/soong/build.ninja \
216 || fail "second value of environment variable not used"
217 local mtime1=$(stat -c "%y" out/soong/build.ninja)
218
219 run_soong
220 local mtime2=$(stat -c "%y" out/soong/build.ninja)
221 if [[ "$mtime1" != "$mtime2" ]]; then
222 fail "Output Ninja file changed when environment variable did not"
223 fi
224
225}
226
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100227function test_add_file_to_soong_build() {
228 setup
229 run_soong
230 local mtime1=$(stat -c "%y" out/soong/build.ninja)
231
232 mkdir -p a
233 cat > a/Android.bp <<'EOF'
234bootstrap_go_package {
235 name: "picard-soong-rules",
236 pkgPath: "android/soong/picard",
237 deps: [
238 "blueprint",
239 "soong",
240 "soong-android",
241 ],
242 srcs: [
243 "picard.go",
244 ],
245 pluginFor: ["soong_build"],
246}
247EOF
248
249 cat > a/picard.go <<'EOF'
250package picard
251
252import (
253 "android/soong/android"
254 "github.com/google/blueprint"
255)
256
257var (
258 pctx = android.NewPackageContext("picard")
259)
260
261func init() {
262 android.RegisterSingletonType("picard", PicardSingleton)
263}
264
265func PicardSingleton() android.Singleton {
266 return &picardSingleton{}
267}
268
269type picardSingleton struct{}
270
271func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) {
272 picardRule := ctx.Rule(pctx, "picard",
273 blueprint.RuleParams{
274 Command: "echo Make it so. > ${out}",
275 CommandDeps: []string{},
276 Description: "Something quotable",
277 })
278
279 outputFile := android.PathForOutput(ctx, "picard", "picard.txt")
280 var deps android.Paths
281
282 ctx.Build(pctx, android.BuildParams{
283 Rule: picardRule,
284 Output: outputFile,
285 Inputs: deps,
286 })
287}
288
289EOF
290
291 run_soong
292 local mtime2=$(stat -c "%y" out/soong/build.ninja)
293 if [[ "$mtime1" == "$mtime2" ]]; then
294 fail "Output Ninja file did not change"
295 fi
296
297 grep -q "Make it so" out/soong/build.ninja || fail "New action not present"
298}
299
Colin Crossc02504e2021-04-08 10:34:16 -0700300# Tests a glob in a build= statement in an Android.bp file, which is interpreted
301# during bootstrapping.
302function test_glob_during_bootstrapping() {
303 setup
304
305 mkdir -p a
306 cat > a/Android.bp <<'EOF'
307build=["foo*.bp"]
308EOF
309 cat > a/fooa.bp <<'EOF'
310bootstrap_go_package {
311 name: "picard-soong-rules",
312 pkgPath: "android/soong/picard",
313 deps: [
314 "blueprint",
315 "soong",
316 "soong-android",
317 ],
318 srcs: [
319 "picard.go",
320 ],
321 pluginFor: ["soong_build"],
322}
323EOF
324
325 cat > a/picard.go <<'EOF'
326package picard
327
328import (
329 "android/soong/android"
330 "github.com/google/blueprint"
331)
332
333var (
334 pctx = android.NewPackageContext("picard")
335)
336
337func init() {
338 android.RegisterSingletonType("picard", PicardSingleton)
339}
340
341func PicardSingleton() android.Singleton {
342 return &picardSingleton{}
343}
344
345type picardSingleton struct{}
346
347var Message = "Make it so."
348
349func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) {
350 picardRule := ctx.Rule(pctx, "picard",
351 blueprint.RuleParams{
352 Command: "echo " + Message + " > ${out}",
353 CommandDeps: []string{},
354 Description: "Something quotable",
355 })
356
357 outputFile := android.PathForOutput(ctx, "picard", "picard.txt")
358 var deps android.Paths
359
360 ctx.Build(pctx, android.BuildParams{
361 Rule: picardRule,
362 Output: outputFile,
363 Inputs: deps,
364 })
365}
366
367EOF
368
369 run_soong
370 local mtime1=$(stat -c "%y" out/soong/build.ninja)
371
372 grep -q "Make it so" out/soong/build.ninja || fail "Original action not present"
373
374 cat > a/foob.bp <<'EOF'
375bootstrap_go_package {
376 name: "worf-soong-rules",
377 pkgPath: "android/soong/worf",
378 deps: [
379 "blueprint",
380 "soong",
381 "soong-android",
382 "picard-soong-rules",
383 ],
384 srcs: [
385 "worf.go",
386 ],
387 pluginFor: ["soong_build"],
388}
389EOF
390
391 cat > a/worf.go <<'EOF'
392package worf
393
394import "android/soong/picard"
395
396func init() {
397 picard.Message = "Engage."
398}
399EOF
400
401 run_soong
402 local mtime2=$(stat -c "%y" out/soong/build.ninja)
403 if [[ "$mtime1" == "$mtime2" ]]; then
404 fail "Output Ninja file did not change"
405 fi
406
407 grep -q "Engage" out/soong/build.ninja || fail "New action not present"
408
Lukacs T. Berkif8e24282021-04-14 10:31:00 +0200409 if grep -q "Make it so" out/soong/build.ninja; then
410 fail "Original action still present"
411 fi
Colin Crossc02504e2021-04-08 10:34:16 -0700412}
413
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100414function test_null_build_after_docs {
415 setup
416 run_soong
417 local mtime1=$(stat -c "%y" out/soong/build.ninja)
418
419 prebuilts/build-tools/linux-x86/bin/ninja -f out/soong/build.ninja soong_docs
420 run_soong
421 local mtime2=$(stat -c "%y" out/soong/build.ninja)
422
423 if [[ "$mtime1" != "$mtime2" ]]; then
424 fail "Output Ninja file changed on null build"
425 fi
426}
427
Lukacs T. Berkif8e24282021-04-14 10:31:00 +0200428function test_integrated_bp2build_smoke {
429 setup
430 INTEGRATED_BP2BUILD=1 run_soong
431 if [[ ! -e out/soong/.bootstrap/bp2build_workspace_marker ]]; then
Lukacs T. Berkid518e1a2021-04-14 13:49:50 +0200432 fail "bp2build marker file not created"
433 fi
434}
435
436function test_integrated_bp2build_add_android_bp {
437 setup
438
439 mkdir -p a
440 touch a/a.txt
441 cat > a/Android.bp <<'EOF'
442filegroup {
443 name: "a",
444 srcs: ["a.txt"],
445 bazel_module: { bp2build_available: true },
446}
447EOF
448
449 INTEGRATED_BP2BUILD=1 run_soong
450 if [[ ! -e out/soong/bp2build/a/BUILD ]]; then
451 fail "a/BUILD not created";
452 fi
453
454 mkdir -p b
455 touch b/b.txt
456 cat > b/Android.bp <<'EOF'
457filegroup {
458 name: "b",
459 srcs: ["b.txt"],
460 bazel_module: { bp2build_available: true },
461}
462EOF
463
464 INTEGRATED_BP2BUILD=1 run_soong
465 if [[ ! -e out/soong/bp2build/b/BUILD ]]; then
466 fail "b/BUILD not created";
Lukacs T. Berkif8e24282021-04-14 10:31:00 +0200467 fi
468}
469
470function test_integrated_bp2build_null_build {
471 setup
Lukacs T. Berkid518e1a2021-04-14 13:49:50 +0200472
Lukacs T. Berkif8e24282021-04-14 10:31:00 +0200473 INTEGRATED_BP2BUILD=1 run_soong
474 local mtime1=$(stat -c "%y" out/soong/build.ninja)
475
476 INTEGRATED_BP2BUILD=1 run_soong
477 local mtime2=$(stat -c "%y" out/soong/build.ninja)
478
479 if [[ "$mtime1" != "$mtime2" ]]; then
480 fail "Output Ninja file changed on null build"
481 fi
482}
483
Lukacs T. Berkid518e1a2021-04-14 13:49:50 +0200484function test_integrated_bp2build_add_to_glob {
485 setup
486
487 mkdir -p a
488 touch a/a1.txt
489 cat > a/Android.bp <<'EOF'
490filegroup {
491 name: "a",
492 srcs: ["*.txt"],
493 bazel_module: { bp2build_available: true },
494}
495EOF
496
497 INTEGRATED_BP2BUILD=1 run_soong
498 grep -q a1.txt out/soong/bp2build/a/BUILD || fail "a1.txt not in BUILD file"
499
500 touch a/a2.txt
501 INTEGRATED_BP2BUILD=1 run_soong
502 grep -q a2.txt out/soong/bp2build/a/BUILD || fail "a2.txt not in BUILD file"
503}
504
Lukacs T. Berki97bb9f12021-04-01 18:28:45 +0200505function test_dump_json_module_graph() {
506 setup
507 SOONG_DUMP_JSON_MODULE_GRAPH="$MOCK_TOP/modules.json" run_soong
508 if [[ ! -r "$MOCK_TOP/modules.json" ]]; then
509 fail "JSON file was not created"
510 fi
511}
512
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100513test_smoke
514test_null_build
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100515test_null_build_after_docs
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100516test_soong_build_rebuilt_if_blueprint_changes
517test_add_file_to_glob
518test_add_android_bp
519test_change_android_bp
520test_delete_android_bp
521test_add_file_to_soong_build
Colin Crossc02504e2021-04-08 10:34:16 -0700522test_glob_during_bootstrapping
Lukacs T. Berkif0b3b942021-03-23 11:46:47 +0100523test_soong_build_rerun_iff_environment_changes
Lukacs T. Berki97bb9f12021-04-01 18:28:45 +0200524test_dump_json_module_graph
Lukacs T. Berkif8e24282021-04-14 10:31:00 +0200525test_integrated_bp2build_smoke
526test_integrated_bp2build_null_build
Lukacs T. Berkid518e1a2021-04-14 13:49:50 +0200527test_integrated_bp2build_add_to_glob