Organize Soong's integration tests:
- Move them into a new directory
- Split tests by theme and add a library file
- Add a shell script that runs them all
Test: Manually ran build/soong/run_integration_tests.sh .
Change-Id: I758b91d679f41aee47d15472cc02547ce89f6386
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
new file mode 100755
index 0000000..b2f7b2b
--- /dev/null
+++ b/tests/bootstrap_test.sh
@@ -0,0 +1,330 @@
+#!/bin/bash -eu
+
+# This test exercises the bootstrapping process of the build system
+# in a source tree that only contains enough files for Bazel and Soong to work.
+
+source "$(dirname "$0")/lib.sh"
+
+function test_smoke {
+ setup
+ run_soong
+}
+
+function test_null_build() {
+ setup
+ run_soong
+ local bootstrap_mtime1=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
+ local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ run_soong
+ local bootstrap_mtime2=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
+ local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+
+ if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then
+ # Bootstrapping is always done. It doesn't take a measurable amount of time.
+ fail "Bootstrap Ninja file did not change on null build"
+ fi
+
+ if [[ "$output_mtime1" != "$output_mtime2" ]]; then
+ fail "Output Ninja file changed on null build"
+ fi
+}
+
+function test_soong_build_rebuilt_if_blueprint_changes() {
+ setup
+ run_soong
+ local mtime1=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
+
+ sed -i 's/pluginGenSrcCmd/pluginGenSrcCmd2/g' build/blueprint/bootstrap/bootstrap.go
+
+ run_soong
+ local mtime2=$(stat -c "%y" out/soong/.bootstrap/build.ninja)
+
+ if [[ "$mtime1" == "$mtime2" ]]; then
+ fail "Bootstrap Ninja file did not change"
+ fi
+}
+
+function test_change_android_bp() {
+ setup
+ mkdir -p a
+ cat > a/Android.bp <<'EOF'
+python_binary_host {
+ name: "my_little_binary_host",
+ srcs: ["my_little_binary_host.py"]
+}
+EOF
+ touch a/my_little_binary_host.py
+ run_soong
+
+ grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja || fail "module not found"
+
+ cat > a/Android.bp <<'EOF'
+python_binary_host {
+ name: "my_great_binary_host",
+ srcs: ["my_great_binary_host.py"]
+}
+EOF
+ touch a/my_great_binary_host.py
+ run_soong
+
+ grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja && fail "old module found"
+ grep -q "^# Module:.*my_great_binary_host" out/soong/build.ninja || fail "new module not found"
+}
+
+
+function test_add_android_bp() {
+ setup
+ run_soong
+ local mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+ mkdir -p a
+ cat > a/Android.bp <<'EOF'
+python_binary_host {
+ name: "my_little_binary_host",
+ srcs: ["my_little_binary_host.py"]
+}
+EOF
+ touch a/my_little_binary_host.py
+ run_soong
+
+ local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ if [[ "$mtime1" == "$mtime2" ]]; then
+ fail "Output Ninja file did not change"
+ fi
+
+ grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "New module not in output"
+
+ run_soong
+}
+
+function test_delete_android_bp() {
+ setup
+ mkdir -p a
+ cat > a/Android.bp <<'EOF'
+python_binary_host {
+ name: "my_little_binary_host",
+ srcs: ["my_little_binary_host.py"]
+}
+EOF
+ touch a/my_little_binary_host.py
+ run_soong
+
+ grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "Module not in output"
+
+ rm a/Android.bp
+ run_soong
+
+ grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja && fail "Old module in output"
+}
+
+function test_add_file_to_glob() {
+ setup
+
+ mkdir -p a
+ cat > a/Android.bp <<'EOF'
+python_binary_host {
+ name: "my_little_binary_host",
+ srcs: ["*.py"],
+}
+EOF
+ touch a/my_little_binary_host.py
+ run_soong
+ local mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+ touch a/my_little_library.py
+ run_soong
+
+ local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ if [[ "$mtime1" == "$mtime2" ]]; then
+ fail "Output Ninja file did not change"
+ fi
+
+ grep -q my_little_library.py out/soong/build.ninja || fail "new file is not in output"
+}
+
+function test_soong_build_rerun_iff_environment_changes() {
+ setup
+
+ mkdir -p cherry
+ cat > cherry/Android.bp <<'EOF'
+bootstrap_go_package {
+ name: "cherry",
+ pkgPath: "android/soong/cherry",
+ deps: [
+ "blueprint",
+ "soong",
+ "soong-android",
+ ],
+ srcs: [
+ "cherry.go",
+ ],
+ pluginFor: ["soong_build"],
+}
+EOF
+
+ cat > cherry/cherry.go <<'EOF'
+package cherry
+
+import (
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+var (
+ pctx = android.NewPackageContext("cherry")
+)
+
+func init() {
+ android.RegisterSingletonType("cherry", CherrySingleton)
+}
+
+func CherrySingleton() android.Singleton {
+ return &cherrySingleton{}
+}
+
+type cherrySingleton struct{}
+
+func (p *cherrySingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ cherryRule := ctx.Rule(pctx, "cherry",
+ blueprint.RuleParams{
+ Command: "echo CHERRY IS " + ctx.Config().Getenv("CHERRY") + " > ${out}",
+ CommandDeps: []string{},
+ Description: "Cherry",
+ })
+
+ outputFile := android.PathForOutput(ctx, "cherry", "cherry.txt")
+ var deps android.Paths
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: cherryRule,
+ Output: outputFile,
+ Inputs: deps,
+ })
+}
+EOF
+
+ export CHERRY=TASTY
+ run_soong
+ grep -q "CHERRY IS TASTY" out/soong/build.ninja \
+ || fail "first value of environment variable is not used"
+
+ export CHERRY=RED
+ run_soong
+ grep -q "CHERRY IS RED" out/soong/build.ninja \
+ || fail "second value of environment variable not used"
+ local mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+ run_soong
+ local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ if [[ "$mtime1" != "$mtime2" ]]; then
+ fail "Output Ninja file changed when environment variable did not"
+ fi
+
+}
+
+function test_add_file_to_soong_build() {
+ setup
+ run_soong
+ local mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+ mkdir -p a
+ cat > a/Android.bp <<'EOF'
+bootstrap_go_package {
+ name: "picard-soong-rules",
+ pkgPath: "android/soong/picard",
+ deps: [
+ "blueprint",
+ "soong",
+ "soong-android",
+ ],
+ srcs: [
+ "picard.go",
+ ],
+ pluginFor: ["soong_build"],
+}
+EOF
+
+ cat > a/picard.go <<'EOF'
+package picard
+
+import (
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+var (
+ pctx = android.NewPackageContext("picard")
+)
+
+func init() {
+ android.RegisterSingletonType("picard", PicardSingleton)
+}
+
+func PicardSingleton() android.Singleton {
+ return &picardSingleton{}
+}
+
+type picardSingleton struct{}
+
+func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ picardRule := ctx.Rule(pctx, "picard",
+ blueprint.RuleParams{
+ Command: "echo Make it so. > ${out}",
+ CommandDeps: []string{},
+ Description: "Something quotable",
+ })
+
+ outputFile := android.PathForOutput(ctx, "picard", "picard.txt")
+ var deps android.Paths
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: picardRule,
+ Output: outputFile,
+ Inputs: deps,
+ })
+}
+
+EOF
+
+ run_soong
+ local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ if [[ "$mtime1" == "$mtime2" ]]; then
+ fail "Output Ninja file did not change"
+ fi
+
+ grep -q "Make it so" out/soong/build.ninja || fail "New action not present"
+}
+
+function test_null_build_after_docs {
+ setup
+ run_soong
+ local mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+ prebuilts/build-tools/linux-x86/bin/ninja -f out/soong/build.ninja soong_docs
+ run_soong
+ local mtime2=$(stat -c "%y" out/soong/build.ninja)
+
+ if [[ "$mtime1" != "$mtime2" ]]; then
+ fail "Output Ninja file changed on null build"
+ fi
+}
+
+function test_dump_json_module_graph() {
+ setup
+ SOONG_DUMP_JSON_MODULE_GRAPH="$MOCK_TOP/modules.json" run_soong
+ if [[ ! -r "$MOCK_TOP/modules.json" ]]; then
+ fail "JSON file was not created"
+ fi
+}
+
+test_smoke
+test_null_build
+test_null_build_after_docs
+test_soong_build_rebuilt_if_blueprint_changes
+test_add_file_to_glob
+test_add_android_bp
+test_change_android_bp
+test_delete_android_bp
+test_add_file_to_soong_build
+test_soong_build_rerun_iff_environment_changes
+test_dump_json_module_graph