зеркало из https://github.com/mozilla/sccache.git
351 строка
9.2 KiB
Bash
Executable File
351 строка
9.2 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# This script contains CI tests for FreeBSD, testing
|
|
#
|
|
# - cargo build & cargo test
|
|
# - configure and start sccache-dist and scheduler
|
|
# - test distributed compile
|
|
# - test that the cache is used
|
|
#
|
|
# It creates a temporary test pool backed by a
|
|
# file (using mdconfig) and does a full configuration
|
|
# of pot.
|
|
#
|
|
# After running it copies the sccache log file into
|
|
# the repo's root directory. It also does a full
|
|
# cleanup (removal of all temporary files, test pool
|
|
# etc.) after each run. This can be prevented by
|
|
# setting FREEBSD_CI_NOCLEAN in the environment:
|
|
#
|
|
# FREEBSD_CI_NOCLEAN=1 scripts/freebsd-ci-test.sh
|
|
#
|
|
# When running in a loop, time and bandwidth can be
|
|
# saved by placing FreeBSD distribution files in
|
|
# $HOME/.potcache
|
|
#
|
|
# mkdir $HOME/.potcache
|
|
# fetch -o $HOME/.potcache/14.1-RELEASE_base.txz \
|
|
# https://ftp.freebsd.org/pub/FreeBSD/releases/amd64/14.1-RELEASE/base.txz
|
|
#
|
|
# This script can be run from a github action. When run locally, make
|
|
# sure to install the required packages:
|
|
#
|
|
# pkg install -y ca-root-nss curl gmake gtar pot sudo
|
|
#
|
|
|
|
# shellcheck disable=SC3040
|
|
set -eo pipefail
|
|
|
|
init()
|
|
{
|
|
base=$(realpath "$(dirname "$0")"/..)
|
|
OS_VERSION="$(freebsd-version | awk -F- '{print $1}')"
|
|
PUB_INTF="$(netstat -4rn | grep default | awk '{ print $4}')"
|
|
TEST_TMPDIR=$(mktemp -d "/tmp/sccache_freebsd.XXXXXXX") || exit 1
|
|
chmod g+r "$TEST_TMPDIR"
|
|
export XDG_CONFIG_HOME="$TEST_TMPDIR/.config"
|
|
mkdir -p "$XDG_CONFIG_HOME"
|
|
export SCCACHE_DIR="$TEST_TMPDIR/.cache"
|
|
killall sccache 2>/dev/null || true
|
|
killall sccache-dist 2>/dev/null || true
|
|
export RUST_LOG_STYLE=never
|
|
}
|
|
|
|
output_env_info()
|
|
{
|
|
echo "## user"
|
|
whoami
|
|
echo "## environment"
|
|
env | sort
|
|
echo "## network"
|
|
ifconfig
|
|
echo "## tooling info"
|
|
cargo -V
|
|
rustc -V
|
|
curl --version
|
|
# See https://github.com/bsdpot/pot/pull/253
|
|
pot version || true
|
|
gtar --version
|
|
echo "## installed packages"
|
|
pkg info
|
|
}
|
|
|
|
build_and_test_project()
|
|
{
|
|
echo "#### building sccache (cargo)"
|
|
cd "$base"
|
|
FAULT=0
|
|
export RUSTFLAGS="-C debuginfo=0"
|
|
cargo build --features "dist-client,dist-server" || FAULT=1
|
|
echo "#### testing sccache (cargo)"
|
|
cargo test --features "dist-client,dist-server" -- \
|
|
--test-threads 1 || FAULT=1
|
|
unset RUSTFLAGS
|
|
if [ "$FAULT" -eq 0 ]; then
|
|
# save build time by avoiding "cargo install"
|
|
cp -a target/debug/sccache target/debug/sccache-dist \
|
|
"$HOME/.cargo/bin/."
|
|
fi
|
|
if [ $FAULT -ne 0 ]; then return 1; fi
|
|
}
|
|
|
|
prepare_and_run_sccache_dist()
|
|
{
|
|
echo "#### preparing sccache-dist"
|
|
SECRET_KEY="$(sccache-dist auth generate-jwt-hs256-key)"
|
|
CLIENT_AUTH_KEY="$(sccache-dist auth generate-jwt-hs256-key)"
|
|
# create scheduler.conf
|
|
cat >"$TEST_TMPDIR"/scheduler.conf <<-EOF
|
|
public_addr = "127.0.0.1:10600"
|
|
[client_auth]
|
|
type = "token"
|
|
token = "$CLIENT_AUTH_KEY"
|
|
[server_auth]
|
|
type = "jwt_hs256"
|
|
secret_key = "$SECRET_KEY"
|
|
EOF
|
|
SERVER_TOKEN="$(sccache-dist auth generate-jwt-hs256-server-token \
|
|
--config="$TEST_TMPDIR"/scheduler.conf \
|
|
--server="127.0.0.1:10501")"
|
|
|
|
# Create server.conf
|
|
cat >"$TEST_TMPDIR"/server.conf <<-EOF
|
|
cache_dir = "$TEST_TMPDIR/toolchains"
|
|
public_addr = "127.0.0.1:10501"
|
|
scheduler_url = "http://127.0.0.1:10600"
|
|
[builder]
|
|
type = "pot"
|
|
pot_fs_root = "$TEST_TMPDIR/pot"
|
|
[scheduler_auth]
|
|
type = "jwt_token"
|
|
token = "$SERVER_TOKEN"
|
|
EOF
|
|
|
|
# create sccache client config
|
|
TC="$(rustup toolchain list | grep default | awk '{ print $1 }')"
|
|
RUSTC_PATH="$HOME/.rustup/toolchains/$TC/bin/rustc"
|
|
mkdir -p "$XDG_CONFIG_HOME/sccache"
|
|
cat >"$XDG_CONFIG_HOME/sccache/config" <<-EOF
|
|
[dist]
|
|
scheduler_url = "http://127.0.0.1:10600"
|
|
toolchain_cache_size = 5368709120
|
|
cache_dir = "$HOME/.cache/sccache-dist-client"
|
|
[dist.auth]
|
|
type = "token"
|
|
token = "$CLIENT_AUTH_KEY"
|
|
[[dist.toolchains]]
|
|
type = "path_override"
|
|
compiler_executable = "/usr/bin/cc"
|
|
archive = "$TEST_TMPDIR/empty.tar.gz"
|
|
archive_compiler_executable = "/usr/bin/cc"
|
|
[[dist.toolchains]]
|
|
type = "path_override"
|
|
compiler_executable = "$RUSTC_PATH"
|
|
archive = "$TEST_TMPDIR/rust-toolchain.tgz"
|
|
archive_compiler_executable = "$RUSTC_PATH"
|
|
EOF
|
|
|
|
echo "Creating toolchain tarballs"
|
|
gtar cvf - --files-from /dev/null | \
|
|
gzip -n >"$TEST_TMPDIR/empty.tar.gz"
|
|
gtar cf - --sort=name --mtime='2022-06-28 17:35Z' "$HOME/.rustup" | \
|
|
gzip -n >"$TEST_TMPDIR/rust-toolchain.tgz"
|
|
|
|
echo "Starting scheduler"
|
|
sccache-dist scheduler --config "$TEST_TMPDIR"/scheduler.conf
|
|
}
|
|
|
|
prepare_zpool()
|
|
{
|
|
echo "#### preparing zpool"
|
|
sudo dd if=/dev/zero of="$TEST_TMPDIR/zfs1" bs=1 count=1 seek=3G
|
|
MDUNIT=$(sudo mdconfig -a -n -t vnode -S 4096 -f "$TEST_TMPDIR/zfs1")
|
|
zdev="/dev/md$MDUNIT"
|
|
sudo zpool create -f potpool "$zdev"
|
|
}
|
|
|
|
prepare_pot()
|
|
{
|
|
echo "#### preparing pot"
|
|
sudo sysrc -f /usr/local/etc/pot/pot.conf POT_ZFS_ROOT=potpool/pot
|
|
sudo sysrc -f /usr/local/etc/pot/pot.conf POT_EXTIF="$PUB_INTF"
|
|
sudo sysrc -f /usr/local/etc/pot/pot.conf POT_TMP="$TEST_TMPDIR"
|
|
sudo sysrc -f /usr/local/etc/pot/pot.conf \
|
|
POT_FS_ROOT="$TEST_TMPDIR/pot"
|
|
sudo sysrc -f /usr/local/etc/pot/pot.conf POT_GROUP=wheel
|
|
sudo pot init -f ""
|
|
sudo pot version
|
|
sudo cp "$HOME"/.potcache/*.txz /var/cache/pot 2>/dev/null || true
|
|
sudo pot create -p sccache-template -N alias -i "lo0|127.0.0.2" \
|
|
-t single -b "$OS_VERSION"
|
|
sudo pot set-cmd -p sccache-template -c /usr/bin/true
|
|
sudo pot set-attr -p sccache-template -A no-rc-script -V YES
|
|
sudo pot snapshot -p sccache-template
|
|
}
|
|
|
|
start_build_server()
|
|
{
|
|
echo "#### starting build-server (as root)"
|
|
SCCACHE_DIST_LOG=debug RUST_LOG=info sudo \
|
|
"$HOME"/.cargo/bin/sccache-dist server \
|
|
--config "$TEST_TMPDIR"/server.conf &
|
|
}
|
|
|
|
wait_for_build_server()
|
|
{
|
|
echo "#### waiting for build server to become available"
|
|
count=0
|
|
while [ "$(sockstat -q4l -p 10501 | wc -l | xargs)" -eq "0" ]; do
|
|
count=$(( count + 1 ))
|
|
if [ $count -gt 60 ]; then
|
|
2>&1 echo "Build server did not become available"
|
|
return 1
|
|
fi
|
|
sleep 5
|
|
done
|
|
}
|
|
|
|
create_build_test_project()
|
|
{
|
|
echo "#### create and build test project"
|
|
cd "$TEST_TMPDIR"
|
|
cargo init buildtest
|
|
cd buildtest
|
|
echo 'chrono = "0.4"' >>Cargo.toml
|
|
}
|
|
|
|
start_sccache_server()
|
|
{
|
|
echo "#### starting sccache-server"
|
|
killall sccache 2>/dev/null || true
|
|
SCCACHE_ERROR_LOG="$TEST_TMPDIR"/sccache_log.txt SCCACHE_LOG=info \
|
|
RUST_LOG=info sccache --start-server
|
|
sleep 10
|
|
}
|
|
|
|
test_sccache_dist_01()
|
|
{
|
|
echo "#### running scache_dist test 01"
|
|
cd "$TEST_TMPDIR/buildtest"
|
|
RUSTC_WRAPPER=sccache cargo build
|
|
STATS="$(sccache -s)"
|
|
echo "Statistics of first buildtest"
|
|
echo "$STATS"
|
|
CACHE_HITS="$(echo "$STATS" | \
|
|
grep "Cache hits" | grep -v Rust | \awk '{ print $3 }')"
|
|
FAILED_DIST="$(echo "$STATS" | \
|
|
grep "Failed distributed compilations" | awk '{ print $4 }')"
|
|
SUCCEEDED_DIST="$(echo "$STATS" | \
|
|
(grep -F "127.0.0.1:10501" || echo 0 0) | awk '{ print $2 }')"
|
|
|
|
if [ "$CACHE_HITS" -ne 0 ]; then
|
|
2>&1 echo "Unexpected cache hits"
|
|
return 1
|
|
fi
|
|
# We sometimes get "connection closed before message completed"
|
|
# on the first remote build (which will make sccache fall-back
|
|
# to building locally). Until this has been resolved, accept
|
|
# one failed remote build.
|
|
if [ "$FAILED_DIST" -gt 1 ]; then
|
|
2>&1 echo "More than one distributed compilations failed"
|
|
cat "$TEST_TMPDIR"/sccache_log.txt
|
|
return 1
|
|
fi
|
|
if [ "$SUCCEEDED_DIST" -eq 0 ]; then
|
|
2>&1 echo "No distributed compilations succeeded"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
test_sccache_dist_02()
|
|
{
|
|
echo "#### running scache_dist test 02"
|
|
cd "$TEST_TMPDIR/buildtest"
|
|
sccache -z
|
|
cargo clean
|
|
RUSTC_WRAPPER=sccache cargo build
|
|
STATS="$(sccache -s)"
|
|
echo "Statistics of second buildtest"
|
|
echo "$STATS"
|
|
CACHE_HITS="$(echo "$STATS" | \
|
|
grep "Cache hits" | grep -v Rust | \awk '{ print $3 }')"
|
|
FAILED_DIST="$(echo "$STATS" | \
|
|
grep "Failed distributed compilations" | awk '{ print $4 }')"
|
|
SUCCEEDED_DIST="$(echo "$STATS" | \
|
|
(grep -F "127.0.0.1:10501" || echo 0 0) | awk '{ print $2 }')"
|
|
|
|
if [ "$CACHE_HITS" -eq 0 ]; then
|
|
2>&1 echo "No cache hits when there should be some"
|
|
return 1
|
|
fi
|
|
# We sometimes get "connection closed before message completed"
|
|
# on the first remote build (which will make sccache fall-back
|
|
# to building locally). Until this has been resolved, accept
|
|
# one failed remote build.
|
|
if [ "$FAILED_DIST" -gt 1 ]; then
|
|
2>&1 echo "More than one distributed compilations failed"
|
|
return 1
|
|
fi
|
|
if [ "$SUCCEEDED_DIST" -ne 0 ]; then
|
|
2>&1 echo "Unexpected distributed compilations happened"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
cleanup()
|
|
{
|
|
echo "#### cleaning up"
|
|
set +e
|
|
sccache --stop-server
|
|
killall sccache
|
|
killall sccache-dist && sleep 3
|
|
sudo killall sccache-dist && sleep 3
|
|
sudo killall -9 sccache-dist
|
|
killall sccache
|
|
cp "$TEST_TMPDIR/sccache_log.txt" "$base/sccache_log_$(date +%s).txt"
|
|
if [ -z "$FREEBSD_CI_NOCLEAN" ]; then
|
|
for name in $(pot ls -q); do
|
|
sudo pot stop -p "$name"
|
|
done
|
|
sudo pot de-init
|
|
sudo zpool destroy -f potpool
|
|
if [ -n "$MDUNIT" ]; then
|
|
sudo mdconfig -d -u "$MDUNIT"
|
|
fi
|
|
sudo rm -rf "$TEST_TMPDIR"
|
|
fi
|
|
set -e
|
|
}
|
|
|
|
install_signal_handler()
|
|
{
|
|
trap 'remove_signal_handler; cleanup; exit' EXIT INT HUP
|
|
}
|
|
|
|
remove_signal_handler()
|
|
{
|
|
trap - EXIT INT HUP
|
|
}
|
|
|
|
main()
|
|
{
|
|
install_signal_handler
|
|
init
|
|
output_env_info
|
|
build_and_test_project
|
|
prepare_and_run_sccache_dist
|
|
prepare_zpool
|
|
prepare_pot
|
|
start_build_server
|
|
wait_for_build_server
|
|
create_build_test_project
|
|
start_sccache_server
|
|
test_sccache_dist_01
|
|
test_sccache_dist_02
|
|
remove_signal_handler
|
|
cleanup
|
|
}
|
|
|
|
# run main function
|
|
main
|