build/tests/11-git.bats

359 lines
10 KiB
Bash
Executable File

#! /usr/bin/env bats
# This is a test file for use with the bats testing framework
# https://github.com/bats-core/bats-core
# On Debian: apt install bats
function setup {
ORIGDIR="$(pwd)"
TMPDIR="$(mktemp -d)"
# If no $FORGEBUILD is supplied in ENV, use the default
# (otherwise you can't `bats ./tests/` manually)
[ -z "$FORGEBUILD" ] && FORGEBUILD="forgebuild"
# Setup simple git repository
GITREPO="$TMPDIR"/git
mkdir $GITREPO
cd $GITREPO
git init
echo "first commit" > README
git add README
git commit -m "first commit"
# Setup forgebuild tasks
FORGEBUILDDIR="$TMPDIR"/forgebuild
mkdir $FORGEBUILDDIR
echo "$GITREPO" > $FORGEBUILDDIR/time.source
echo "date +%s%N > $TMPDIR/forgebuild-time" > $FORGEBUILDDIR/time
chmod +x $FORGEBUILDDIR/time
echo "$GITREPO" > $FORGEBUILDDIR/host.source
echo "cat \$FORGEBUILDCONF/entry > $TMPDIR/forgebuild-host" > $FORGEBUILDDIR/host
chmod +x $FORGEBUILDDIR/host
echo "$GITREPO" > $FORGEBUILDDIR/branch.source
echo "cat branch > $TMPDIR/forgebuild-branch" > $FORGEBUILDDIR/branch
chmod +x $FORGEBUILDDIR/branch
echo "echo \$(pwd) > $TMPDIR/forgebuild-pwd" > $FORGEBUILDDIR/pwd
chmod +x $FORGEBUILDDIR/pwd
echo "$GITREPO" > $FORGEBUILDDIR/pwd.source
# Setup settings
mkdir $FORGEBUILDDIR/config
echo "default" > $FORGEBUILDDIR/config/entry
mkdir $FORGEBUILDDIR/$HOSTNAME
echo "host" > $FORGEBUILDDIR/$HOSTNAME/entry
}
function teardown {
cd $ORIGDIR
clean
}
function clean {
if [ -d $TMPDIR ]; then rm -rf $TMPDIR; fi
# This is only for the last test (with ~/.forgebuild basedir)
if [ -f $HOME/.forgebuild/TESTtime ]; then rm $HOME/.forgebuild/TESTtime; fi
if [ -f $HOME/.forgebuild/TESTtime.source ]; then rm $HOME/.forgebuild/TESTtime.source; fi
if [ -f $HOME/.forgebuild/.TESTtime ]; then rm -rf $HOME/.forgebuild/.TESTtime; fi
}
# Simple repository
@test "repository is cloned" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $FORGEBUILDDIR/.time/README ]
}
@test "first run triggers task" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
}
@test "task is run from within its source folder" {
$FORGEBUILD -b $FORGEBUILDDIR pwd
PWD="$(cat $TMPDIR/forgebuild-pwd)"
[[ "$PWD" = "$FORGEBUILDDIR/.pwd" ]]
}
@test "after running, back to the previous working dir" {
cd /tmp
$FORGEBUILD -b $FORGEBUILDDIR pwd
[[ "$(pwd)" = "/tmp" ]]
}
@test "no update does not trigger task" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
TIME="$(cat $TMPDIR/forgebuild-time)"
$FORGEBUILD -b $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" = "$NEWTIME" ]]
}
@test "update triggers task" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
TIME="$(cat $TMPDIR/forgebuild-time)"
cd $GITREPO
touch NEWFILE
git add NEWFILE
git commit -m "second commit"
$FORGEBUILD -b $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" != "$NEWTIME" ]]
# Check that the forgebuild repo has been updated
[ -f "$FORGEBUILDDIR"/.time/NEWFILE ]
}
@test "update by source URL works" {
echo "FALSESOURCE" > "$FORGEBUILDDIR"/branch.source
$FORGEBUILD -b $FORGEBUILDDIR "$GITREPO"
[ -f $TMPDIR/forgebuild-host ]
[ -f $TMPDIR/forgebuild-time ]
[ ! -f $TMPDIR/forgebuild-branch ]
}
@test "update can mix source URL and task name" {
git init $TMPDIR/newrepo
echo "$TMPDIR/newrepo" > "$FORGEBUILDDIR"/branch.source
$FORGEBUILD -b $FORGEBUILDDIR "$GITREPO" "branch"
[ -f $TMPDIR/forgebuild-host ]
[ -f $TMPDIR/forgebuild-time ]
[ -f $TMPDIR/forgebuild-branch ]
}
@test "support any default branch (not just master)" {
cd $GITREPO
# Move "master" to "default" branch
git branch -m default
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
}
# Task settings
@test "host-based settings are loaded" {
$FORGEBUILD -b $FORGEBUILDDIR host
[[ "$(cat $TMPDIR/forgebuild-host)" = "host" ]]
}
@test "unknown host uses default settings" {
HOST="UNKNOWN" $FORGEBUILD -b $FORGEBUILDDIR host
[[ "$(cat $TMPDIR/forgebuild-host)" = "default" ]]
}
@test "can checkout to a specific branch/commit" {
echo "branch" > $FORGEBUILDDIR/branch.checkout
cd $GITREPO
# Fetch default branch
default="$(git rev-parse --abbrev-ref HEAD)"
git checkout -b branch
echo "branch" > branch
git add branch
git commit -m "new branch"
git checkout "$default"
$FORGEBUILD -b $FORGEBUILDDIR branch
[[ "$(cat $TMPDIR/forgebuild-branch)" = "branch" ]]
}
@test "task only runs in allowlisted hosts" {
# When t.hosts exist, only this (line-separated) list of hosts
# runs the task
echo "$HOSTNAME" > $FORGEBUILDDIR/time.hosts
$FORGEBUILD -b $FORGEBUILDDIR time
TIME="$(cat $TMPDIR/forgebuild-time)"
# Doesn't run on unknown host
HOST="UNKNOWN" $FORGEBUILD -b $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" = "$NEWTIME" ]]
echo "TESTHOST" >> $FORGEBUILDDIR/time.hosts
# Force trigger because repo was not updated
HOST="TESTHOST" $FORGEBUILD -f -b $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" != "$NEWTIME" ]]
}
@test "task doesn't run in ignored host" {
touch $FORGEBUILDDIR/$HOSTNAME/time.ignore
$FORGEBUILD -b $FORGEBUILDDIR time
[ ! -f $TMPDIR/forgebuild-time ]
HOST="TESTHOST" $FORGEBUILD -f -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
}
@test "repository unavailable fails to trigger task" {
rm -Rf $GITREPO
! $FORGEBUILD -b $FORGEBUILDDIR time
[ ! -f $TMPDIR/forgebuild-time ]
}
# Repository with submodules
function setup_submodule {
export SUBMODULE="$TMPDIR"/submodule
mkdir $SUBMODULE
cd $SUBMODULE
git init
echo "SUB" > README
git add README
git commit -m "first commit"
cd $GITREPO
git submodule add $SUBMODULE sub
git commit -m "add submodule"
}
@test "submodule is cloned" {
setup_submodule
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $FORGEBUILDDIR/.time/sub/README ]
[[ "$(cat $FORGEBUILDDIR/.time/sub/README)" = "SUB" ]]
}
@test "first submodule run triggers task" {
setup_submodule
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
}
@test "submodule added after first clone is initialized" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
setup_submodule
$FORGEBUILD -b $FORGEBUILDDIR time
[[ "$(cat $FORGEBUILDDIR/.time/sub/README)" = "SUB" ]]
}
@test "submodule added after first clone is not updated if subupdates is disabled" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
setup_submodule
cd $SUBMODULE
echo "SUBUPDATE" > README
git add README
git commit -m "update submodule"
$FORGEBUILD -b $FORGEBUILDDIR time
[[ "$(cat $FORGEBUILDDIR/.time/sub/README)" = "SUB" ]]
}
@test "submodule is updated on first clone if subupdates is enabled" {
setup_submodule
cd $SUBMODULE
echo "SUBUPDATE" > README
git add README
git commit -m "update commit"
touch $FORGEBUILDDIR/time.subupdates
$FORGEBUILD -b $FORGEBUILDDIR time
[[ "$(cat $FORGEBUILDDIR/.time/sub/README)" = "SUBUPDATE" ]]
}
@test "submodule update does not trigger task by default" {
setup_submodule
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
TIME="$(cat $TMPDIR/forgebuild-time)"
cd $SUBMODULE
echo "new stuff" > NEWFILE
git add NEWFILE
git commit -m "second commit"
$FORGEBUILD -b $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" = "$NEWTIME" ]]
}
@test "submodule update triggers task when task.subupdates is set" {
setup_submodule
touch $FORGEBUILDDIR/time.subupdates
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
TIME="$(cat $TMPDIR/forgebuild-time)"
cd $SUBMODULE
echo "new stuff" > NEWFILE
git add NEWFILE
git commit -m "second commit"
$FORGEBUILD -b $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" != "$NEWTIME" ]]
}
# CLI arguments/flags
@test "running specific tasks only runs those tasks" {
$FORGEBUILD -b $FORGEBUILDDIR time host
[ -f $TMPDIR/forgebuild-time ]
[ -f $TMPDIR/forgebuild-host ]
[ ! -f $TMPDIR/forgebuild-branch ]
}
@test "not specifying tasks runs all tasks" {
$FORGEBUILD -b $FORGEBUILDDIR
[ -f $TMPDIR/forgebuild-time ]
[ -f $TMPDIR/forgebuild-host ]
[ -f $TMPDIR/forgebuild-branch ]
}
@test "forced run triggers task" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
TIME="$(cat $TMPDIR/forgebuild-time)"
$FORGEBUILD -f -b $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" != "$NEWTIME" ]]
}
@test "can run with relative basedir" {
cd $FORGEBUILDDIR
$FORGEBUILD -b . time
[ -f $TMPDIR/forgebuild-time ]
}
@test "can run with trailing slash in basedir" {
cd $FORGEBUILDDIR
$FORGEBUILD -b ./ time
[ -f $TMPDIR/forgebuild-time ]
}
@test "can use long CLI flags" {
$FORGEBUILD -b $FORGEBUILDDIR time
[ -f $TMPDIR/forgebuild-time ]
TIME="$(cat $TMPDIR/forgebuild-time)"
$FORGEBUILD --force --basedir $FORGEBUILDDIR time
NEWTIME="$(cat $TMPDIR/forgebuild-time)"
[[ "$TIME" != "$NEWTIME" ]]
}
@test "tasks are run in alphanumeric order" {
# Run in background
$FORGEBUILD -b $FORGEBUILDDIR &
while [ ! -f $TMPDIR/forgebuild-branch ]; do
[ ! -f $TMPDIR/forgebuild-host ] && [ ! -f /tmp/forgebuild-time ]
done
while [ ! -f $TMPDIR/forgebuild-host ]; do
[ ! -f $TMPDIR/forgebuild-time ]
done
sleep 1
[ -f $TMPDIR/forgebuild-time ]
}
@test "can run with ~/.forgebuild" {
if [ ! -d $HOME/.forgebuild ]; then
mkdir $HOME/.forgebuild
fi
cp $FORGEBUILDDIR/time $HOME/.forgebuild/TESTtime
cp $FORGEBUILDDIR/time.source $HOME/.forgebuild/TESTtime.source
$FORGEBUILD TESTtime
}