• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash -eu
2
3set -o pipefail
4
5# Test that bp2build and Bazel can play nicely together
6
7source "$(dirname "$0")/lib.sh"
8
9readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
10
11function test_bp2build_null_build {
12  setup
13  run_soong bp2build
14  local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
15
16  run_soong bp2build
17  local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
18
19  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
20    fail "Output bp2build marker file changed on null build"
21  fi
22}
23
24# Tests that, if bp2build reruns due to a blueprint file changing, that
25# BUILD files whose contents are unchanged are not regenerated.
26function test_bp2build_unchanged {
27  setup
28
29  mkdir -p pkg
30  touch pkg/x.txt
31  cat > pkg/Android.bp <<'EOF'
32filegroup {
33    name: "x",
34    srcs: ["x.txt"],
35    bazel_module: {bp2build_available: true},
36  }
37EOF
38
39  run_soong bp2build
40  local -r buildfile_mtime1=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
41  local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
42
43  # Force bp2build to rerun by updating the timestamp of a blueprint file.
44  touch pkg/Android.bp
45
46  run_soong bp2build
47  local -r buildfile_mtime2=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
48  local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
49
50  if [[ "$marker_mtime1" == "$marker_mtime2" ]]; then
51    fail "Expected bp2build marker file to change"
52  fi
53  if [[ "$buildfile_mtime1" != "$buildfile_mtime2" ]]; then
54    fail "BUILD.bazel was updated even though contents are same"
55  fi
56}
57
58# Tests that blueprint files that are deleted are not present when the
59# bp2build tree is regenerated.
60function test_bp2build_deleted_blueprint {
61  setup
62
63  mkdir -p pkg
64  touch pkg/x.txt
65  cat > pkg/Android.bp <<'EOF'
66filegroup {
67    name: "x",
68    srcs: ["x.txt"],
69    bazel_module: {bp2build_available: true},
70  }
71EOF
72
73  run_soong bp2build
74  if [[ ! -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
75    fail "Expected pkg/BUILD.bazel to be generated"
76  fi
77
78  rm pkg/Android.bp
79
80  run_soong bp2build
81  if [[ -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
82    fail "Expected pkg/BUILD.bazel to be deleted"
83  fi
84}
85
86function test_bp2build_null_build_with_globs {
87  setup
88
89  mkdir -p foo/bar
90  cat > foo/bar/Android.bp <<'EOF'
91filegroup {
92    name: "globs",
93    srcs: ["*.txt"],
94  }
95EOF
96  touch foo/bar/a.txt foo/bar/b.txt
97
98  run_soong bp2build
99  local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
100
101  run_soong bp2build
102  local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
103
104  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
105    fail "Output bp2build marker file changed on null build"
106  fi
107}
108
109function test_different_relative_outdir {
110  setup
111
112  mkdir -p a
113  touch a/g.txt
114  cat > a/Android.bp <<'EOF'
115filegroup {
116    name: "g",
117    srcs: ["g.txt"],
118    bazel_module: {bp2build_available: true},
119  }
120EOF
121
122  # A directory under $MOCK_TOP
123  outdir=out2
124  trap "rm -rf $outdir" EXIT
125  # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
126  (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
127}
128
129function test_different_absolute_outdir {
130  setup
131
132  mkdir -p a
133  touch a/g.txt
134  cat > a/Android.bp <<'EOF'
135filegroup {
136    name: "g",
137    srcs: ["g.txt"],
138    bazel_module: {bp2build_available: true},
139  }
140EOF
141
142  # A directory under /tmp/...
143  outdir=$(mktemp -t -d st.XXXXX)
144  trap 'rm -rf $outdir' EXIT
145  # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
146  (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
147}
148
149function _bp2build_generates_all_buildfiles {
150  setup
151
152  mkdir -p foo/convertible_soong_module
153  cat > foo/convertible_soong_module/Android.bp <<'EOF'
154genrule {
155    name: "the_answer",
156    cmd: "echo '42' > $(out)",
157    out: [
158        "the_answer.txt",
159    ],
160    bazel_module: {
161        bp2build_available: true,
162    },
163  }
164EOF
165
166  mkdir -p foo/unconvertible_soong_module
167  cat > foo/unconvertible_soong_module/Android.bp <<'EOF'
168genrule {
169    name: "not_the_answer",
170    cmd: "echo '43' > $(out)",
171    out: [
172        "not_the_answer.txt",
173    ],
174    bazel_module: {
175        bp2build_available: false,
176    },
177  }
178EOF
179
180  run_soong bp2build
181
182  if [[ ! -f "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
183    fail "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
184  fi
185
186  if [[ ! -f "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
187    fail "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
188  fi
189
190  if ! grep "the_answer" "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
191    fail "missing BUILD target the_answer in convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
192  fi
193
194  if grep "not_the_answer" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
195    fail "found unexpected BUILD target not_the_answer in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
196  fi
197
198  if ! grep "filegroup" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
199    fail "missing filegroup in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
200  fi
201
202  # NOTE: We don't actually use the extra BUILD file for anything here
203  run_bazel build --config=android --config=bp2build --config=ci //foo/...
204
205  local -r the_answer_file="$(find -L bazel-out -name the_answer.txt)"
206  if [[ ! -f "${the_answer_file}" ]]; then
207    fail "Expected the_answer.txt to be generated, but was missing"
208  fi
209  if ! grep 42 "${the_answer_file}"; then
210    fail "Expected to find 42 in '${the_answer_file}'"
211  fi
212}
213
214function test_bp2build_generates_all_buildfiles {
215  _save_trap=$(trap -p EXIT)
216  trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
217  _bp2build_generates_all_buildfiles
218  eval "${_save_trap}"
219}
220
221function test_bp2build_symlinks_files {
222  setup
223  mkdir -p foo
224  touch foo/BLANK1
225  touch foo/BLANK2
226  touch foo/F2D
227  touch foo/BUILD
228
229  run_soong bp2build
230
231  if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
232    fail "./out/soong/workspace/foo/BUILD should be omitted"
233  fi
234  for file in BLANK1 BLANK2 F2D
235  do
236    if [[ ! -L "./out/soong/workspace/foo/$file" ]]; then
237      fail "./out/soong/workspace/foo/$file should exist"
238    fi
239  done
240  local -r BLANK1_BEFORE=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
241
242  rm foo/BLANK2
243  rm foo/F2D
244  mkdir foo/F2D
245  touch foo/F2D/BUILD
246
247  run_soong bp2build
248
249  if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
250    fail "./out/soong/workspace/foo/BUILD should be omitted"
251  fi
252  local -r BLANK1_AFTER=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
253  if [[ "$BLANK1_AFTER" != "$BLANK1_BEFORE" ]]; then
254    fail "./out/soong/workspace/foo/BLANK1 should be untouched"
255  fi
256  if [[  -e "./out/soong/workspace/foo/BLANK2" ]]; then
257    fail "./out/soong/workspace/foo/BLANK2 should be removed"
258  fi
259  if [[ -L "./out/soong/workspace/foo/F2D" ]] || [[ ! -d "./out/soong/workspace/foo/F2D" ]]; then
260    fail "./out/soong/workspace/foo/F2D should be a dir"
261  fi
262}
263
264function test_cc_correctness {
265  setup
266
267  mkdir -p a
268  cat > a/Android.bp <<EOF
269cc_object {
270  name: "qq",
271  srcs: ["qq.cc"],
272  bazel_module: {
273    bp2build_available: true,
274  },
275  stl: "none",
276  system_shared_libs: [],
277}
278EOF
279
280  cat > a/qq.cc <<EOF
281#include "qq.h"
282int qq() {
283  return QQ;
284}
285EOF
286
287  cat > a/qq.h <<EOF
288#define QQ 1
289EOF
290
291  run_soong bp2build
292
293  run_bazel build --config=android --config=bp2build --config=ci //a:qq
294  local -r output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
295
296  run_bazel build --config=android --config=bp2build --config=ci //a:qq
297  local -r output_mtime2=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
298
299  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
300    fail "output changed on null build"
301  fi
302
303  cat > a/qq.h <<EOF
304#define QQ 2
305EOF
306
307  run_bazel build --config=android --config=bp2build --config=ci //a:qq
308  local -r output_mtime3=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
309
310  if [[ "$output_mtime1" == "$output_mtime3" ]]; then
311    fail "output not changed when included header changed"
312  fi
313}
314
315# Regression test for the following failure during symlink forest creation:
316#
317#   Cannot stat '/tmp/st.rr054/foo/bar/unresolved_symlink': stat /tmp/st.rr054/foo/bar/unresolved_symlink: no such file or directory
318#
319function test_bp2build_null_build_with_unresolved_symlink_in_source() {
320  setup
321
322  mkdir -p foo/bar
323  ln -s /tmp/non-existent foo/bar/unresolved_symlink
324  cat > foo/bar/Android.bp <<'EOF'
325filegroup {
326    name: "fg",
327    srcs: ["unresolved_symlink/non-existent-file.txt"],
328  }
329EOF
330
331  run_soong bp2build
332
333  dest=$(readlink -f out/soong/workspace/foo/bar/unresolved_symlink)
334  if [[ "$dest" != "/tmp/non-existent" ]]; then
335    fail "expected to plant an unresolved symlink out/soong/workspace/foo/bar/unresolved_symlink that resolves to /tmp/non-existent"
336  fi
337}
338
339# Smoke test to verify api_bp2build worksapce does not contain any errors
340function test_api_bp2build_empty_build() {
341  setup
342  run_soong api_bp2build
343  run_bazel build --config=android --config=api_bp2build //:empty
344}
345
346# Verify that an *_api_contribution target can refer to an api file from
347# another Bazel package.
348function test_api_export_from_another_bazel_package() {
349  setup
350  # Parent dir Android.bp
351  mkdir -p foo
352  cat > foo/Android.bp << 'EOF'
353cc_library {
354  name: "libfoo",
355  stubs: {
356    symbol_file: "api/libfoo.map.txt",
357  },
358}
359EOF
360  # Child dir Android.bp
361  mkdir -p foo/api
362  cat > foo/api/Android.bp << 'EOF'
363package{}
364EOF
365  touch foo/api/libfoo.map.txt
366  # Run test
367  run_soong api_bp2build
368  run_bazel build --config=android --config=api_bp2build //foo:libfoo.contribution
369}
370
371scan_and_run_tests
372