kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

run.sh (70255B)


      1 #!/bin/sh
      2 # Driver-level checks for the content-addressed build coordinator.
      3 
      4 set -u
      5 
      6 script_dir=$(cd "$(dirname "$0")" && pwd)
      7 repo_root=$(cd "$script_dir/../.." && pwd)
      8 
      9 KIT="${KIT:-$repo_root/build/kit}"
     10 
     11 if [ ! -x "$KIT" ]; then
     12     echo "buildcoord: kit binary not found at $KIT" >&2
     13     exit 2
     14 fi
     15 
     16 work=$(mktemp -d "${TMPDIR:-/tmp}/kit-buildcoord-test.XXXXXX")
     17 trap 'rm -rf "$work"' EXIT
     18 
     19 KIT_KIT_DIR="$repo_root/test/lib"
     20 . "$repo_root/test/lib/kit_sh_kit.sh"
     21 kit_report_init
     22 
     23 ws="$work/ws"
     24 store="$work/store"
     25 mkdir -p "$ws/recipes" "$ws/remote" "$ws/src/depfile" "$ws/src/globset" \
     26     "$ws/src/list/sub" "$ws/src/tree/nested/deeper" "$store"
     27 
     28 make_pkg() {
     29     pkg=$1
     30     shift
     31     mkdir -p "$ws/$pkg"
     32     {
     33         printf 'kit-build 1\n'
     34         while [ "$#" -gt 0 ]; do
     35             printf '[target %s]\nrecipe //recipes/%s\n' "$1" "$2"
     36             shift 2
     37         done
     38     } > "$ws/$pkg/BUILD.kit"
     39 }
     40 
     41 make_pkg absent probe absent.sh
     42 make_pkg app bundle app.sh
     43 make_pkg argv argv argv.sh echo argv.sh
     44 make_pkg async dep async_dep.sh unawaited async_unawaited.sh
     45 make_pkg cfg default cfg_default.sh probe cfg.sh
     46 make_pkg client formats client_formats.sh
     47 make_pkg cycle a cycle_a.sh b cycle_b.sh self cycle_self.sh
     48 make_pkg defn probe defn_v1.sh unused defn_unused_v1.sh
     49 make_pkg depfile lines depfile_lines.sh probe depfile.sh
     50 make_pkg env probe env_probe.sh
     51 make_pkg exports consumer exports_consumer.sh other exports_other.sh \
     52     provider exports_provider.sh
     53 make_pkg extuser probe extuser.sh
     54 make_pkg fail probe fail.sh
     55 make_pkg fetch blob fetch.sh format fetch_format.sh
     56 make_pkg globset probe globset.sh
     57 make_pkg globstar probe globstar.sh
     58 make_pkg lib data lib.sh
     59 make_pkg material probe material.sh
     60 make_pkg needargv dep argv.sh probe needargv.sh
     61 make_pkg nondet counter nondet.sh
     62 make_pkg recipe stamp recipe.sh
     63 make_pkg repeat probe repeat.sh
     64 make_pkg scope leaf scope_leaf.sh parent-inherit scope_parent_inherit.sh \
     65     parent-override scope_parent_override.sh plain scope_plain.sh
     66 make_pkg shadow leaf shadow_leaf.sh parent shadow_parent.sh
     67 make_pkg stable dep stable_dep.sh parent stable_parent.sh
     68 make_pkg storage probe material.sh
     69 make_pkg submit echo argv.sh probe submit.sh
     70 make_pkg test fail test_fail.sh nondet test_nondet.sh parent test_parent.sh \
     71     pass test_pass.sh separate test_pass.sh
     72 make_pkg wscfg probe wscfg.sh
     73 
     74 mkdir -p "$ws/redo/do"
     75 cat > "$ws/redo/BUILD.kit" <<'EOF'
     76 kit-build 2
     77 
     78 [redo-defaults]
     79 enabled true
     80 search . do
     81 walk-parents true
     82 EOF
     83 
     84 mkdir -p "$ws/listpkg" "$ws/listpkg/subpkg"
     85 cat > "$ws/listpkg/BUILD.kit" <<'EOF'
     86 kit-build 2
     87 
     88 [target exact]
     89 recipe //recipes/argv.sh
     90 
     91 [targets c.object]
     92 list ../src/list/*.c -> {stem}.o
     93 
     94 [rule object]
     95 match *.o
     96 type c.object
     97 
     98 [default c.object]
     99 recipe //recipes/argv.sh
    100 
    101 [redo-defaults]
    102 enabled true
    103 search . do
    104 walk-parents true
    105 EOF
    106 
    107 cat > "$ws/listpkg/subpkg/BUILD.kit" <<'EOF'
    108 kit-build 1
    109 [target child]
    110 recipe //recipes/argv.sh
    111 EOF
    112 
    113 cat > "$ws/BUILD.kit" <<'EOF'
    114 kit-build 2
    115 
    116 [target root]
    117 recipe //recipes/argv.sh
    118 
    119 [redo-defaults]
    120 enabled true
    121 search . do
    122 walk-parents true
    123 EOF
    124 
    125 cat > "$ws/src/a.txt" <<'EOF'
    126 alpha
    127 EOF
    128 cat > "$ws/src/b.txt" <<'EOF'
    129 beta
    130 EOF
    131 cat > "$ws/src/noop.txt" <<'EOF'
    132 first
    133 EOF
    134 cat > "$ws/src/scope-noop.txt" <<'EOF'
    135 first
    136 EOF
    137 cat > "$ws/src/depfile/a.h" <<'EOF'
    138 dep-a:v1
    139 EOF
    140 cat > "$ws/src/depfile/b.h" <<'EOF'
    141 dep-b:v1
    142 EOF
    143 cat > "$ws/src/globset/one.txt" <<'EOF'
    144 one
    145 EOF
    146 cat > "$ws/src/list/foo.c" <<'EOF'
    147 int foo;
    148 EOF
    149 cat > "$ws/src/list/sub/bar.c" <<'EOF'
    150 int bar;
    151 EOF
    152 cat > "$ws/src/tree/root.txt" <<'EOF'
    153 root
    154 EOF
    155 cat > "$ws/src/tree/nested/mid.txt" <<'EOF'
    156 mid
    157 EOF
    158 cat > "$ws/src/tree/nested/deeper/leaf.txt" <<'EOF'
    159 leaf
    160 EOF
    161 cat > "$ws/remote/fetch.txt" <<'EOF'
    162 remote:v1
    163 EOF
    164 
    165 cat > "$ws/recipes/lib.sh" <<'EOF'
    166 #!/bin/sh
    167 set -eu
    168 mode=$("$KIT" build config-get mode || true)
    169 mkdir -p "$KIT_BUILD_OUT"
    170 printf 'lib:%s\n' "$mode" > "$KIT_BUILD_OUT/lib.txt"
    171 EOF
    172 
    173 cat > "$ws/recipes/app.sh" <<'EOF'
    174 #!/bin/sh
    175 set -eu
    176 mkdir -p "$KIT_BUILD_OUT"
    177 : "${KIT_BUILD_TARGET:?missing target}"
    178 lib_dir=$("$KIT" build need --config mode=debug //lib:data)
    179 for p in $("$KIT" build glob 'src/*.txt'); do
    180     cat "$("$KIT" build source "$p")"
    181 done > "$KIT_BUILD_OUT/sources.txt"
    182 cat "$lib_dir/lib.txt" > "$KIT_BUILD_OUT/lib.txt"
    183 printf '%s\n' "$KIT_BUILD_TARGET" > "$KIT_BUILD_OUT/target.txt"
    184 printf '%s\n' "$KIT_BUILD_PACKAGE" > "$KIT_BUILD_OUT/package.txt"
    185 EOF
    186 
    187 cat > "$ws/recipes/extuser.sh" <<'EOF'
    188 #!/bin/sh
    189 set -eu
    190 dep=$("$KIT" build need @ext//:data)
    191 mkdir -p "$KIT_BUILD_OUT"
    192 cat "$dep/external.txt" > "$KIT_BUILD_OUT/via-external.txt"
    193 EOF
    194 
    195 cat > "$ws/recipes/wscfg.sh" <<'EOF'
    196 #!/bin/sh
    197 set -eu
    198 mode=$("$KIT" build config-get workspace-mode || true)
    199 mkdir -p "$KIT_BUILD_OUT"
    200 printf 'workspace:%s\n' "$mode" > "$KIT_BUILD_OUT/workspace.txt"
    201 EOF
    202 
    203 cat > "$ws/recipes/absent.sh" <<'EOF'
    204 #!/bin/sh
    205 set -eu
    206 mkdir -p "$KIT_BUILD_OUT"
    207 if p=$("$KIT" build source src/optional.txt 2>/dev/null); then
    208     cat "$p" > "$KIT_BUILD_OUT/optional.txt"
    209 else
    210     printf 'absent\n' > "$KIT_BUILD_OUT/optional.txt"
    211 fi
    212 EOF
    213 
    214 cat > "$ws/recipes/argv.sh" <<'EOF'
    215 #!/bin/sh
    216 set -eu
    217 mkdir -p "$KIT_BUILD_OUT"
    218 printf '%s\n' "$@" > "$KIT_BUILD_OUT/args.txt"
    219 EOF
    220 
    221 cat > "$ws/recipes/async_dep.sh" <<'EOF'
    222 #!/bin/sh
    223 set -eu
    224 count=0
    225 if [ -f async-dep.count ]; then
    226     count=$(cat async-dep.count)
    227 fi
    228 count=$((count + 1))
    229 printf '%s\n' "$count" > async-dep.count
    230 mkdir -p "$KIT_BUILD_OUT"
    231 printf 'async-dep:%s\n' "$count" > "$KIT_BUILD_OUT/dep.txt"
    232 EOF
    233 
    234 cat > "$ws/recipes/async_unawaited.sh" <<'EOF'
    235 #!/bin/sh
    236 set -eu
    237 mkdir -p "$KIT_BUILD_OUT"
    238 "$KIT" build need-submit //async:dep >/dev/null
    239 printf 'unawaited\n' > "$KIT_BUILD_OUT/unawaited.txt"
    240 EOF
    241 
    242 cat > "$ws/recipes/cfg.sh" <<'EOF'
    243 #!/bin/sh
    244 set -eu
    245 mkdir -p "$KIT_BUILD_OUT"
    246 mode=$("$KIT" build config-get mode || true)
    247 printf 'mode:%s\n' "$mode" > "$KIT_BUILD_OUT/mode.txt"
    248 EOF
    249 
    250 cat > "$ws/recipes/cfg_default.sh" <<'EOF'
    251 #!/bin/sh
    252 set -eu
    253 mkdir -p "$KIT_BUILD_OUT"
    254 value=$("$KIT" build config-get --default fallback missing-default)
    255 printf 'default:%s\n' "$value" > "$KIT_BUILD_OUT/default.txt"
    256 EOF
    257 
    258 cat > "$ws/recipes/client_formats.sh" <<'EOF'
    259 #!/bin/sh
    260 set -eu
    261 "$KIT" build config-get --default fallback missing-key > "$KIT_BUILD_OUT/default.txt"
    262 "$KIT" build source --optional src/missing-optional.txt > "$KIT_BUILD_OUT/optional.txt"
    263 "$KIT" build source --format id-path src/a.txt > "$KIT_BUILD_OUT/source.txt"
    264 "$KIT" build need --format id-path //argv:echo -- format-arg \
    265     > "$KIT_BUILD_OUT/need.txt"
    266 tok=$("$KIT" build need-submit //argv:echo -- format-arg)
    267 "$KIT" build need-await --format id-path "$tok" > "$KIT_BUILD_OUT/await.txt"
    268 EOF
    269 
    270 cat > "$ws/recipes/cycle_a.sh" <<'EOF'
    271 #!/bin/sh
    272 set -eu
    273 mkdir -p "$KIT_BUILD_OUT"
    274 "$KIT" build need //cycle:b >/dev/null
    275 printf 'a\n' > "$KIT_BUILD_OUT/cycle.txt"
    276 EOF
    277 
    278 cat > "$ws/recipes/cycle_b.sh" <<'EOF'
    279 #!/bin/sh
    280 set -eu
    281 mkdir -p "$KIT_BUILD_OUT"
    282 "$KIT" build need //cycle:a >/dev/null
    283 printf 'b\n' > "$KIT_BUILD_OUT/cycle.txt"
    284 EOF
    285 
    286 cat > "$ws/recipes/cycle_self.sh" <<'EOF'
    287 #!/bin/sh
    288 set -eu
    289 mkdir -p "$KIT_BUILD_OUT"
    290 "$KIT" build need //cycle:self >/dev/null
    291 printf 'self\n' > "$KIT_BUILD_OUT/cycle.txt"
    292 EOF
    293 
    294 cat > "$ws/recipes/defn_v1.sh" <<'EOF'
    295 #!/bin/sh
    296 set -eu
    297 mkdir -p "$KIT_BUILD_OUT"
    298 printf 'defn:v1\n' > "$KIT_BUILD_OUT/defn.txt"
    299 EOF
    300 
    301 cat > "$ws/recipes/defn_same.sh" <<'EOF'
    302 #!/bin/sh
    303 set -eu
    304 mkdir -p "$KIT_BUILD_OUT"
    305 printf 'defn:v1\n' > "$KIT_BUILD_OUT/defn.txt"
    306 EOF
    307 
    308 cat > "$ws/recipes/defn_v2.sh" <<'EOF'
    309 #!/bin/sh
    310 set -eu
    311 mkdir -p "$KIT_BUILD_OUT"
    312 printf 'defn:v2\n' > "$KIT_BUILD_OUT/defn.txt"
    313 EOF
    314 
    315 cat > "$ws/recipes/defn_unused_v1.sh" <<'EOF'
    316 #!/bin/sh
    317 set -eu
    318 mkdir -p "$KIT_BUILD_OUT"
    319 printf 'unused:v1\n' > "$KIT_BUILD_OUT/unused.txt"
    320 EOF
    321 
    322 cat > "$ws/recipes/defn_unused_v2.sh" <<'EOF'
    323 #!/bin/sh
    324 set -eu
    325 mkdir -p "$KIT_BUILD_OUT"
    326 printf 'unused:v2\n' > "$KIT_BUILD_OUT/unused.txt"
    327 EOF
    328 
    329 cat > "$ws/recipes/depfile.sh" <<'EOF'
    330 #!/bin/sh
    331 set -eu
    332 mkdir -p "$KIT_BUILD_OUT"
    333 cat src/depfile/a.h src/depfile/b.h > "$KIT_BUILD_OUT/combined.txt"
    334 cat > "$KIT_BUILD_OUT/probe.d" <<'DEPFILE'
    335 obj/probe.o: src/depfile/a.h \
    336  src/depfile/b.h
    337 DEPFILE
    338 "$KIT" build depfile "$KIT_BUILD_OUT/probe.d"
    339 EOF
    340 
    341 cat > "$ws/recipes/depfile_lines.sh" <<'EOF'
    342 #!/bin/sh
    343 set -eu
    344 mkdir -p "$KIT_BUILD_OUT"
    345 cat src/depfile/a.h src/depfile/b.h > "$KIT_BUILD_OUT/combined.txt"
    346 cat > "$KIT_BUILD_OUT/probe.lines" <<'DEPFILE'
    347 src/depfile/a.h
    348 src/depfile/b.h
    349 DEPFILE
    350 "$KIT" build depfile --lines "$KIT_BUILD_OUT/probe.lines"
    351 EOF
    352 
    353 cat > "$ws/recipes/env_probe.sh" <<'EOF'
    354 #!/bin/sh
    355 set -eu
    356 mkdir -p "$KIT_BUILD_OUT"
    357 printf 'ambient:%s\n' "${AMBIENT-unset}" > "$KIT_BUILD_OUT/env.txt"
    358 printf 'declared:%s\n' "${DECLARED-unset}" >> "$KIT_BUILD_OUT/env.txt"
    359 printf 'repo:%s\n' "${KIT_BUILD_REPO-unset}" >> "$KIT_BUILD_OUT/env.txt"
    360 printf 'package:%s\n' "${KIT_BUILD_PACKAGE-unset}" >> "$KIT_BUILD_OUT/env.txt"
    361 printf 'local:%s\n' "${KIT_BUILD_LOCAL-unset}" >> "$KIT_BUILD_OUT/env.txt"
    362 EOF
    363 
    364 cat > "$ws/recipes/exports_provider.sh" <<'EOF'
    365 #!/bin/sh
    366 set -eu
    367 mkdir -p "$KIT_BUILD_OUT"
    368 "$KIT" build export-set cflags -- -Iinclude -DPROVIDER=1
    369 "$KIT" build export-set libs -- -Llib -lprovider
    370 printf 'provider\n' > "$KIT_BUILD_OUT/provider.txt"
    371 EOF
    372 
    373 cat > "$ws/recipes/exports_other.sh" <<'EOF'
    374 #!/bin/sh
    375 set -eu
    376 mkdir -p "$KIT_BUILD_OUT"
    377 "$KIT" build export-set cflags -- -Iother
    378 printf 'other\n' > "$KIT_BUILD_OUT/other.txt"
    379 EOF
    380 
    381 cat > "$ws/recipes/exports_consumer.sh" <<'EOF'
    382 #!/bin/sh
    383 set -eu
    384 mkdir -p "$KIT_BUILD_OUT"
    385 "$KIT" build export-get //exports:provider cflags > "$KIT_BUILD_OUT/cflags.txt"
    386 "$KIT" build export-get //exports:provider libs > "$KIT_BUILD_OUT/libs.txt"
    387 "$KIT" build export-collect cflags //exports:provider //exports:other \
    388     > "$KIT_BUILD_OUT/collect.txt"
    389 EOF
    390 
    391 cat > "$ws/recipes/fail.sh" <<'EOF'
    392 #!/bin/sh
    393 set -eu
    394 count=0
    395 if [ -f fail.count ]; then
    396     count=$(cat fail.count)
    397 fi
    398 count=$((count + 1))
    399 printf '%s\n' "$count" > fail.count
    400 exit 1
    401 EOF
    402 
    403 cat > "$ws/recipes/fetch.sh" <<'EOF'
    404 #!/bin/sh
    405 set -eu
    406 blob=$1
    407 shift
    408 p=$("$KIT" build fetch "$blob" "$@")
    409 IFS= read -r line < "$p"
    410 printf '%s\n' "$line" > "$KIT_BUILD_OUT/fetched.txt"
    411 EOF
    412 
    413 cat > "$ws/recipes/fetch_format.sh" <<'EOF'
    414 #!/bin/sh
    415 set -eu
    416 blob=$1
    417 shift
    418 info=$("$KIT" build fetch --format id-path "$blob" "$@")
    419 printf '%s\n' "$info" > "$KIT_BUILD_OUT/fetch-info.txt"
    420 path=${info#* }
    421 IFS= read -r line < "$path"
    422 printf '%s\n' "$line" > "$KIT_BUILD_OUT/fetched.txt"
    423 EOF
    424 
    425 cat > "$ws/recipes/globset.sh" <<'EOF'
    426 #!/bin/sh
    427 set -eu
    428 mkdir -p "$KIT_BUILD_OUT"
    429 for p in $("$KIT" build glob 'src/globset/*.txt'); do
    430     cat "$p"
    431 done > "$KIT_BUILD_OUT/files.txt"
    432 EOF
    433 
    434 cat > "$ws/recipes/globstar.sh" <<'EOF'
    435 #!/bin/sh
    436 set -eu
    437 mkdir -p "$KIT_BUILD_OUT"
    438 "$KIT" build glob 'src/tree/**/*.txt' > "$KIT_BUILD_OUT/all.txt"
    439 "$KIT" build glob 'src/tree/**/leaf.txt' > "$KIT_BUILD_OUT/leaf.txt"
    440 "$KIT" build glob 'src/tree/**/root.txt' > "$KIT_BUILD_OUT/root.txt"
    441 EOF
    442 
    443 cat > "$ws/recipes/needargv.sh" <<'EOF'
    444 #!/bin/sh
    445 set -eu
    446 mkdir -p "$KIT_BUILD_OUT"
    447 dep_dir=$("$KIT" build need :dep -- dep-one dep-two)
    448 cat "$dep_dir/args.txt" > "$KIT_BUILD_OUT/dep-args.txt"
    449 EOF
    450 
    451 cat > "$ws/recipes/recipe.sh" <<'EOF'
    452 #!/bin/sh
    453 set -eu
    454 mkdir -p "$KIT_BUILD_OUT"
    455 printf 'recipe:v1\n' > "$KIT_BUILD_OUT/stamp.txt"
    456 EOF
    457 
    458 cat > "$ws/recipes/repeat.sh" <<'EOF'
    459 #!/bin/sh
    460 set -eu
    461 mkdir -p "$KIT_BUILD_OUT"
    462 p1=$("$KIT" build source src/a.txt)
    463 p2=$("$KIT" build source src/a.txt)
    464 cat "$p1" > "$KIT_BUILD_OUT/source1.txt"
    465 cat "$p2" > "$KIT_BUILD_OUT/source2.txt"
    466 "$KIT" build glob 'src/*.txt' > "$KIT_BUILD_OUT/glob1.txt"
    467 "$KIT" build glob 'src/*.txt' > "$KIT_BUILD_OUT/glob2.txt"
    468 EOF
    469 
    470 cat > "$ws/recipes/material.sh" <<'EOF'
    471 #!/bin/sh
    472 set -eu
    473 mkdir -p "$KIT_BUILD_OUT"
    474 printf 'material\n' > "$KIT_BUILD_OUT/material.txt"
    475 EOF
    476 
    477 cat > "$ws/recipes/nondet.sh" <<'EOF'
    478 #!/bin/sh
    479 set -eu
    480 mkdir -p "$KIT_BUILD_OUT"
    481 count=0
    482 if [ -f .nondet-count ]; then
    483     count=$(cat .nondet-count)
    484 fi
    485 count=$((count + 1))
    486 printf '%s\n' "$count" > .nondet-count
    487 printf 'nondet:%s\n' "$count" > "$KIT_BUILD_OUT/nondet.txt"
    488 EOF
    489 
    490 cat > "$ws/recipes/scope_leaf.sh" <<'EOF'
    491 #!/bin/sh
    492 set -eu
    493 mkdir -p "$KIT_BUILD_OUT"
    494 "$KIT" build source src/scope-noop.txt >/dev/null
    495 mode=$("$KIT" build config-get mode || true)
    496 printf 'mode:%s\n' "$mode" > "$KIT_BUILD_OUT/mode.txt"
    497 EOF
    498 
    499 cat > "$ws/recipes/scope_parent_inherit.sh" <<'EOF'
    500 #!/bin/sh
    501 set -eu
    502 mkdir -p "$KIT_BUILD_OUT"
    503 dep_dir=$("$KIT" build need //scope:leaf)
    504 cat "$dep_dir/mode.txt" > "$KIT_BUILD_OUT/mode.txt"
    505 EOF
    506 
    507 cat > "$ws/recipes/scope_parent_override.sh" <<'EOF'
    508 #!/bin/sh
    509 set -eu
    510 mkdir -p "$KIT_BUILD_OUT"
    511 dep_dir=$("$KIT" build need --config mode=forced //scope:leaf)
    512 cat "$dep_dir/mode.txt" > "$KIT_BUILD_OUT/mode.txt"
    513 EOF
    514 
    515 cat > "$ws/recipes/scope_plain.sh" <<'EOF'
    516 #!/bin/sh
    517 set -eu
    518 mkdir -p "$KIT_BUILD_OUT"
    519 printf 'plain\n' > "$KIT_BUILD_OUT/plain.txt"
    520 EOF
    521 
    522 cat > "$ws/recipes/shadow_leaf.sh" <<'EOF'
    523 #!/bin/sh
    524 set -eu
    525 mkdir -p "$KIT_BUILD_OUT"
    526 mode=$("$KIT" build config-get mode || true)
    527 printf 'leaf:%s\n' "$mode" > "$KIT_BUILD_OUT/leaf.txt"
    528 EOF
    529 
    530 cat > "$ws/recipes/shadow_parent.sh" <<'EOF'
    531 #!/bin/sh
    532 set -eu
    533 mkdir -p "$KIT_BUILD_OUT"
    534 mode=$("$KIT" build config-get mode || true)
    535 dep_dir=$("$KIT" build need --config mode=child //shadow:leaf)
    536 printf 'parent:%s\n' "$mode" > "$KIT_BUILD_OUT/parent.txt"
    537 cat "$dep_dir/leaf.txt" > "$KIT_BUILD_OUT/leaf.txt"
    538 EOF
    539 
    540 cat > "$ws/recipes/stable_dep.sh" <<'EOF'
    541 #!/bin/sh
    542 set -eu
    543 mkdir -p "$KIT_BUILD_OUT"
    544 "$KIT" build source src/noop.txt >/dev/null
    545 printf 'stable\n' > "$KIT_BUILD_OUT/stable.txt"
    546 EOF
    547 
    548 cat > "$ws/recipes/stable_parent.sh" <<'EOF'
    549 #!/bin/sh
    550 set -eu
    551 mkdir -p "$KIT_BUILD_OUT"
    552 dep_dir=$("$KIT" build need //stable:dep)
    553 cat "$dep_dir/stable.txt" > "$KIT_BUILD_OUT/stable.txt"
    554 EOF
    555 
    556 cat > "$ws/recipes/submit.sh" <<'EOF'
    557 #!/bin/sh
    558 set -eu
    559 mkdir -p "$KIT_BUILD_OUT"
    560 tok=$("$KIT" build need-submit echo -- via-submit)
    561 dep_dir=$("$KIT" build need-await "$tok")
    562 cat "$dep_dir/args.txt" > "$KIT_BUILD_OUT/submit.txt"
    563 dep_dir_again=$("$KIT" build need-await "$tok")
    564 cat "$dep_dir_again/args.txt" > "$KIT_BUILD_OUT/submit-again.txt"
    565 EOF
    566 
    567 cat > "$ws/recipes/test_pass.sh" <<'EOF'
    568 #!/bin/sh
    569 set -eu
    570 count=0
    571 if [ -f test-pass.count ]; then
    572     count=$(cat test-pass.count)
    573 fi
    574 count=$((count + 1))
    575 printf '%s\n' "$count" > test-pass.count
    576 mkdir -p "$KIT_BUILD_OUT"
    577 "$KIT" build source src/a.txt >/dev/null
    578 printf 'pass-artifact\n' > "$KIT_BUILD_OUT/result.txt"
    579 printf 'pass-stdout:%s\n' "$count"
    580 printf 'pass-stderr:%s\n' "$count" >&2
    581 EOF
    582 
    583 cat > "$ws/recipes/test_parent.sh" <<'EOF'
    584 #!/bin/sh
    585 set -eu
    586 count=0
    587 if [ -f test-parent.count ]; then
    588     count=$(cat test-parent.count)
    589 fi
    590 count=$((count + 1))
    591 printf '%s\n' "$count" > test-parent.count
    592 mkdir -p "$KIT_BUILD_OUT"
    593 dep_dir=$("$KIT" build need //stable:dep)
    594 cat "$dep_dir/stable.txt" > "$KIT_BUILD_OUT/stable.txt"
    595 printf 'parent-pass\n'
    596 EOF
    597 
    598 cat > "$ws/recipes/test_fail.sh" <<'EOF'
    599 #!/bin/sh
    600 set -eu
    601 count=0
    602 if [ -f test-fail.count ]; then
    603     count=$(cat test-fail.count)
    604 fi
    605 count=$((count + 1))
    606 printf '%s\n' "$count" > test-fail.count
    607 mkdir -p "$KIT_BUILD_OUT"
    608 printf 'fail-artifact:%s\n' "$count" > "$KIT_BUILD_OUT/fail.txt"
    609 printf 'fail-stdout:%s\n' "$count"
    610 printf 'fail-stderr:%s\n' "$count" >&2
    611 if [ -f src/test_fail_mode ] && grep -q '^pass$' src/test_fail_mode; then
    612     exit 0
    613 fi
    614 exit 7
    615 EOF
    616 
    617 cat > "$ws/recipes/test_nondet.sh" <<'EOF'
    618 #!/bin/sh
    619 set -eu
    620 count=0
    621 if [ -f test-nondet.count ]; then
    622     count=$(cat test-nondet.count)
    623 fi
    624 count=$((count + 1))
    625 printf '%s\n' "$count" > test-nondet.count
    626 mkdir -p "$KIT_BUILD_OUT"
    627 printf 'nondet-test:%s\n' "$count" > "$KIT_BUILD_OUT/nondet.txt"
    628 printf 'nondet-stdout:%s\n' "$count"
    629 EOF
    630 cat > "$ws/redo/do/default.o.do" <<'EOF'
    631 #!/bin/sh
    632 set -eu
    633 mkdir -p "$KIT_BUILD_OUT"
    634 printf '%s\n' "$KIT_BUILD_TARGET" > "$KIT_BUILD_OUT/redo.txt"
    635 EOF
    636 chmod +x "$ws"/recipes/*.sh
    637 chmod +x "$ws/redo/do/default.o.do"
    638 
    639 mkdir -p "$work/extsrc"
    640 cat > "$work/extsrc/BUILD.kit" <<'EOF'
    641 kit-build 1
    642 [target data]
    643 recipe //build.sh
    644 EOF
    645 cat > "$work/extsrc/data.txt" <<'EOF'
    646 external-data
    647 EOF
    648 cat > "$work/extsrc/build.sh" <<'EOF'
    649 #!/bin/sh
    650 set -eu
    651 src=$("$KIT" build source data.txt)
    652 mode=$("$KIT" build config-get workspace-mode || true)
    653 mkdir -p "$KIT_BUILD_OUT"
    654 printf 'external:%s:%s:%s\n' "$(cat "$src")" "$KIT_BUILD_TARGET" "$mode" \
    655     > "$KIT_BUILD_OUT/external.txt"
    656 EOF
    657 chmod +x "$work/extsrc/build.sh"
    658 if ! "$KIT" cas add-tree --cas "$store/cas" --root "$work/extsrc" \
    659     > "$work/external-tree.out" 2> "$work/external-tree.err"; then
    660     cat "$work/external-tree.err" >&2
    661     exit 2
    662 fi
    663 ext_tree=$(awk 'NR == 1 {print $1}' "$work/external-tree.out")
    664 case "$ext_tree" in
    665     ????????????????????????????????????????????????????????????????)
    666         ;;
    667     *)
    668         echo "could not parse external tree id" >&2
    669         exit 2
    670         ;;
    671 esac
    672 
    673 have_targz_external=0
    674 ext_gz_blob=
    675 if command -v tar >/dev/null 2>&1 && command -v gzip >/dev/null 2>&1; then
    676     mkdir -p "$work/targzsrc/extgz-1"
    677     cat > "$work/targzsrc/extgz-1/BUILD.kit" <<'EOF'
    678 kit-build 1
    679 [target data]
    680 recipe //build.sh
    681 EOF
    682     cat > "$work/targzsrc/extgz-1/data.txt" <<'EOF'
    683 external-gzip-data
    684 EOF
    685     cat > "$work/targzsrc/extgz-1/build.sh" <<'EOF'
    686 #!/bin/sh
    687 set -eu
    688 src=$("$KIT" build source data.txt)
    689 mkdir -p "$KIT_BUILD_OUT"
    690 printf 'targz:%s:%s\n' "$(cat "$src")" "$KIT_BUILD_TARGET" \
    691     > "$KIT_BUILD_OUT/targz.txt"
    692 EOF
    693     chmod +x "$work/targzsrc/extgz-1/build.sh"
    694     if (cd "$work/targzsrc" &&
    695         COPYFILE_DISABLE=1 tar --format ustar -czf "$work/extgz.tar.gz" \
    696             extgz-1) \
    697         > "$work/targz-pack.out" 2> "$work/targz-pack.err" &&
    698        "$KIT" cas add-blob --cas "$store/cas" "$work/extgz.tar.gz" \
    699         > "$work/targz-blob.out" 2> "$work/targz-blob.err"; then
    700         ext_gz_blob=$(awk 'NR == 1 {print $1}' "$work/targz-blob.out")
    701         case "$ext_gz_blob" in
    702             ????????????????????????????????????????????????????????????????)
    703                 have_targz_external=1
    704                 ;;
    705             *)
    706                 have_targz_external=0
    707                 ;;
    708         esac
    709     fi
    710 fi
    711 
    712 cat > "$ws/WORKSPACE.kit" <<EOF
    713 kit-workspace 1
    714 name buildcoord
    715 version test
    716 
    717 [config default]
    718 workspace-mode default
    719 
    720 [config release]
    721 inherits default
    722 workspace-mode release
    723 
    724 [external ext]
    725 format tree
    726 archive $ext_tree
    727 EOF
    728 if [ "$have_targz_external" -eq 1 ]; then
    729     cat >> "$ws/WORKSPACE.kit" <<EOF
    730 
    731 [external gz]
    732 format tar.gz
    733 archive $ext_gz_blob
    734 strip-prefix extgz-1
    735 EOF
    736 fi
    737 
    738 run_build() {
    739     name=$1
    740     shift
    741     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
    742         --config "env.KIT=$KIT" "$@" \
    743         > "$work/$name.out" 2> "$work/$name.err"
    744 }
    745 
    746 run_test() {
    747     name=$1
    748     shift
    749     "$KIT" build test --store "$store" --root "$ws" --def BUILD.kit \
    750         --config "env.KIT=$KIT" "$@" \
    751         > "$work/$name.out" 2> "$work/$name.err"
    752 }
    753 
    754 run_build_tool() {
    755     name=$1
    756     shift
    757     "$KIT" build --store "$store" --root "$ws" --def-name BUILD.kit "$@" \
    758         > "$work/$name.out" 2> "$work/$name.err"
    759 }
    760 
    761 build_assert_ok() {
    762     name=$1
    763     shift
    764     if run_build "$name" "$@"; then
    765         ok "$name"
    766     else
    767         not_ok "$name" "$work/$name.err"
    768     fi
    769 }
    770 
    771 test_assert_pass() {
    772     name=$1
    773     shift
    774     if run_test "$name" "$@"; then
    775         if awk 'NR == 1 && $1 == "PASS" {ok = 1} END {exit ok ? 0 : 1}' \
    776             "$work/$name.out"; then
    777             ok "$name"
    778         else
    779             not_ok "$name" "$work/$name.out"
    780         fi
    781     else
    782         not_ok "$name" "$work/$name.err"
    783     fi
    784 }
    785 
    786 test_assert_fail_result() {
    787     name=$1
    788     shift
    789     if run_test "$name" "$@"; then
    790         not_ok "$name" "$work/$name.out"
    791     else
    792         if awk 'NR == 1 && $1 == "FAIL" {ok = 1} END {exit ok ? 0 : 1}' \
    793             "$work/$name.out"; then
    794             ok "$name"
    795         else
    796             not_ok "$name" "$work/$name.err"
    797         fi
    798     fi
    799 }
    800 
    801 not_contains() {
    802     name=$1
    803     file=$2
    804     needle=$3
    805     if grep -F "$needle" "$file" >/dev/null 2>&1; then
    806         { printf 'unexpected text: %s\n' "$needle"; sed 's/^/file: /' "$file"; } \
    807             > "$work/$name.diag"
    808         not_ok "$name" "$work/$name.diag"
    809     else
    810         ok "$name"
    811     fi
    812 }
    813 
    814 tree_path_from() {
    815     awk 'NF >= 2 {print $2; exit}' "$1"
    816 }
    817 
    818 test_tree_path_from() {
    819     awk 'NF >= 3 {print $3; exit}' "$1"
    820 }
    821 
    822 first_field_from() {
    823     awk 'NF >= 1 {print $1; exit}' "$1"
    824 }
    825 
    826 second_field_from() {
    827     awk 'NF >= 2 {print $2; exit}' "$1"
    828 }
    829 
    830 tree_id_from() {
    831     awk 'NF >= 1 {print $1; exit}' "$1"
    832 }
    833 
    834 target_record_for() {
    835     target=$1
    836     find "$store/build/target" -type f -exec grep -l "$target" {} + 2>/dev/null |
    837         awk 'NR == 1 {print; exit}'
    838 }
    839 
    840 cache_path_from() {
    841     id=$1
    842     pp=$(printf '%.2s' "$id")
    843     printf '%s/build/cache/%s/%s\n' "$store" "$pp" "$id"
    844 }
    845 
    846 cas_tree_path_from() {
    847     id=$1
    848     pp=$(printf '%.2s' "$id")
    849     printf '%s/cas/tree/%s/%s\n' "$store" "$pp" "$id"
    850 }
    851 
    852 run_build cold //app:bundle
    853 if [ $? -eq 0 ]; then
    854     ok "buildcoord-cold-build"
    855 else
    856     not_ok "buildcoord-cold-build" "$work/cold.err"
    857 fi
    858 cold_path=$(tree_path_from "$work/cold.out")
    859 if [ -n "$cold_path" ] && [ -d "$cold_path" ]; then
    860     ok "buildcoord-cold-output-path"
    861 else
    862     echo "missing output path: $cold_path" > "$work/cold-path.diag"
    863     not_ok "buildcoord-cold-output-path" "$work/cold-path.diag"
    864 fi
    865 contains "buildcoord-source-a" "$cold_path/sources.txt" "alpha"
    866 contains "buildcoord-source-b" "$cold_path/sources.txt" "beta"
    867 contains "buildcoord-need-output" "$cold_path/lib.txt" "lib:debug"
    868 contains "buildcoord-target-env" "$cold_path/target.txt" "//app:bundle"
    869 contains "buildcoord-package-env" "$cold_path/package.txt" "app"
    870 
    871 run_build cached //app:bundle
    872 if [ $? -eq 0 ]; then
    873     ok "buildcoord-cache-build"
    874 else
    875     not_ok "buildcoord-cache-build" "$work/cached.err"
    876 fi
    877 cached_path=$(tree_path_from "$work/cached.out")
    878 if [ "$cached_path" = "$cold_path" ]; then
    879     ok "buildcoord-cache-reuses-tree"
    880 else
    881     printf 'cold=%s\ncached=%s\n' "$cold_path" "$cached_path" \
    882         > "$work/cache-tree.diag"
    883     not_ok "buildcoord-cache-reuses-tree" "$work/cache-tree.diag"
    884 fi
    885 
    886 cat > "$ws/src/b.txt" <<'EOF'
    887 beta2
    888 EOF
    889 run_build changed //app:bundle
    890 if [ $? -eq 0 ]; then
    891     ok "buildcoord-glob-change-build"
    892 else
    893     not_ok "buildcoord-glob-change-build" "$work/changed.err"
    894 fi
    895 changed_path=$(tree_path_from "$work/changed.out")
    896 contains "buildcoord-glob-change-visible" "$changed_path/sources.txt" "beta2"
    897 if [ "$changed_path" != "$cold_path" ]; then
    898     ok "buildcoord-glob-change-new-tree"
    899 else
    900     printf 'unchanged tree path=%s\n' "$changed_path" > "$work/change-tree.diag"
    901     not_ok "buildcoord-glob-change-new-tree" "$work/change-tree.diag"
    902 fi
    903 
    904 run_build verify --verify //app:bundle
    905 if [ $? -eq 0 ]; then
    906     ok "buildcoord-verify"
    907 else
    908     not_ok "buildcoord-verify" "$work/verify.err"
    909 fi
    910 
    911 run_fail "buildcoord-missing-target-fails" \
    912     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
    913         --config "env.KIT=$KIT" //missing:target
    914 contains "buildcoord-missing-target-diag" "$work/buildcoord-missing-target-fails.err" \
    915     "build failed"
    916 
    917 run_fail "buildcoord-helper-outside-recipe-fails" \
    918     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit glob 'src/*.txt'
    919 contains "buildcoord-helper-outside-recipe-diag" \
    920     "$work/buildcoord-helper-outside-recipe-fails.err" "unexpected argument"
    921 
    922 if run_build_tool buildcoord-list-package list //listpkg/...; then
    923     ok "buildcoord-list-package"
    924 else
    925     not_ok "buildcoord-list-package" "$work/buildcoord-list-package.err"
    926 fi
    927 contains "buildcoord-list-exact-target" \
    928     "$work/buildcoord-list-package.out" "//listpkg:exact"
    929 contains "buildcoord-list-generated-target" \
    930     "$work/buildcoord-list-package.out" "//listpkg:foo.o"
    931 contains "buildcoord-list-nested-package" \
    932     "$work/buildcoord-list-package.out" "//listpkg/subpkg:child"
    933 not_contains "buildcoord-list-no-child-files-from-parent-rule" \
    934     "$work/buildcoord-list-package.out" "//listpkg:sub/bar.o"
    935 
    936 if run_build_tool buildcoord-list-scan-do list --scan-do //redo/...; then
    937     ok "buildcoord-list-scan-do"
    938 else
    939     not_ok "buildcoord-list-scan-do" "$work/buildcoord-list-scan-do.err"
    940 fi
    941 contains "buildcoord-list-scan-do-default-provider" \
    942     "$work/buildcoord-list-scan-do.out" "default.o.do"
    943 
    944 run_fail "buildcoord-invalid-def-name-rejected" \
    945     "$KIT" build --store "$store" --root "$ws" --def-name ../BUILD.kit \
    946         //app:bundle
    947 contains "buildcoord-invalid-def-name-diag" \
    948     "$work/buildcoord-invalid-def-name-rejected.err" "def"
    949 
    950 run_fail "buildcoord-invalid-label-rejected" \
    951     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit //bad/../pkg:target
    952 contains "buildcoord-invalid-label-diag" \
    953     "$work/buildcoord-invalid-label-rejected.err" "invalid"
    954 
    955 mkdir -p "$ws/badrecipe"
    956 cat > "$ws/badrecipe/BUILD.kit" <<'EOF'
    957 kit-build 1
    958 [target probe]
    959 recipe ../recipes/argv.sh
    960 EOF
    961 run_fail "buildcoord-invalid-recipe-path-rejected" \
    962     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
    963         --config "env.KIT=$KIT" //badrecipe:probe
    964 contains "buildcoord-invalid-recipe-path-diag" \
    965     "$work/buildcoord-invalid-recipe-path-rejected.err" "recipe"
    966 
    967 build_assert_ok buildcoord-workspace-default //wscfg:probe
    968 wscfg_default_path=$(tree_path_from "$work/buildcoord-workspace-default.out")
    969 contains "buildcoord-workspace-default-output" \
    970     "$wscfg_default_path/workspace.txt" "workspace:default"
    971 
    972 build_assert_ok buildcoord-workspace-profile --profile release //wscfg:probe
    973 wscfg_release_path=$(tree_path_from "$work/buildcoord-workspace-profile.out")
    974 contains "buildcoord-workspace-profile-output" \
    975     "$wscfg_release_path/workspace.txt" "workspace:release"
    976 
    977 build_assert_ok buildcoord-workspace-profile-override --profile release \
    978     --config workspace-mode=cli //wscfg:probe
    979 wscfg_cli_path=$(tree_path_from \
    980     "$work/buildcoord-workspace-profile-override.out")
    981 contains "buildcoord-workspace-profile-override-output" \
    982     "$wscfg_cli_path/workspace.txt" "workspace:cli"
    983 
    984 build_assert_ok buildcoord-external-direct @ext//:data
    985 external_direct_path=$(tree_path_from "$work/buildcoord-external-direct.out")
    986 contains "buildcoord-external-direct-output" \
    987     "$external_direct_path/external.txt" "external:external-data:@ext//:data:default"
    988 
    989 build_assert_ok buildcoord-external-need //extuser:probe
    990 external_need_path=$(tree_path_from "$work/buildcoord-external-need.out")
    991 contains "buildcoord-external-need-output" \
    992     "$external_need_path/via-external.txt" \
    993     "external:external-data:@ext//:data:default"
    994 
    995 if [ "$have_targz_external" -eq 1 ]; then
    996     build_assert_ok buildcoord-external-targz @gz//:data
    997     external_targz_path=$(tree_path_from "$work/buildcoord-external-targz.out")
    998     contains "buildcoord-external-targz-output" \
    999         "$external_targz_path/targz.txt" "targz:external-gzip-data:@gz//:data"
   1000 else
   1001     kit_skip "buildcoord-external-targz" "host tar/gzip unavailable"
   1002 fi
   1003 
   1004 if run_build_tool buildcoord-repo-list repo list; then
   1005     ok "buildcoord-repo-list"
   1006 else
   1007     not_ok "buildcoord-repo-list" "$work/buildcoord-repo-list.err"
   1008 fi
   1009 contains "buildcoord-repo-list-ext" "$work/buildcoord-repo-list.out" "ext"
   1010 contains "buildcoord-repo-list-tree-format" \
   1011     "$work/buildcoord-repo-list.out" "tree"
   1012 
   1013 if run_build_tool buildcoord-repo-fetch repo fetch ext; then
   1014     ok "buildcoord-repo-fetch"
   1015 else
   1016     not_ok "buildcoord-repo-fetch" "$work/buildcoord-repo-fetch.err"
   1017 fi
   1018 contains "buildcoord-repo-fetch-output" \
   1019     "$work/buildcoord-repo-fetch.out" "ext"
   1020 
   1021 mkdir -p "$work/repoadd-src"
   1022 cat > "$work/repoadd-src/WORKSPACE.kit" <<'EOF'
   1023 kit-workspace 1
   1024 name repoadd
   1025 version test
   1026 EOF
   1027 cat > "$work/repoadd-src/BUILD.kit" <<'EOF'
   1028 kit-build 1
   1029 [target data]
   1030 recipe //build.sh
   1031 EOF
   1032 cat > "$work/repoadd-src/build.sh" <<'EOF'
   1033 #!/bin/sh
   1034 set -eu
   1035 mkdir -p "$KIT_BUILD_OUT"
   1036 printf 'repoadd\n' > "$KIT_BUILD_OUT/repoadd.txt"
   1037 EOF
   1038 chmod +x "$work/repoadd-src/build.sh"
   1039 if (cd "$work" && COPYFILE_DISABLE=1 tar --format ustar -czf \
   1040         "$work/repoadd.tar.gz" repoadd-src) \
   1041         > "$work/repoadd-pack.out" 2> "$work/repoadd-pack.err"; then
   1042     if run_build_tool buildcoord-repo-add repo add added \
   1043             "file://$work/repoadd.tar.gz" --format tar.gz \
   1044             --strip-prefix repoadd-src; then
   1045         ok "buildcoord-repo-add"
   1046     else
   1047         not_ok "buildcoord-repo-add" "$work/buildcoord-repo-add.err"
   1048     fi
   1049     contains "buildcoord-repo-add-workspace-entry" "$ws/WORKSPACE.kit" \
   1050         "[external added]"
   1051 else
   1052     kit_skip "buildcoord-repo-add" "host tar unavailable"
   1053     kit_skip "buildcoord-repo-add-workspace-entry" "host tar unavailable"
   1054 fi
   1055 
   1056 if run_build_tool buildcoord-workspace-package workspace package \
   1057         --format tar.gz -o "$work/workspace-package.tar.gz"; then
   1058     ok "buildcoord-workspace-package"
   1059 else
   1060     not_ok "buildcoord-workspace-package" \
   1061         "$work/buildcoord-workspace-package.err"
   1062 fi
   1063 assert_file_exists "buildcoord-workspace-package-output" \
   1064     "$work/workspace-package.tar.gz"
   1065 if tar -tzf "$work/workspace-package.tar.gz" \
   1066         > "$work/workspace-package.list" 2> "$work/workspace-package-list.err"; then
   1067     ok "buildcoord-workspace-package-list"
   1068 else
   1069     not_ok "buildcoord-workspace-package-list" \
   1070         "$work/workspace-package-list.err"
   1071 fi
   1072 contains "buildcoord-workspace-package-includes-workspace" \
   1073     "$work/workspace-package.list" "WORKSPACE.kit"
   1074 contains "buildcoord-workspace-package-includes-build-def" \
   1075     "$work/workspace-package.list" "BUILD.kit"
   1076 not_contains "buildcoord-workspace-package-excludes-store" \
   1077     "$work/workspace-package.list" "/build/cache/"
   1078 
   1079 build_assert_ok buildcoord-absent-cold //absent:probe
   1080 absent_path=$(tree_path_from "$work/buildcoord-absent-cold.out")
   1081 contains "buildcoord-absent-cold-output" "$absent_path/optional.txt" "absent"
   1082 cat > "$ws/src/optional.txt" <<'EOF'
   1083 present
   1084 EOF
   1085 build_assert_ok buildcoord-absent-created //absent:probe
   1086 present_path=$(tree_path_from "$work/buildcoord-absent-created.out")
   1087 contains "buildcoord-absent-created-output" "$present_path/optional.txt" "present"
   1088 if [ "$present_path" != "$absent_path" ]; then
   1089     ok "buildcoord-absent-created-new-tree"
   1090 else
   1091     printf 'unchanged tree path=%s\n' "$present_path" > "$work/absent-tree.diag"
   1092     not_ok "buildcoord-absent-created-new-tree" "$work/absent-tree.diag"
   1093 fi
   1094 
   1095 build_assert_ok buildcoord-argv-top //argv:echo -- one two
   1096 argv_path=$(tree_path_from "$work/buildcoord-argv-top.out")
   1097 contains "buildcoord-argv-top-one" "$argv_path/args.txt" "one"
   1098 contains "buildcoord-argv-top-two" "$argv_path/args.txt" "two"
   1099 build_assert_ok buildcoord-argv-package-shorthand //argv -- short
   1100 argv_short_path=$(tree_path_from "$work/buildcoord-argv-package-shorthand.out")
   1101 contains "buildcoord-argv-package-shorthand-output" "$argv_short_path/args.txt" \
   1102     "short"
   1103 build_assert_ok buildcoord-argv-changed //argv:echo -- three
   1104 argv_changed_path=$(tree_path_from "$work/buildcoord-argv-changed.out")
   1105 contains "buildcoord-argv-changed-output" "$argv_changed_path/args.txt" "three"
   1106 if [ "$argv_changed_path" != "$argv_path" ]; then
   1107     ok "buildcoord-argv-changed-new-tree"
   1108 else
   1109     printf 'unchanged tree path=%s\n' "$argv_changed_path" > "$work/argv-tree.diag"
   1110     not_ok "buildcoord-argv-changed-new-tree" "$work/argv-tree.diag"
   1111 fi
   1112 
   1113 build_assert_ok buildcoord-need-argv //needargv:probe
   1114 need_argv_path=$(tree_path_from "$work/buildcoord-need-argv.out")
   1115 contains "buildcoord-need-argv-one" "$need_argv_path/dep-args.txt" "dep-one"
   1116 contains "buildcoord-need-argv-two" "$need_argv_path/dep-args.txt" "dep-two"
   1117 
   1118 build_assert_ok buildcoord-redo-default //redo:foo.o
   1119 redo_path=$(tree_path_from "$work/buildcoord-redo-default.out")
   1120 contains "buildcoord-redo-default-target" "$redo_path/redo.txt" "//redo:foo.o"
   1121 
   1122 build_assert_ok buildcoord-recipe-v1 //recipe:stamp
   1123 recipe_v1_path=$(tree_path_from "$work/buildcoord-recipe-v1.out")
   1124 contains "buildcoord-recipe-v1-output" "$recipe_v1_path/stamp.txt" "recipe:v1"
   1125 cat > "$ws/recipes/recipe.sh" <<'EOF'
   1126 #!/bin/sh
   1127 set -eu
   1128 mkdir -p "$KIT_BUILD_OUT"
   1129 printf 'recipe:v2\n' > "$KIT_BUILD_OUT/stamp.txt"
   1130 EOF
   1131 chmod +x "$ws/recipes/recipe.sh"
   1132 build_assert_ok buildcoord-recipe-v2 //recipe:stamp
   1133 recipe_v2_path=$(tree_path_from "$work/buildcoord-recipe-v2.out")
   1134 contains "buildcoord-recipe-v2-output" "$recipe_v2_path/stamp.txt" "recipe:v2"
   1135 if [ "$recipe_v2_path" != "$recipe_v1_path" ]; then
   1136     ok "buildcoord-recipe-edit-new-tree"
   1137 else
   1138     printf 'unchanged tree path=%s\n' "$recipe_v2_path" > "$work/recipe-tree.diag"
   1139     not_ok "buildcoord-recipe-edit-new-tree" "$work/recipe-tree.diag"
   1140 fi
   1141 
   1142 build_assert_ok buildcoord-repeat-inputs-cold --stats //repeat:probe
   1143 contains "buildcoord-repeat-inputs-cold-run" \
   1144     "$work/buildcoord-repeat-inputs-cold.err" "recipes_run=1"
   1145 repeat_path=$(tree_path_from "$work/buildcoord-repeat-inputs-cold.out")
   1146 contains "buildcoord-repeat-source-first" "$repeat_path/source1.txt" "alpha"
   1147 contains "buildcoord-repeat-source-second" "$repeat_path/source2.txt" "alpha"
   1148 if cmp -s "$repeat_path/glob1.txt" "$repeat_path/glob2.txt"; then
   1149     ok "buildcoord-repeat-glob-stable"
   1150 else
   1151     printf 'glob outputs differ\n' > "$work/repeat-glob.diag"
   1152     not_ok "buildcoord-repeat-glob-stable" "$work/repeat-glob.diag"
   1153 fi
   1154 build_assert_ok buildcoord-repeat-inputs-deep --stats //repeat:probe
   1155 contains "buildcoord-repeat-inputs-deep-hit" \
   1156     "$work/buildcoord-repeat-inputs-deep.err" "deep_hits=1"
   1157 contains "buildcoord-repeat-inputs-deep-no-run" \
   1158     "$work/buildcoord-repeat-inputs-deep.err" "recipes_run=0"
   1159 
   1160 build_assert_ok buildcoord-depfile-cold --stats //depfile:probe
   1161 contains "buildcoord-depfile-cold-run" "$work/buildcoord-depfile-cold.err" \
   1162     "recipes_run=1"
   1163 depfile_cold_path=$(tree_path_from "$work/buildcoord-depfile-cold.out")
   1164 contains "buildcoord-depfile-cold-a" "$depfile_cold_path/combined.txt" \
   1165     "dep-a:v1"
   1166 contains "buildcoord-depfile-cold-b" "$depfile_cold_path/combined.txt" \
   1167     "dep-b:v1"
   1168 build_assert_ok buildcoord-depfile-deep --stats //depfile:probe
   1169 contains "buildcoord-depfile-deep-hit" "$work/buildcoord-depfile-deep.err" \
   1170     "deep_hits=1"
   1171 contains "buildcoord-depfile-deep-no-run" "$work/buildcoord-depfile-deep.err" \
   1172     "recipes_run=0"
   1173 cat > "$ws/src/depfile/a.h" <<'EOF'
   1174 dep-a:v2
   1175 EOF
   1176 build_assert_ok buildcoord-depfile-edit --stats //depfile:probe
   1177 contains "buildcoord-depfile-edit-run" "$work/buildcoord-depfile-edit.err" \
   1178     "recipes_run=1"
   1179 depfile_edit_path=$(tree_path_from "$work/buildcoord-depfile-edit.out")
   1180 contains "buildcoord-depfile-edit-output" "$depfile_edit_path/combined.txt" \
   1181     "dep-a:v2"
   1182 
   1183 build_assert_ok buildcoord-depfile-lines-cold --stats //depfile:lines
   1184 contains "buildcoord-depfile-lines-cold-run" \
   1185     "$work/buildcoord-depfile-lines-cold.err" "recipes_run=1"
   1186 depfile_lines_cold_path=$(
   1187     tree_path_from "$work/buildcoord-depfile-lines-cold.out")
   1188 contains "buildcoord-depfile-lines-cold-a" \
   1189     "$depfile_lines_cold_path/combined.txt" "dep-a:v2"
   1190 contains "buildcoord-depfile-lines-cold-b" \
   1191     "$depfile_lines_cold_path/combined.txt" "dep-b:v1"
   1192 build_assert_ok buildcoord-depfile-lines-deep --stats //depfile:lines
   1193 contains "buildcoord-depfile-lines-deep-hit" \
   1194     "$work/buildcoord-depfile-lines-deep.err" "deep_hits=1"
   1195 contains "buildcoord-depfile-lines-deep-no-run" \
   1196     "$work/buildcoord-depfile-lines-deep.err" "recipes_run=0"
   1197 cat > "$ws/src/depfile/b.h" <<'EOF'
   1198 dep-b:v2
   1199 EOF
   1200 build_assert_ok buildcoord-depfile-lines-edit --stats //depfile:lines
   1201 contains "buildcoord-depfile-lines-edit-run" \
   1202     "$work/buildcoord-depfile-lines-edit.err" "recipes_run=1"
   1203 depfile_lines_edit_path=$(
   1204     tree_path_from "$work/buildcoord-depfile-lines-edit.out")
   1205 contains "buildcoord-depfile-lines-edit-output" \
   1206     "$depfile_lines_edit_path/combined.txt" "dep-b:v2"
   1207 
   1208 build_assert_ok buildcoord-stats-cold --stats //stable:parent
   1209 contains "buildcoord-stats-cold-recipes" "$work/buildcoord-stats-cold.err" \
   1210     "recipes_run=2"
   1211 contains "buildcoord-stats-cold-no-deep" "$work/buildcoord-stats-cold.err" \
   1212     "deep_hits=0"
   1213 contains "buildcoord-stats-cold-no-shallow" "$work/buildcoord-stats-cold.err" \
   1214     "shallow_hits=0"
   1215 
   1216 build_assert_ok buildcoord-stats-deep --stats //stable:parent
   1217 contains "buildcoord-stats-deep-hit" "$work/buildcoord-stats-deep.err" \
   1218     "deep_hits=1"
   1219 contains "buildcoord-stats-deep-no-run" "$work/buildcoord-stats-deep.err" \
   1220     "recipes_run=0"
   1221 
   1222 cat > "$ws/src/noop.txt" <<'EOF'
   1223 second
   1224 EOF
   1225 build_assert_ok buildcoord-stats-shallow --stats //stable:parent
   1226 contains "buildcoord-stats-shallow-hit" "$work/buildcoord-stats-shallow.err" \
   1227     "shallow_hits=1"
   1228 contains "buildcoord-stats-shallow-child-run" "$work/buildcoord-stats-shallow.err" \
   1229     "recipes_run=1"
   1230 stable_shallow_path=$(tree_path_from "$work/buildcoord-stats-shallow.out")
   1231 contains "buildcoord-stats-shallow-output" "$stable_shallow_path/stable.txt" \
   1232     "stable"
   1233 
   1234 build_assert_ok buildcoord-stats-cfg-cold --stats --config mode=debug //cfg:probe
   1235 contains "buildcoord-stats-cfg-cold-run" "$work/buildcoord-stats-cfg-cold.err" \
   1236     "recipes_run=1"
   1237 build_assert_ok buildcoord-stats-cfg-deep --stats --config mode=debug //cfg:probe
   1238 contains "buildcoord-stats-cfg-deep-hit" "$work/buildcoord-stats-cfg-deep.err" \
   1239     "deep_hits=1"
   1240 contains "buildcoord-stats-cfg-deep-no-run" "$work/buildcoord-stats-cfg-deep.err" \
   1241     "recipes_run=0"
   1242 build_assert_ok buildcoord-stats-cfg-change --stats --config mode=release //cfg:probe
   1243 contains "buildcoord-stats-cfg-change-run" "$work/buildcoord-stats-cfg-change.err" \
   1244     "recipes_run=1"
   1245 contains "buildcoord-stats-cfg-change-no-hit" "$work/buildcoord-stats-cfg-change.err" \
   1246     "shallow_hits=0"
   1247 cfg_change_path=$(tree_path_from "$work/buildcoord-stats-cfg-change.out")
   1248 contains "buildcoord-stats-cfg-change-output" "$cfg_change_path/mode.txt" \
   1249     "mode:release"
   1250 
   1251 build_assert_ok buildcoord-config-unread-cold --stats --config flavor=one \
   1252     //scope:plain
   1253 contains "buildcoord-config-unread-cold-run" \
   1254     "$work/buildcoord-config-unread-cold.err" "recipes_run=1"
   1255 build_assert_ok buildcoord-config-unread-change --stats --config flavor=two \
   1256     //scope:plain
   1257 contains "buildcoord-config-unread-change-deep" \
   1258     "$work/buildcoord-config-unread-change.err" "deep_hits=1"
   1259 contains "buildcoord-config-unread-change-no-run" \
   1260     "$work/buildcoord-config-unread-change.err" "recipes_run=0"
   1261 plain_change_path=$(tree_path_from "$work/buildcoord-config-unread-change.out")
   1262 contains "buildcoord-config-unread-change-output" "$plain_change_path/plain.txt" \
   1263     "plain"
   1264 
   1265 build_assert_ok buildcoord-config-inherit-cold --stats --config mode=debug \
   1266     //scope:parent-inherit
   1267 inherit_debug_path=$(tree_path_from "$work/buildcoord-config-inherit-cold.out")
   1268 contains "buildcoord-config-inherit-debug-output" "$inherit_debug_path/mode.txt" \
   1269     "mode:debug"
   1270 build_assert_ok buildcoord-config-inherit-change --stats --config mode=release \
   1271     //scope:parent-inherit
   1272 contains "buildcoord-config-inherit-change-runs" \
   1273     "$work/buildcoord-config-inherit-change.err" "recipes_run=2"
   1274 inherit_release_path=$(tree_path_from "$work/buildcoord-config-inherit-change.out")
   1275 contains "buildcoord-config-inherit-release-output" \
   1276     "$inherit_release_path/mode.txt" "mode:release"
   1277 if [ "$inherit_release_path" != "$inherit_debug_path" ]; then
   1278     ok "buildcoord-config-inherit-new-tree"
   1279 else
   1280     printf 'unchanged tree path=%s\n' "$inherit_release_path" \
   1281         > "$work/config-inherit-tree.diag"
   1282     not_ok "buildcoord-config-inherit-new-tree" \
   1283         "$work/config-inherit-tree.diag"
   1284 fi
   1285 
   1286 build_assert_ok buildcoord-config-override-cold --stats --config mode=debug \
   1287     //scope:parent-override
   1288 override_debug_path=$(tree_path_from "$work/buildcoord-config-override-cold.out")
   1289 contains "buildcoord-config-override-debug-output" \
   1290     "$override_debug_path/mode.txt" "mode:forced"
   1291 build_assert_ok buildcoord-config-override-leaf-direct-deep --trace --stats \
   1292     --config mode=forced //scope:leaf
   1293 contains "buildcoord-config-override-leaf-direct-deep-hit" \
   1294     "$work/buildcoord-config-override-leaf-direct-deep.err" "deep_hits=1"
   1295 contains "buildcoord-config-override-leaf-direct-deep-target-hit" \
   1296     "$work/buildcoord-config-override-leaf-direct-deep.err" \
   1297     "trace deep-hit target=//scope:leaf"
   1298 contains "buildcoord-config-override-leaf-direct-deep-no-run" \
   1299     "$work/buildcoord-config-override-leaf-direct-deep.err" "recipes_run=0"
   1300 build_assert_ok buildcoord-config-override-change --trace --stats \
   1301     --config mode=release //scope:parent-override
   1302 contains "buildcoord-config-override-change-deep" \
   1303     "$work/buildcoord-config-override-change.err" "deep_hits=1"
   1304 contains "buildcoord-config-override-change-parent-deep" \
   1305     "$work/buildcoord-config-override-change.err" \
   1306     "trace deep-hit target=//scope:parent-override"
   1307 contains "buildcoord-config-override-change-shielded-trace" \
   1308     "$work/buildcoord-config-override-change.err" \
   1309     "deep-config target=//scope:parent-override child=//scope:leaf key=mode scope=overlay-shielded"
   1310 not_contains "buildcoord-config-override-change-parent-not-shallow" \
   1311     "$work/buildcoord-config-override-change.err" \
   1312     "trace shallow-hit target=//scope:parent-override"
   1313 contains "buildcoord-config-override-change-no-run" \
   1314     "$work/buildcoord-config-override-change.err" "recipes_run=0"
   1315 override_release_path=$(tree_path_from "$work/buildcoord-config-override-change.out")
   1316 contains "buildcoord-config-override-release-output" \
   1317     "$override_release_path/mode.txt" "mode:forced"
   1318 if [ "$override_release_path" = "$override_debug_path" ]; then
   1319     ok "buildcoord-config-override-reuses-tree"
   1320 else
   1321     printf 'debug=%s\nrelease=%s\n' "$override_debug_path" \
   1322         "$override_release_path" > "$work/config-override-tree.diag"
   1323     not_ok "buildcoord-config-override-reuses-tree" \
   1324         "$work/config-override-tree.diag"
   1325 fi
   1326 
   1327 cat > "$ws/src/scope-noop.txt" <<'EOF'
   1328 second
   1329 EOF
   1330 build_assert_ok buildcoord-config-override-shallow --trace --stats \
   1331     --config mode=profile //scope:parent-override
   1332 contains "buildcoord-config-override-shallow-parent-hit" \
   1333     "$work/buildcoord-config-override-shallow.err" \
   1334     "trace shallow-hit target=//scope:parent-override"
   1335 contains "buildcoord-config-override-shallow-one-run" \
   1336     "$work/buildcoord-config-override-shallow.err" "recipes_run=1"
   1337 contains "buildcoord-config-override-shallow-count" \
   1338     "$work/buildcoord-config-override-shallow.err" "shallow_hits=1"
   1339 override_shallow_path=$(
   1340     tree_path_from "$work/buildcoord-config-override-shallow.out")
   1341 contains "buildcoord-config-override-shallow-output" \
   1342     "$override_shallow_path/mode.txt" "mode:forced"
   1343 
   1344 build_assert_ok buildcoord-config-shadow-parent-cold --stats --config mode=parent1 \
   1345     //shadow:parent
   1346 contains "buildcoord-config-shadow-parent-cold-run" \
   1347     "$work/buildcoord-config-shadow-parent-cold.err" "recipes_run=2"
   1348 shadow_parent1_path=$(tree_path_from \
   1349     "$work/buildcoord-config-shadow-parent-cold.out")
   1350 contains "buildcoord-config-shadow-parent-cold-parent" \
   1351     "$shadow_parent1_path/parent.txt" "parent:parent1"
   1352 contains "buildcoord-config-shadow-parent-cold-leaf" \
   1353     "$shadow_parent1_path/leaf.txt" "leaf:child"
   1354 build_assert_ok buildcoord-config-shadow-parent-deep --stats --config mode=parent1 \
   1355     //shadow:parent
   1356 contains "buildcoord-config-shadow-parent-deep-hit" \
   1357     "$work/buildcoord-config-shadow-parent-deep.err" "deep_hits=1"
   1358 contains "buildcoord-config-shadow-parent-deep-no-run" \
   1359     "$work/buildcoord-config-shadow-parent-deep.err" "recipes_run=0"
   1360 build_assert_ok buildcoord-config-shadow-leaf-direct-deep --stats \
   1361     --config mode=child //shadow:leaf
   1362 contains "buildcoord-config-shadow-leaf-direct-deep-hit" \
   1363     "$work/buildcoord-config-shadow-leaf-direct-deep.err" "deep_hits=1"
   1364 contains "buildcoord-config-shadow-leaf-direct-deep-no-run" \
   1365     "$work/buildcoord-config-shadow-leaf-direct-deep.err" "recipes_run=0"
   1366 shadow_leaf_path=$(tree_path_from \
   1367     "$work/buildcoord-config-shadow-leaf-direct-deep.out")
   1368 contains "buildcoord-config-shadow-leaf-direct-deep-output" \
   1369     "$shadow_leaf_path/leaf.txt" "leaf:child"
   1370 build_assert_ok buildcoord-config-shadow-parent-change --stats --config mode=parent2 \
   1371     //shadow:parent
   1372 contains "buildcoord-config-shadow-parent-change-rerun" \
   1373     "$work/buildcoord-config-shadow-parent-change.err" "recipes_run=1"
   1374 contains "buildcoord-config-shadow-parent-change-child-hit" \
   1375     "$work/buildcoord-config-shadow-parent-change.err" "deep_hits=1"
   1376 shadow_parent2_path=$(tree_path_from \
   1377     "$work/buildcoord-config-shadow-parent-change.out")
   1378 contains "buildcoord-config-shadow-parent-change-parent" \
   1379     "$shadow_parent2_path/parent.txt" "parent:parent2"
   1380 contains "buildcoord-config-shadow-parent-change-leaf" \
   1381     "$shadow_parent2_path/leaf.txt" "leaf:child"
   1382 
   1383 build_assert_ok buildcoord-config-shadow-parent-change-trace --trace --stats \
   1384     --config mode=parent3 //shadow:parent
   1385 contains "buildcoord-config-shadow-parent-root-mismatch-trace" \
   1386     "$work/buildcoord-config-shadow-parent-change-trace.err" \
   1387     "deep-config target=//shadow:parent key=mode scope=root result=mismatch"
   1388 contains "buildcoord-config-shadow-parent-child-shielded-trace" \
   1389     "$work/buildcoord-config-shadow-parent-change-trace.err" \
   1390     "deep-config target=//shadow:parent child=//shadow:leaf key=mode scope=overlay-shielded"
   1391 
   1392 build_assert_ok buildcoord-stats-argv-cold --stats //argv:echo -- stat-one
   1393 contains "buildcoord-stats-argv-cold-run" "$work/buildcoord-stats-argv-cold.err" \
   1394     "recipes_run=1"
   1395 build_assert_ok buildcoord-stats-argv-deep --stats //argv:echo -- stat-one
   1396 contains "buildcoord-stats-argv-deep-hit" "$work/buildcoord-stats-argv-deep.err" \
   1397     "deep_hits=1"
   1398 contains "buildcoord-stats-argv-deep-no-run" "$work/buildcoord-stats-argv-deep.err" \
   1399     "recipes_run=0"
   1400 build_assert_ok buildcoord-stats-argv-change --stats //argv:echo -- stat-two
   1401 contains "buildcoord-stats-argv-change-run" "$work/buildcoord-stats-argv-change.err" \
   1402     "recipes_run=1"
   1403 contains "buildcoord-stats-argv-change-no-hit" "$work/buildcoord-stats-argv-change.err" \
   1404     "shallow_hits=0"
   1405 argv_stat_path=$(tree_path_from "$work/buildcoord-stats-argv-change.out")
   1406 contains "buildcoord-stats-argv-change-output" "$argv_stat_path/args.txt" \
   1407     "stat-two"
   1408 
   1409 build_assert_ok buildcoord-config-unset-cold --stats //cfg:probe
   1410 contains "buildcoord-config-unset-cold-run" \
   1411     "$work/buildcoord-config-unset-cold.err" "recipes_run=1"
   1412 cfg_unset_path=$(tree_path_from "$work/buildcoord-config-unset-cold.out")
   1413 contains "buildcoord-config-unset-cold-output" "$cfg_unset_path/mode.txt" \
   1414     "mode:"
   1415 build_assert_ok buildcoord-config-set-after-unset --stats --config mode=set \
   1416     //cfg:probe
   1417 contains "buildcoord-config-set-after-unset-run" \
   1418     "$work/buildcoord-config-set-after-unset.err" "recipes_run=1"
   1419 cfg_set_path=$(tree_path_from "$work/buildcoord-config-set-after-unset.out")
   1420 contains "buildcoord-config-set-after-unset-output" "$cfg_set_path/mode.txt" \
   1421     "mode:set"
   1422 build_assert_ok buildcoord-config-unset-restores-trace --stats //cfg:probe
   1423 contains "buildcoord-config-unset-restores-trace-hit" \
   1424     "$work/buildcoord-config-unset-restores-trace.err" "deep_hits=1"
   1425 contains "buildcoord-config-unset-restores-trace-no-run" \
   1426     "$work/buildcoord-config-unset-restores-trace.err" "recipes_run=0"
   1427 cfg_unset_again_path=$(tree_path_from \
   1428     "$work/buildcoord-config-unset-restores-trace.out")
   1429 contains "buildcoord-config-unset-restores-trace-output" \
   1430     "$cfg_unset_again_path/mode.txt" "mode:"
   1431 
   1432 build_assert_ok buildcoord-config-default-cold --stats //cfg:default
   1433 contains "buildcoord-config-default-cold-run" \
   1434     "$work/buildcoord-config-default-cold.err" "recipes_run=1"
   1435 cfg_default_cold_path=$(tree_path_from "$work/buildcoord-config-default-cold.out")
   1436 contains "buildcoord-config-default-cold-output" \
   1437     "$cfg_default_cold_path/default.txt" "default:fallback"
   1438 build_assert_ok buildcoord-config-default-absent-hit --stats //cfg:default
   1439 contains "buildcoord-config-default-absent-hit-deep" \
   1440     "$work/buildcoord-config-default-absent-hit.err" "deep_hits=1"
   1441 contains "buildcoord-config-default-absent-hit-no-run" \
   1442     "$work/buildcoord-config-default-absent-hit.err" "recipes_run=0"
   1443 build_assert_ok buildcoord-config-default-present-fallback --stats \
   1444     --config missing-default=fallback //cfg:default
   1445 contains "buildcoord-config-default-present-fallback-run" \
   1446     "$work/buildcoord-config-default-present-fallback.err" "recipes_run=1"
   1447 cfg_default_fallback_path=$(tree_path_from \
   1448     "$work/buildcoord-config-default-present-fallback.out")
   1449 contains "buildcoord-config-default-present-fallback-output" \
   1450     "$cfg_default_fallback_path/default.txt" "default:fallback"
   1451 build_assert_ok buildcoord-config-default-present-other --stats \
   1452     --config missing-default=other //cfg:default
   1453 contains "buildcoord-config-default-present-other-run" \
   1454     "$work/buildcoord-config-default-present-other.err" "recipes_run=1"
   1455 cfg_default_other_path=$(tree_path_from \
   1456     "$work/buildcoord-config-default-present-other.out")
   1457 contains "buildcoord-config-default-present-other-output" \
   1458     "$cfg_default_other_path/default.txt" "default:other"
   1459 
   1460 build_assert_ok buildcoord-client-formats //client:formats
   1461 client_formats_path=$(tree_path_from "$work/buildcoord-client-formats.out")
   1462 contains "buildcoord-config-get-default" "$client_formats_path/default.txt" \
   1463     "fallback"
   1464 if [ ! -s "$client_formats_path/optional.txt" ]; then
   1465     ok "buildcoord-source-optional-absent"
   1466 else
   1467     printf 'optional output was not empty\n' > "$work/source-optional.diag"
   1468     not_ok "buildcoord-source-optional-absent" "$work/source-optional.diag"
   1469 fi
   1470 source_fmt_id=$(first_field_from "$client_formats_path/source.txt")
   1471 source_fmt_path=$(second_field_from "$client_formats_path/source.txt")
   1472 if [ ${#source_fmt_id} -eq 64 ] && [ -f "$source_fmt_path" ]; then
   1473     ok "buildcoord-source-format-id-path"
   1474 else
   1475     printf 'id=%s\npath=%s\n' "$source_fmt_id" "$source_fmt_path" \
   1476         > "$work/source-format.diag"
   1477     not_ok "buildcoord-source-format-id-path" "$work/source-format.diag"
   1478 fi
   1479 need_fmt_id=$(first_field_from "$client_formats_path/need.txt")
   1480 need_fmt_path=$(second_field_from "$client_formats_path/need.txt")
   1481 if [ ${#need_fmt_id} -eq 64 ] && [ -d "$need_fmt_path" ]; then
   1482     ok "buildcoord-need-format-id-path"
   1483 else
   1484     printf 'id=%s\npath=%s\n' "$need_fmt_id" "$need_fmt_path" \
   1485         > "$work/need-format.diag"
   1486     not_ok "buildcoord-need-format-id-path" "$work/need-format.diag"
   1487 fi
   1488 contains "buildcoord-need-format-output" "$need_fmt_path/args.txt" \
   1489     "format-arg"
   1490 await_fmt_id=$(first_field_from "$client_formats_path/await.txt")
   1491 await_fmt_path=$(second_field_from "$client_formats_path/await.txt")
   1492 if [ ${#await_fmt_id} -eq 64 ] && [ -d "$await_fmt_path" ]; then
   1493     ok "buildcoord-need-await-format-id-path"
   1494 else
   1495     printf 'id=%s\npath=%s\n' "$await_fmt_id" "$await_fmt_path" \
   1496         > "$work/await-format.diag"
   1497     not_ok "buildcoord-need-await-format-id-path" "$work/await-format.diag"
   1498 fi
   1499 contains "buildcoord-need-await-format-output" "$await_fmt_path/args.txt" \
   1500     "format-arg"
   1501 
   1502 build_assert_ok buildcoord-exports-provider --stats //exports:provider
   1503 exports_provider_path=$(tree_path_from "$work/buildcoord-exports-provider.out")
   1504 contains "buildcoord-exports-file-created" \
   1505     "$exports_provider_path/.kit/exports" "kit-build-exports 1"
   1506 contains "buildcoord-exports-cflags-stored" \
   1507     "$exports_provider_path/.kit/exports" "DPROVIDER=1"
   1508 
   1509 build_assert_ok buildcoord-exports-consumer --stats //exports:consumer
   1510 exports_consumer_path=$(tree_path_from "$work/buildcoord-exports-consumer.out")
   1511 contains "buildcoord-export-get-cflags" \
   1512     "$exports_consumer_path/cflags.txt" "Iinclude"
   1513 contains "buildcoord-export-get-libs" \
   1514     "$exports_consumer_path/libs.txt" "lprovider"
   1515 contains "buildcoord-export-collect-provider-first" \
   1516     "$exports_consumer_path/collect.txt" "Iinclude"
   1517 contains "buildcoord-export-collect-other-second" \
   1518     "$exports_consumer_path/collect.txt" "Iother"
   1519 
   1520 cat > "$ws/recipes/exports_provider.sh" <<'EOF'
   1521 #!/bin/sh
   1522 set -eu
   1523 mkdir -p "$KIT_BUILD_OUT"
   1524 "$KIT" build export-set cflags -- -Iinclude -DPROVIDER=2
   1525 "$KIT" build export-set libs -- -Llib -lprovider
   1526 printf 'provider-v2\n' > "$KIT_BUILD_OUT/provider.txt"
   1527 EOF
   1528 chmod +x "$ws/recipes/exports_provider.sh"
   1529 build_assert_ok buildcoord-exports-provider-change-invalidates-consumer \
   1530     --stats //exports:consumer
   1531 contains "buildcoord-exports-consumer-reruns-on-provider-tree-change" \
   1532     "$work/buildcoord-exports-provider-change-invalidates-consumer.err" \
   1533     "recipes_run="
   1534 exports_consumer_v2_path=$(tree_path_from \
   1535     "$work/buildcoord-exports-provider-change-invalidates-consumer.out")
   1536 contains "buildcoord-export-get-cflags-updated" \
   1537     "$exports_consumer_v2_path/cflags.txt" "DPROVIDER=2"
   1538 
   1539 build_assert_ok buildcoord-defn-v1 --stats //defn:probe
   1540 contains "buildcoord-defn-v1-run" "$work/buildcoord-defn-v1.err" \
   1541     "recipes_run=1"
   1542 defn_v1_path=$(tree_path_from "$work/buildcoord-defn-v1.out")
   1543 contains "buildcoord-defn-v1-output" "$defn_v1_path/defn.txt" "defn:v1"
   1544 sed 's|recipe //recipes/defn_v1.sh|recipe //recipes/defn_same.sh|' \
   1545     "$ws/defn/BUILD.kit" > "$ws/defn/BUILD.next"
   1546 mv "$ws/defn/BUILD.next" "$ws/defn/BUILD.kit"
   1547 build_assert_ok buildcoord-defn-same-content --stats //defn:probe
   1548 contains "buildcoord-defn-same-content-hit" \
   1549     "$work/buildcoord-defn-same-content.err" "deep_hits=1"
   1550 contains "buildcoord-defn-same-content-no-run" \
   1551     "$work/buildcoord-defn-same-content.err" "recipes_run=0"
   1552 sed 's|recipe //recipes/defn_same.sh|recipe //recipes/defn_v2.sh|' \
   1553     "$ws/defn/BUILD.kit" > "$ws/defn/BUILD.next"
   1554 mv "$ws/defn/BUILD.next" "$ws/defn/BUILD.kit"
   1555 build_assert_ok buildcoord-defn-different-content --stats //defn:probe
   1556 contains "buildcoord-defn-different-content-run" \
   1557     "$work/buildcoord-defn-different-content.err" "recipes_run=1"
   1558 defn_v2_path=$(tree_path_from "$work/buildcoord-defn-different-content.out")
   1559 contains "buildcoord-defn-different-content-output" "$defn_v2_path/defn.txt" \
   1560     "defn:v2"
   1561 sed 's|recipe //recipes/defn_unused_v1.sh|recipe //recipes/defn_unused_v2.sh|' \
   1562     "$ws/defn/BUILD.kit" > "$ws/defn/BUILD.next"
   1563 mv "$ws/defn/BUILD.next" "$ws/defn/BUILD.kit"
   1564 build_assert_ok buildcoord-defn-unrelated-stanza --stats //defn:probe
   1565 contains "buildcoord-defn-unrelated-stanza-hit" \
   1566     "$work/buildcoord-defn-unrelated-stanza.err" "deep_hits=1"
   1567 contains "buildcoord-defn-unrelated-stanza-no-run" \
   1568     "$work/buildcoord-defn-unrelated-stanza.err" "recipes_run=0"
   1569 
   1570 build_assert_ok buildcoord-material-cold --stats //material:probe
   1571 contains "buildcoord-material-cold-run" "$work/buildcoord-material-cold.err" \
   1572     "recipes_run=1"
   1573 material_id=$(tree_id_from "$work/buildcoord-material-cold.out")
   1574 material_cache=$(cache_path_from "$material_id")
   1575 rm -rf "$material_cache"
   1576 build_assert_ok buildcoord-material-restores-from-cas --stats //material:probe
   1577 contains "buildcoord-material-restores-from-cas-hit" \
   1578     "$work/buildcoord-material-restores-from-cas.err" "deep_hits=1"
   1579 contains "buildcoord-material-restores-from-cas-no-run" \
   1580     "$work/buildcoord-material-restores-from-cas.err" "recipes_run=0"
   1581 contains "buildcoord-material-restores-from-cas-no-miss" \
   1582     "$work/buildcoord-material-restores-from-cas.err" "materialize_misses=0"
   1583 material_cache=$(cache_path_from "$material_id")
   1584 material_tree=$(cas_tree_path_from "$material_id")
   1585 rm -rf "$material_cache"
   1586 rm -f "$material_tree"
   1587 build_assert_ok buildcoord-material-missing-bytes-reruns --stats //material:probe
   1588 contains "buildcoord-material-missing-bytes-reruns-run" \
   1589     "$work/buildcoord-material-missing-bytes-reruns.err" "recipes_run=1"
   1590 contains "buildcoord-material-missing-bytes-reruns-miss" \
   1591     "$work/buildcoord-material-missing-bytes-reruns.err" "materialize_misses="
   1592 
   1593 build_assert_ok buildcoord-storage-record-cold --stats //storage:probe
   1594 contains "buildcoord-storage-record-cold-run" \
   1595     "$work/buildcoord-storage-record-cold.err" "recipes_run=1"
   1596 storage_record=$(target_record_for "//storage:probe")
   1597 if [ -n "$storage_record" ] && [ -f "$storage_record" ]; then
   1598     ok "buildcoord-storage-record-found"
   1599     printf 'not a kit-build-record\n' > "$storage_record"
   1600 else
   1601     printf 'record=%s\n' "$storage_record" > "$work/storage-record.diag"
   1602     not_ok "buildcoord-storage-record-found" "$work/storage-record.diag"
   1603 fi
   1604 build_assert_ok buildcoord-storage-corrupt-record-reruns --stats //storage:probe
   1605 contains "buildcoord-storage-corrupt-record-reruns-run" \
   1606     "$work/buildcoord-storage-corrupt-record-reruns.err" "recipes_run=1"
   1607 
   1608 find "$store/build/trace" -type f -exec grep -l "target //storage:probe" {} + \
   1609     > "$work/storage-traces.txt" 2> "$work/storage-traces.err"
   1610 if [ -s "$work/storage-traces.txt" ]; then
   1611     ok "buildcoord-storage-traces-found"
   1612     while IFS= read -r trace_file; do
   1613         printf 'not a kit-build-trace\n' > "$trace_file"
   1614     done < "$work/storage-traces.txt"
   1615 else
   1616     not_ok "buildcoord-storage-traces-found" "$work/storage-traces.err"
   1617 fi
   1618 build_assert_ok buildcoord-storage-malformed-trace-reruns --stats //storage:probe
   1619 contains "buildcoord-storage-malformed-trace-reruns-run" \
   1620     "$work/buildcoord-storage-malformed-trace-reruns.err" "recipes_run=1"
   1621 
   1622 build_assert_ok buildcoord-globset-cold --stats //globset:probe
   1623 contains "buildcoord-globset-cold-run" "$work/buildcoord-globset-cold.err" \
   1624     "recipes_run=1"
   1625 globset_one_path=$(tree_path_from "$work/buildcoord-globset-cold.out")
   1626 contains "buildcoord-globset-cold-output" "$globset_one_path/files.txt" "one"
   1627 cat > "$ws/src/globset/two.txt" <<'EOF'
   1628 two
   1629 EOF
   1630 build_assert_ok buildcoord-globset-add --stats //globset:probe
   1631 contains "buildcoord-globset-add-run" "$work/buildcoord-globset-add.err" \
   1632     "recipes_run=1"
   1633 globset_two_path=$(tree_path_from "$work/buildcoord-globset-add.out")
   1634 contains "buildcoord-globset-add-one" "$globset_two_path/files.txt" "one"
   1635 contains "buildcoord-globset-add-two" "$globset_two_path/files.txt" "two"
   1636 rm -f "$ws/src/globset/one.txt"
   1637 build_assert_ok buildcoord-globset-remove --stats //globset:probe
   1638 contains "buildcoord-globset-remove-run" "$work/buildcoord-globset-remove.err" \
   1639     "recipes_run=1"
   1640 globset_remove_path=$(tree_path_from "$work/buildcoord-globset-remove.out")
   1641 contains "buildcoord-globset-remove-output" "$globset_remove_path/files.txt" \
   1642     "two"
   1643 
   1644 build_assert_ok buildcoord-globstar-cold --stats //globstar:probe
   1645 contains "buildcoord-globstar-cold-run" "$work/buildcoord-globstar-cold.err" \
   1646     "recipes_run=1"
   1647 globstar_path=$(tree_path_from "$work/buildcoord-globstar-cold.out")
   1648 contains "buildcoord-globstar-root" "$globstar_path/all.txt" \
   1649     "src/tree/root.txt"
   1650 contains "buildcoord-globstar-mid" "$globstar_path/all.txt" \
   1651     "src/tree/nested/mid.txt"
   1652 contains "buildcoord-globstar-leaf" "$globstar_path/all.txt" \
   1653     "src/tree/nested/deeper/leaf.txt"
   1654 contains "buildcoord-globstar-specific-leaf" "$globstar_path/leaf.txt" \
   1655     "src/tree/nested/deeper/leaf.txt"
   1656 contains "buildcoord-globstar-zero-depth" "$globstar_path/root.txt" \
   1657     "src/tree/root.txt"
   1658 build_assert_ok buildcoord-globstar-deep --stats //globstar:probe
   1659 contains "buildcoord-globstar-deep-hit" "$work/buildcoord-globstar-deep.err" \
   1660     "deep_hits=1"
   1661 contains "buildcoord-globstar-deep-no-run" "$work/buildcoord-globstar-deep.err" \
   1662     "recipes_run=0"
   1663 
   1664 test_assert_pass buildcoord-test-pass-cold --stats //test:pass
   1665 contains "buildcoord-test-pass-cold-run" "$work/buildcoord-test-pass-cold.err" \
   1666     "test_runs=1"
   1667 test_pass_path=$(test_tree_path_from "$work/buildcoord-test-pass-cold.out")
   1668 contains "buildcoord-test-pass-artifact" "$test_pass_path/result.txt" \
   1669     "pass-artifact"
   1670 contains "buildcoord-test-pass-stdout" "$test_pass_path/stdout" \
   1671     "pass-stdout:1"
   1672 contains "buildcoord-test-pass-stderr" "$test_pass_path/stderr" \
   1673     "pass-stderr:1"
   1674 
   1675 test_assert_pass buildcoord-test-pass-deep --stats //test:pass
   1676 contains "buildcoord-test-pass-deep-hit" "$work/buildcoord-test-pass-deep.err" \
   1677     "test_cache_hits=1"
   1678 contains "buildcoord-test-pass-deep-no-run" \
   1679     "$work/buildcoord-test-pass-deep.err" "test_runs=0"
   1680 contains "buildcoord-test-pass-deep-count" "$ws/test-pass.count" "1"
   1681 
   1682 test_assert_pass buildcoord-test-parent-cold --stats //test:parent
   1683 contains "buildcoord-test-parent-cold-run" \
   1684     "$work/buildcoord-test-parent-cold.err" "test_runs=1"
   1685 cat > "$ws/src/noop.txt" <<'EOF'
   1686 third
   1687 EOF
   1688 test_assert_pass buildcoord-test-parent-shallow --stats //test:parent
   1689 contains "buildcoord-test-parent-shallow-hit" \
   1690     "$work/buildcoord-test-parent-shallow.err" "test_cache_hits=1"
   1691 contains "buildcoord-test-parent-shallow-no-run" \
   1692     "$work/buildcoord-test-parent-shallow.err" "test_runs=0"
   1693 contains "buildcoord-test-parent-shallow-count" "$ws/test-parent.count" "1"
   1694 
   1695 test_assert_fail_result buildcoord-test-fail-first --stats //test:fail
   1696 test_fail_path=$(test_tree_path_from "$work/buildcoord-test-fail-first.out")
   1697 contains "buildcoord-test-fail-artifact" "$test_fail_path/fail.txt" \
   1698     "fail-artifact:1"
   1699 contains "buildcoord-test-fail-stdout" "$test_fail_path/stdout" \
   1700     "fail-stdout:1"
   1701 contains "buildcoord-test-fail-stderr" "$test_fail_path/stderr" \
   1702     "fail-stderr:1"
   1703 contains "buildcoord-test-fail-stats" "$work/buildcoord-test-fail-first.err" \
   1704     "test_failures=1"
   1705 test_assert_fail_result buildcoord-test-fail-reruns --stats //test:fail
   1706 contains "buildcoord-test-fail-rerun-count" "$ws/test-fail.count" "2"
   1707 contains "buildcoord-test-fail-rerun-no-cache" \
   1708     "$work/buildcoord-test-fail-reruns.err" "test_cache_hits=0"
   1709 cat > "$ws/src/test_fail_mode" <<'EOF'
   1710 pass
   1711 EOF
   1712 test_assert_pass buildcoord-test-fail-then-pass --stats //test:fail
   1713 contains "buildcoord-test-fail-pass-run" \
   1714     "$work/buildcoord-test-fail-then-pass.err" "test_runs=1"
   1715 test_assert_pass buildcoord-test-fail-pass-cached --stats //test:fail
   1716 contains "buildcoord-test-fail-pass-cached-hit" \
   1717     "$work/buildcoord-test-fail-pass-cached.err" "test_cache_hits=1"
   1718 
   1719 build_assert_ok buildcoord-test-build-record-cold --stats //test:separate
   1720 cat > "$ws/test-pass.count" <<'EOF'
   1721 0
   1722 EOF
   1723 test_assert_pass buildcoord-test-record-separate --stats //test:separate
   1724 contains "buildcoord-test-record-separate-runs" \
   1725     "$work/buildcoord-test-record-separate.err" "test_runs=1"
   1726 
   1727 test_assert_pass buildcoord-test-nondet-cold //test:nondet
   1728 run_fail "buildcoord-test-verify-mismatch" \
   1729     "$KIT" build test --store "$store" --root "$ws" --def BUILD.kit \
   1730         --config "env.KIT=$KIT" --verify //test:nondet
   1731 contains "buildcoord-test-verify-diag" \
   1732     "$work/buildcoord-test-verify-mismatch.err" "verify mismatch"
   1733 
   1734 run_fail "buildcoord-failure-first-fails" \
   1735     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
   1736         --config "env.KIT=$KIT" //fail:probe
   1737 run_fail "buildcoord-failure-second-reruns" \
   1738     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
   1739         --config "env.KIT=$KIT" //fail:probe
   1740 contains "buildcoord-failure-second-count" "$ws/fail.count" "2"
   1741 cat > "$ws/recipes/fail.sh" <<'EOF'
   1742 #!/bin/sh
   1743 set -eu
   1744 mkdir -p "$KIT_BUILD_OUT"
   1745 printf 'fixed\n' > "$KIT_BUILD_OUT/fixed.txt"
   1746 EOF
   1747 chmod +x "$ws/recipes/fail.sh"
   1748 build_assert_ok buildcoord-failure-fixed-runs --stats //fail:probe
   1749 contains "buildcoord-failure-fixed-run" "$work/buildcoord-failure-fixed-runs.err" \
   1750     "recipes_run=1"
   1751 fail_fixed_path=$(tree_path_from "$work/buildcoord-failure-fixed-runs.out")
   1752 contains "buildcoord-failure-fixed-output" "$fail_fixed_path/fixed.txt" \
   1753     "fixed"
   1754 
   1755 fetch_id=$("$KIT" hash -a blake2b "$ws/remote/fetch.txt" | awk '{print $1}')
   1756 build_assert_ok buildcoord-fetch-mirror --stats --config env.PATH=/no/such \
   1757     //fetch:blob -- "$fetch_id" \
   1758     "file://$work/missing-fetch.txt" "file://$ws/remote/fetch.txt"
   1759 contains "buildcoord-fetch-mirror-run" "$work/buildcoord-fetch-mirror.err" \
   1760     "recipes_run=1"
   1761 fetch_path=$(tree_path_from "$work/buildcoord-fetch-mirror.out")
   1762 contains "buildcoord-fetch-mirror-output" "$fetch_path/fetched.txt" \
   1763     "remote:v1"
   1764 find "$store/build/trace" -type f -exec grep -l "$fetch_id" {} + \
   1765     > "$work/fetch-traces.txt" 2> "$work/fetch-traces.err"
   1766 if [ -s "$work/fetch-traces.txt" ]; then
   1767     ok "buildcoord-fetch-logged-in-trace"
   1768 else
   1769     not_ok "buildcoord-fetch-logged-in-trace" "$work/fetch-traces.err"
   1770 fi
   1771 build_assert_ok buildcoord-fetch-cas-hit-bad-url --stats \
   1772     --config env.PATH=/no/such //fetch:blob -- \
   1773     "$fetch_id" "file://$work/still-missing-fetch.txt"
   1774 contains "buildcoord-fetch-cas-hit-rerun" \
   1775     "$work/buildcoord-fetch-cas-hit-bad-url.err" "recipes_run=1"
   1776 fetch_hit_path=$(tree_path_from "$work/buildcoord-fetch-cas-hit-bad-url.out")
   1777 contains "buildcoord-fetch-cas-hit-output" "$fetch_hit_path/fetched.txt" \
   1778     "remote:v1"
   1779 build_assert_ok buildcoord-fetch-format --stats --config env.PATH=/no/such \
   1780     //fetch:format -- "$fetch_id" "file://$ws/remote/fetch.txt"
   1781 fetch_format_path=$(tree_path_from "$work/buildcoord-fetch-format.out")
   1782 fetch_format_id=$(first_field_from "$fetch_format_path/fetch-info.txt")
   1783 fetch_format_file=$(second_field_from "$fetch_format_path/fetch-info.txt")
   1784 if [ "$fetch_format_id" = "$fetch_id" ] && [ -f "$fetch_format_file" ]; then
   1785     ok "buildcoord-fetch-format-id-path"
   1786 else
   1787     printf 'want=%s\ngot=%s\npath=%s\n' "$fetch_id" "$fetch_format_id" \
   1788         "$fetch_format_file" > "$work/fetch-format.diag"
   1789     not_ok "buildcoord-fetch-format-id-path" "$work/fetch-format.diag"
   1790 fi
   1791 contains "buildcoord-fetch-format-output" "$fetch_format_path/fetched.txt" \
   1792     "remote:v1"
   1793 
   1794 run_fail "buildcoord-cycle-self-fails" \
   1795     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
   1796         --config "env.KIT=$KIT" //cycle:self
   1797 contains "buildcoord-cycle-self-diag" "$work/buildcoord-cycle-self-fails.err" \
   1798     "cycle"
   1799 run_fail "buildcoord-cycle-indirect-fails" \
   1800     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
   1801         --config "env.KIT=$KIT" //cycle:a
   1802 contains "buildcoord-cycle-indirect-diag" \
   1803     "$work/buildcoord-cycle-indirect-fails.err" "cycle"
   1804 
   1805 build_assert_ok buildcoord-async-unawaited-cold --stats //async:unawaited
   1806 contains "buildcoord-async-unawaited-cold-stats" \
   1807     "$work/buildcoord-async-unawaited-cold.err" "recipes_run="
   1808 async_unawaited_path=$(tree_path_from "$work/buildcoord-async-unawaited-cold.out")
   1809 contains "buildcoord-async-unawaited-output" \
   1810     "$async_unawaited_path/unawaited.txt" "unawaited"
   1811 find "$store/build/trace" -type f -exec grep -l "target //async:unawaited" {} + \
   1812     > "$work/async-unawaited-traces.txt" 2> "$work/async-unawaited-traces.err"
   1813 if [ -s "$work/async-unawaited-traces.txt" ]; then
   1814     xargs grep -h "//async:dep" < "$work/async-unawaited-traces.txt" \
   1815         > "$work/async-unawaited-deps.txt" 2> "$work/async-unawaited-deps.err" || true
   1816     if [ ! -s "$work/async-unawaited-deps.txt" ]; then
   1817         ok "buildcoord-async-unawaited-not-recorded"
   1818     else
   1819         not_ok "buildcoord-async-unawaited-not-recorded" \
   1820             "$work/async-unawaited-deps.txt"
   1821     fi
   1822 else
   1823     not_ok "buildcoord-async-unawaited-traces-found" \
   1824         "$work/async-unawaited-traces.err"
   1825 fi
   1826 cat > "$ws/recipes/async_dep.sh" <<'EOF'
   1827 #!/bin/sh
   1828 set -eu
   1829 mkdir -p "$KIT_BUILD_OUT"
   1830 printf 'async-dep:edited\n' > "$KIT_BUILD_OUT/dep.txt"
   1831 EOF
   1832 chmod +x "$ws/recipes/async_dep.sh"
   1833 build_assert_ok buildcoord-async-unawaited-dep-edit --stats //async:unawaited
   1834 contains "buildcoord-async-unawaited-dep-edit-hit" \
   1835     "$work/buildcoord-async-unawaited-dep-edit.err" "deep_hits=1"
   1836 contains "buildcoord-async-unawaited-dep-edit-no-run" \
   1837     "$work/buildcoord-async-unawaited-dep-edit.err" "recipes_run=0"
   1838 
   1839 export AMBIENT=leaked
   1840 build_assert_ok buildcoord-env-cold --stats --config env.DECLARED=one \
   1841     //env:probe
   1842 unset AMBIENT
   1843 env_one_path=$(tree_path_from "$work/buildcoord-env-cold.out")
   1844 contains "buildcoord-env-clean-ambient" "$env_one_path/env.txt" \
   1845     "ambient:unset"
   1846 contains "buildcoord-env-declared-visible" "$env_one_path/env.txt" \
   1847     "declared:one"
   1848 contains "buildcoord-env-target-repo" "$env_one_path/env.txt" "repo:"
   1849 contains "buildcoord-env-target-package" "$env_one_path/env.txt" \
   1850     "package:env"
   1851 contains "buildcoord-env-target-local" "$env_one_path/env.txt" "local:probe"
   1852 
   1853 unset MISSING_BUILDCOORD_ENV
   1854 run_fail "buildcoord-env-shorthand-unset-rejected" \
   1855     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
   1856         --env MISSING_BUILDCOORD_ENV --config "env.KIT=$KIT" //env:probe
   1857 contains "buildcoord-env-shorthand-unset-rejected-diag" \
   1858     "$work/buildcoord-env-shorthand-unset-rejected.err" "MISSING_BUILDCOORD_ENV"
   1859 
   1860 run_fail "buildcoord-env-config-unset-rejected" \
   1861     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
   1862         --config env.MISSING_BUILDCOORD_ENV --config "env.KIT=$KIT" //env:probe
   1863 contains "buildcoord-env-config-unset-rejected-diag" \
   1864     "$work/buildcoord-env-config-unset-rejected.err" "MISSING_BUILDCOORD_ENV"
   1865 
   1866 # Spec checks below are intentionally red until these BUILD_COORDINATOR.md
   1867 # promises are implemented.
   1868 build_assert_ok buildcoord-spec-env-change-invalidates --stats \
   1869     --config env.DECLARED=two //env:probe
   1870 contains "buildcoord-spec-env-change-reruns" \
   1871     "$work/buildcoord-spec-env-change-invalidates.err" "recipes_run=1"
   1872 env_two_path=$(tree_path_from "$work/buildcoord-spec-env-change-invalidates.out")
   1873 contains "buildcoord-spec-env-change-output" "$env_two_path/env.txt" \
   1874     "declared:two"
   1875 
   1876 build_assert_ok buildcoord-env-shorthand-set --stats \
   1877     --env DECLARED=three //env:probe
   1878 env_three_path=$(tree_path_from "$work/buildcoord-env-shorthand-set.out")
   1879 contains "buildcoord-env-shorthand-set-output" "$env_three_path/env.txt" \
   1880     "declared:three"
   1881 
   1882 export DECLARED=from-current-env
   1883 build_assert_ok buildcoord-env-config-passthrough --stats \
   1884     --config env.DECLARED //env:probe
   1885 unset DECLARED
   1886 env_current_path=$(tree_path_from "$work/buildcoord-env-config-passthrough.out")
   1887 contains "buildcoord-env-config-passthrough-output" \
   1888     "$env_current_path/env.txt" "declared:from-current-env"
   1889 
   1890 build_assert_ok buildcoord-spec-nondet-cold //nondet:counter
   1891 run_fail "buildcoord-spec-verify-reruns-cache-hit" \
   1892     "$KIT" build --store "$store" --root "$ws" --def BUILD.kit \
   1893         --config "env.KIT=$KIT" --verify //nondet:counter
   1894 
   1895 build_assert_ok buildcoord-spec-need-submit-await //submit:probe
   1896 submit_path=$(tree_path_from "$work/buildcoord-spec-need-submit-await.out")
   1897 if [ -n "$submit_path" ] && [ -f "$submit_path/submit.txt" ]; then
   1898     contains "buildcoord-spec-need-submit-output" "$submit_path/submit.txt" \
   1899         "via-submit"
   1900     contains "buildcoord-spec-need-submit-await-idempotent" \
   1901         "$submit_path/submit-again.txt" "via-submit"
   1902 fi
   1903 
   1904 kit_summary "buildcoord"
   1905 kit_exit