Nothing measured what the tests reach. scripts/coverage.sh runs the cargo tests under cargo-llvm-cov in the ipx-coverage image (Dockerfile.coverage, built by build-image.sh coverage), in a container held to the image builder's 6 GB and six threads, one crate at a time, with the same room and load checks: an instrumented build rebuilds every dependency, the kind of build that took Tower down on 2026-11-04. The first run stayed under load 8 with 11 GB free; 69% of lines. web.rs and daemon.rs read low because the browser suite drives them against a daemon that is not instrumented. npm run coverage:page runs the browser suite on a build of the page (IPX_COVERAGE=1) whose script keeps a source map to each web/src file: web/concat-map.mts maps the joined files line by line and swc takes it as its input map. Each test's page records V8's coverage (tests/ui/coverage.ts, which the specs now take test and expect from), and monocart-coverage-reports writes it file by file: 73% of lines. build.mjs requires the map helper only for that build, since Dockerfile.web's Node does not run TypeScript, and not with a top-level await, which stopped the CommonJS tests requiring build.mjs. The offline tests move to offline.spec.ts, in TypeScript, and stand alone (they add their feed and set the read state they need), with what #391 found untested: another account signing in clears what was kept, a position saved offline waits and is sent, and pictures past the budget go oldest first (keepPictures takes the budget, and trims whether or not anything new came). The fixture JPEGs were a few bytes no browser could draw; they are real now, and the artwork test checks one draws. tsconfig.tools.json type-checks the tests' and build's TypeScript, in npm run typecheck. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
2.1 KiB
Bash
50 lines
2.1 KiB
Bash
#!/bin/sh
|
|
# Build and push one service's image, inside limits Tower can afford.
|
|
#
|
|
# sh scripts/build-image.sh ipx|directory|web|coverage
|
|
#
|
|
# On 2026-11-04 a plain `docker buildx build` of ipx (its dependencies' cache layer invalidated
|
|
# by a Cargo.toml change) rebuilt everything in release on all twelve threads with 5 GB free and
|
|
# no swap; Tower thrashed for three hours with every core pegged and had to be rebooted. So the
|
|
# build runs in a BuildKit container under a cgroup cap: past the memory cap the build is killed,
|
|
# it does not take production down with it. And it does not start without room for that cap.
|
|
set -eu
|
|
|
|
MEM=6g # the builder's memory cap (Tower has no swap to spill into)
|
|
CPUS=0-5 # six of twelve threads; cargo inside sees six and runs six jobs
|
|
NEED_KB=$((9 * 1024 * 1024)) # the cap plus 3 GB for everything else
|
|
MAX_LOAD=12
|
|
BUILDER=ipx-capped
|
|
|
|
case "${1:-}" in
|
|
ipx) FILE=Dockerfile; IMAGE=ipx ;;
|
|
directory) FILE=Dockerfile.directory; IMAGE=ipx-directory ;;
|
|
web) FILE=Dockerfile.web; IMAGE=ipx-web ;;
|
|
# Not a service: what scripts/coverage.sh runs the Rust tests in (#390).
|
|
coverage) FILE=Dockerfile.coverage; IMAGE=ipx-coverage ;;
|
|
*) echo "usage: $0 ipx|directory|web|coverage" >&2; exit 2 ;;
|
|
esac
|
|
cd "$(dirname "$0")/.."
|
|
|
|
avail=$(awk '/^MemAvailable:/ {print $2}' /proc/meminfo)
|
|
load=$(cut -d' ' -f1 /proc/loadavg)
|
|
echo "MemAvailable $((avail / 1024)) MB, load $load"
|
|
if [ "$avail" -lt "$NEED_KB" ]; then
|
|
echo "refusing: under $((NEED_KB / 1024 / 1024)) GB available. Wait, or find what is using it." >&2
|
|
exit 1
|
|
fi
|
|
if awk -v l="$load" -v m="$MAX_LOAD" 'BEGIN { exit !(l > m) }'; then
|
|
echo "refusing: load over $MAX_LOAD. Wait for it to come down." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Made once; buildx starts its container again when needed, after a reboot too.
|
|
if ! docker buildx inspect "$BUILDER" >/dev/null 2>&1; then
|
|
docker buildx create --name "$BUILDER" --driver docker-container \
|
|
--driver-opt "memory=$MEM,cpuset-cpus=$CPUS" \
|
|
--buildkitd-config scripts/buildkitd.toml >/dev/null
|
|
fi
|
|
|
|
exec docker buildx build --builder "$BUILDER" -f "$FILE" \
|
|
--tag "192.168.1.130:5000/$IMAGE:latest" --push .
|