xref: /aosp_15_r20/build/soong/tests/build_action_caching_test.sh (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1#!/bin/bash -u
2
3set -o pipefail
4
5# Test that the mk and ninja files generated by Soong don't change if some
6# incremental modules are restored from cache.
7
8OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
9
10echo ${OUTPUT_DIR}
11
12function cleanup {
13  rm -rf "${OUTPUT_DIR}"
14}
15trap cleanup EXIT
16
17function run_soong_build {
18  USE_RBE=false TARGET_PRODUCT=aosp_arm TARGET_RELEASE=trunk_staging TARGET_BUILD_VARIANT=userdebug build/soong/soong_ui.bash --make-mode "$@" nothing
19}
20
21function run_soong_clean {
22  build/soong/soong_ui.bash --make-mode clean
23}
24
25function assert_files_equal {
26  if [ $# -ne 2 ]; then
27    echo "Usage: assert_files_equal file1 file2"
28    exit 1
29  fi
30
31  if ! cmp -s "$1" "$2"; then
32    echo "Files are different: $1 $2"
33    exit 1
34  fi
35}
36
37function compare_mtimes() {
38  if [ $# -ne 2 ]; then
39    echo "Usage: compare_mtimes file1 file2"
40    exit 1
41  fi
42
43  file1_mtime=$(stat -c '%Y' $1)
44  file2_mtime=$(stat -c '%Y' $2)
45
46  if [ "$file1_mtime" -eq "$file2_mtime" ]; then
47      return 1
48  else
49      return 0
50  fi
51}
52
53function test_build_action_restoring() {
54  local test_dir="${OUTPUT_DIR}/test_build_action_restoring"
55  mkdir -p ${test_dir}
56  run_soong_clean
57  cat > ${test_dir}/Android.bp <<'EOF'
58python_binary_host {
59  name: "my_little_binary_host",
60  srcs: ["my_little_binary_host.py"],
61}
62EOF
63  touch ${test_dir}/my_little_binary_host.py
64  run_soong_build --incremental-build-actions
65  local dir_before="${test_dir}/before"
66  mkdir -p ${dir_before}
67  cp -pr out/soong/build_aosp_arm_ninja_incremental out/soong/*.mk out/soong/build.aosp_arm*.ninja ${test_dir}/before
68  # add a comment to the bp file, this should force a new analysis but no module
69  # should be really impacted, so all the incremental modules should be skipped.
70  cat >> ${test_dir}/Android.bp <<'EOF'
71// new comments
72EOF
73  run_soong_build --incremental-build-actions
74  local dir_after="${test_dir}/after"
75  mkdir -p ${dir_after}
76  cp -pr out/soong/build_aosp_arm_ninja_incremental out/soong/*.mk out/soong/build.aosp_arm*.ninja ${test_dir}/after
77
78  compare_incremental_files $dir_before $dir_after
79  rm -rf "$test_dir"
80  echo "test_build_action_restoring test passed"
81}
82
83function test_incremental_build_parity() {
84  local test_dir="${OUTPUT_DIR}/test_incremental_build_parity"
85  run_soong_clean
86  run_soong_build
87  local dir_before="${test_dir}/before"
88  mkdir -p ${dir_before}
89  cp -pr out/soong/*.mk out/soong/build.aosp_arm*.ninja ${test_dir}/before
90
91  # Now run clean build with incremental enabled
92  run_soong_clean
93  run_soong_build --incremental-build-actions
94  local dir_after="${test_dir}/after"
95  mkdir -p ${dir_after}
96  cp -pr out/soong/build_aosp_arm_ninja_incremental out/soong/*.mk out/soong/build.aosp_arm*.ninja ${test_dir}/after
97
98  compare_files_parity $dir_before $dir_after
99  rm -rf "$test_dir"
100  echo "test_incremental_build_parity test passed"
101}
102
103function compare_files_parity() {
104  local dir_before=$1; shift
105  local dir_after=$1; shift
106  count=0
107  for file_before in ${dir_before}/*.mk; do
108    file_after="${dir_after}/$(basename "$file_before")"
109    assert_files_equal $file_before $file_after
110    ((count++))
111  done
112  echo "Compared $count mk files"
113
114  combined_before_file="${dir_before}/combined_files.ninja"
115  count=0
116  for file in ${dir_before}/build.aosp_arm.*.ninja; do
117    cat $file >> $combined_before_file
118    ((count++))
119  done
120  echo "Combined $count ninja files from normal build"
121
122  combined_after_file="${dir_after}/combined_files.ninja"
123  count=0
124  for file in ${dir_after}/build.aosp_arm.*.ninja; do
125    cat $file >> $combined_after_file
126    ((count++))
127  done
128  echo "Combined $count ninja files from incremental build"
129
130  combined_incremental_ninjas="${dir_after}/combined_incremental_files.ninja"
131  count=0
132  for file in ${dir_after}/build_aosp_arm_ninja_incremental/*.ninja; do
133    cat $file >> $combined_incremental_ninjas
134    ((count++))
135  done
136  echo "Combined $count incremental ninja files"
137
138  cat $combined_incremental_ninjas >> $combined_after_file
139  sort $combined_after_file -o $combined_after_file
140  sort $combined_before_file -o $combined_before_file
141  assert_files_equal $combined_before_file $combined_after_file
142}
143
144function compare_incremental_files() {
145  local dir_before=$1; shift
146  local dir_after=$1; shift
147  count=0
148  for file_before in ${dir_before}/*.ninja; do
149    file_after="${dir_after}/$(basename "$file_before")"
150    assert_files_equal $file_before $file_after
151    compare_mtimes $file_before $file_after
152    if [ $? -ne 0 ]; then
153      echo "Files have identical mtime: $file_before $file_after"
154      exit 1
155    fi
156    ((count++))
157  done
158  echo "Compared $count ninja files"
159
160  count=0
161  for file_before in ${dir_before}/*.mk; do
162    file_after="${dir_after}/$(basename "$file_before")"
163    assert_files_equal $file_before $file_after
164    compare_mtimes $file_before $file_after
165    # mk files shouldn't be regenerated
166    if [ $? -ne 1 ]; then
167      echo "Files have different mtimes: $file_before $file_after"
168      exit 1
169    fi
170    ((count++))
171  done
172  echo "Compared $count mk files"
173
174  count=0
175  for file_before in ${dir_before}/build_aosp_arm_ninja_incremental/*.ninja; do
176    file_after="${dir_after}/build_aosp_arm_ninja_incremental/$(basename "$file_before")"
177    assert_files_equal $file_before $file_after
178    compare_mtimes $file_before $file_after
179    # ninja files of skipped modules shouldn't be regenerated
180    if [ $? -ne 1 ]; then
181      echo "Files have different mtimes: $file_before $file_after"
182      exit 1
183    fi
184    ((count++))
185  done
186  echo "Compared $count incremental ninja files"
187}
188
189test_incremental_build_parity
190test_build_action_restoring
191