391 lines
15 KiB
Bash
Executable File
391 lines
15 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
script/build
|
|
|
|
OUTPUT=$(mktemp)
|
|
RESULT=-1
|
|
|
|
SRC_GIT_DAEMON_PORT=9419
|
|
SRC_GIT_DAEMON_OUTPUT=$(mktemp)
|
|
SRC_GIT_DAEMON_PID=-1
|
|
|
|
DEST_GIT_DAEMON_PORT=9420
|
|
DEST_GIT_DAEMON_OUTPUT=$(mktemp)
|
|
DEST_GIT_DAEMON_PID=-1
|
|
|
|
DEST_API_PORT=8081
|
|
DEST_API_OUTPUT=$(mktemp)
|
|
DEST_API_PID=-1
|
|
trap "after_suite" EXIT
|
|
trap "after_suite" SIGINT
|
|
|
|
function test_version() {
|
|
version "version shouldn't require any flags"
|
|
|
|
echo "all version tests passed"
|
|
}
|
|
|
|
function test_pull() {
|
|
# Pull new repo
|
|
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_cache
|
|
pull --repo-name "org/repo" "pulling new repo"
|
|
assert_cache_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "pulling new repo org/repo"
|
|
|
|
echo "all pull tests passed successfully"
|
|
}
|
|
|
|
function test_push() {
|
|
# Push with a new change to main
|
|
setup_cache "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push "pushing new commit to main"
|
|
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:heads/main to new commit"
|
|
|
|
# Push a non-linear change
|
|
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_dest "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
|
|
push "pushing to an old commit to main"
|
|
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "updating heads/main to an old commit"
|
|
|
|
# Push with no changes to main
|
|
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
push "pushing no changes to main"
|
|
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "leaving org/repo:heads/main at existing commit"
|
|
|
|
# Push multiple branches
|
|
setup_cache "org/repo:heads/change:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
|
"org/repo:heads/nochange:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_dest "org/repo:heads/change:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
|
"org/repo:heads/nochange:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push "pushing multiple branches"
|
|
assert_dest_sha "org/repo" "heads/change" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:heads/change to new commit"
|
|
assert_dest_sha "org/repo" "heads/nochange" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "leaving org/repo:heads/nochange at existing commit"
|
|
|
|
# Pushing multiple branches and tags
|
|
setup_cache "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
|
"org/repo:tags/v1:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
|
"org/repo:tags/v1:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push "pushing multiple branches and tags"
|
|
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:heads/main to new commit"
|
|
assert_dest_sha "org/repo" "tags/v1" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo:tags/v1 to new commit"
|
|
|
|
# Pushing multiple repositories
|
|
setup_cache "org1/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
|
"org1/repo2:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
|
"org1/repo2:tags/v1:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
|
"org2/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org1/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
|
"org1/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
|
"org1/repo2:tags/v1:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
|
"org2/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push "pushing multiple repositories"
|
|
assert_dest_sha "org1/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org1/repo1:heads/main to new commit"
|
|
assert_dest_sha "org1/repo2" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org1/repo2:heads/main to new commit"
|
|
assert_dest_sha "org1/repo2" "tags/v1" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org1/repo2:tags/v1 to new commit"
|
|
assert_dest_sha "org2/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org2/repo1:tags/v1 to new commit"
|
|
|
|
# Honor --repo-name flag, ignore other cache entries
|
|
setup_cache "org/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
|
"org/repo2:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
|
"org/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push2args --repo-name "org/repo1" "pushing only one of the repos in the cache"
|
|
assert_dest_sha "org/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo1 passed in repo flag"
|
|
assert_dest_sha "org/repo2" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "org/repo2 not updated despite cache"
|
|
|
|
# Push to pre-existing org
|
|
setup_cache "org-already-exists/new-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org-already-exists/new-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push "pushing to existing org"
|
|
assert_dest_sha "org-already-exists/new-repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org-already-exists/new-repo"
|
|
|
|
# Push to pre-existing repo
|
|
setup_cache "org-already-exists/repo-already-exists:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org-already-exists/repo-already-exists:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push "pushing to existing repo"
|
|
assert_dest_sha "org-already-exists/repo-already-exists" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org-already-exists/repo-already-exists"
|
|
|
|
# Push to repo in user's account
|
|
setup_cache "monalisa/new-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "monalisa/new-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
push "pushing to authenticated user's account"
|
|
assert_dest_sha "monalisa/new-repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating monalisa/new-repo"
|
|
|
|
# Push to GHAE with impersonation
|
|
setup_cache "org-already-exists/ghae-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org-already-exists/ghae-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
push_impersonation "ghae-admin" "pushing to GHAE repo"
|
|
|
|
# Push to GHES with impersonation
|
|
setup_cache "org-already-exists/ghes-repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org-already-exists/ghes-repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
push_impersonation "ghes-admin" "pushing to GHES repo"
|
|
|
|
echo "all push tests passed successfully"
|
|
}
|
|
|
|
function test_sync() {
|
|
# Sync no change without cached
|
|
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_cache
|
|
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
|
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing no changes without cache"
|
|
|
|
# Sync a new commit without cache
|
|
setup_src "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_cache
|
|
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
|
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "syncing a new commit without cache"
|
|
|
|
# Sync no change with uncached
|
|
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
|
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing no changes with cache"
|
|
|
|
# Sync a new commit with cache
|
|
setup_src "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_cache "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_dest "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
sync --repo-name "org/repo" "syncing a new commit in an uncached repo"
|
|
assert_dest_sha "org/repo" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "syncing a new commit with cache"
|
|
|
|
# Sync a non-linear change without cache
|
|
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_cache
|
|
setup_dest "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
|
|
sync --repo-name "org/repo" "syncing an old commit in an uncached repo"
|
|
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing heads/main to an old commit without cache"
|
|
|
|
# Sync a non-linear change with cache
|
|
setup_src "org/repo:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
setup_cache "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
|
|
sync --repo-name "org/repo" "syncing an old commit in an cached repo"
|
|
assert_dest_sha "org/repo" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "syncing heads/main to an old commit with cache"
|
|
|
|
# Sync to a different repo
|
|
setup_src "org/repo:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_cache
|
|
setup_dest "org2/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
sync --repo-name "org/repo:org2/repo2" "syncing org/repo aliased to org2/repo2"
|
|
assert_dest_sha "org2/repo2" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "syncing org/repo aliased to org2/repo2"
|
|
|
|
# Honor --repo-name flag, ignore other cache entries
|
|
setup_cache "org/repo1:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52" \
|
|
"org/repo2:heads/main:e9009d51dd6da2c363d1d14779c53dd27fcb0c52"
|
|
setup_dest "org/repo1:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142" \
|
|
"org/repo2:heads/main:a5984bb887dd2fcdc2892cd906d6f004844d1142"
|
|
|
|
sync --repo-name "org/repo1" "syncing only one of the repos in the cache"
|
|
assert_dest_sha "org/repo1" "heads/main" "e9009d51dd6da2c363d1d14779c53dd27fcb0c52" "updating org/repo1 passed in repo flag"
|
|
assert_dest_sha "org/repo2" "heads/main" "a5984bb887dd2fcdc2892cd906d6f004844d1142" "org/repo2 not updated despite cache"
|
|
|
|
echo "all sync tests passed successfully"
|
|
}
|
|
|
|
function before_suite() {
|
|
set -e
|
|
$(
|
|
rm -rf test/tmp
|
|
mkdir -p test/tmp/dest
|
|
mkdir -p test/tmp/src
|
|
) > /dev/null
|
|
|
|
git daemon \
|
|
--reuseaddr \
|
|
--verbose \
|
|
--export-all \
|
|
--enable=receive-pack \
|
|
--port="$SRC_GIT_DAEMON_PORT" \
|
|
--base-path=test/tmp/src &> $SRC_GIT_DAEMON_OUTPUT &
|
|
SRC_GIT_DAEMON_PID=$!
|
|
|
|
git daemon \
|
|
--reuseaddr \
|
|
--verbose \
|
|
--export-all \
|
|
--enable=receive-pack \
|
|
--port="$DEST_GIT_DAEMON_PORT" \
|
|
--base-path=test/tmp/dest &> $DEST_GIT_DAEMON_OUTPUT &
|
|
DEST_GIT_DAEMON_PID=$!
|
|
|
|
go run test/github.go \
|
|
-p "$DEST_API_PORT" \
|
|
-git-daemon-url "git://localhost:$DEST_GIT_DAEMON_PORT/" &> $DEST_API_OUTPUT &
|
|
DEST_API_PID=$!
|
|
|
|
script/build
|
|
|
|
until $(curl --output /dev/null --silent --head --fail "http://localhost:$DEST_API_PORT/ping"); do
|
|
sleep 0.1
|
|
done
|
|
|
|
set +e
|
|
}
|
|
|
|
function after_suite() {
|
|
kill "$SRC_GIT_DAEMON_PID" "$DEST_GIT_DAEMON_PID" "$DEST_API_PID"
|
|
}
|
|
|
|
function setup_src() {
|
|
rm -rf test/tmp/src
|
|
mkdir -p test/tmp/src
|
|
|
|
for r in "$@"; do
|
|
local nwo=$(echo $r | cut -d':' -f1)
|
|
local refname=$(echo $r | cut -d':' -f2)
|
|
local sha=$(echo $r | cut -d':' -f3)
|
|
|
|
local org=$(echo $nwo | cut -d'/' -f1)
|
|
mkdir -p test/tmp/src/$org && cp -R test/fixtures/repo.git test/tmp/src/$nwo
|
|
echo "$sha" > "test/tmp/src/$nwo/refs/$refname"
|
|
done
|
|
}
|
|
|
|
function setup_cache() {
|
|
rm -rf test/tmp/cache
|
|
mkdir -p test/tmp/cache
|
|
|
|
for r in "$@"; do
|
|
local nwo=$(echo $r | cut -d':' -f1)
|
|
local refname=$(echo $r | cut -d':' -f2)
|
|
local sha=$(echo $r | cut -d':' -f3)
|
|
mkdir -p test/tmp/cache/$nwo && cp -R test/fixtures/repo.git test/tmp/cache/$nwo/.git
|
|
echo "$sha" > "test/tmp/cache/$nwo/.git/refs/$refname"
|
|
done
|
|
}
|
|
|
|
function setup_dest() {
|
|
rm -rf test/tmp/dest
|
|
mkdir -p test/tmp/dest
|
|
|
|
for r in "$@"; do
|
|
local nwo=$(echo $r | cut -d':' -f1)
|
|
local refname=$(echo $r | cut -d':' -f2)
|
|
local sha=$(echo $r | cut -d':' -f3)
|
|
mkdir -p test/tmp/dest/$nwo && cp -R test/fixtures/repo.git test/tmp/dest/$nwo/.git
|
|
echo "$sha" > "test/tmp/dest/$nwo/.git/refs/$refname"
|
|
done
|
|
}
|
|
|
|
function version() {
|
|
bin/actions-sync version \
|
|
&> $OUTPUT ||
|
|
fail $1
|
|
}
|
|
|
|
function pull() {
|
|
bin/actions-sync pull \
|
|
--cache-dir "test/tmp/cache" \
|
|
--source-url "git://localhost:$SRC_GIT_DAEMON_PORT" \
|
|
"$1" "$2" \
|
|
&> $OUTPUT ||
|
|
fail $3
|
|
}
|
|
|
|
function push() {
|
|
bin/actions-sync push \
|
|
--cache-dir "test/tmp/cache" \
|
|
--disable-push-git-auth \
|
|
--destination-token "token" \
|
|
--destination-url "http://localhost:$DEST_API_PORT" \
|
|
&> $OUTPUT ||
|
|
fail "$1"
|
|
}
|
|
|
|
function push2args() {
|
|
bin/actions-sync push \
|
|
--cache-dir "test/tmp/cache" \
|
|
--disable-push-git-auth \
|
|
--destination-token "token" \
|
|
--destination-url "http://localhost:$DEST_API_PORT" \
|
|
"$1" "$2" \
|
|
&> $OUTPUT ||
|
|
fail $3
|
|
}
|
|
|
|
function push_impersonation() {
|
|
bin/actions-sync push \
|
|
--cache-dir "test/tmp/cache" \
|
|
--disable-push-git-auth \
|
|
--destination-token "token" \
|
|
--destination-url "http://localhost:$DEST_API_PORT" \
|
|
--actions-admin-user $1 \
|
|
&> $OUTPUT ||
|
|
fail "$2"
|
|
}
|
|
|
|
function sync() {
|
|
bin/actions-sync sync \
|
|
--cache-dir "test/tmp/cache" \
|
|
--source-url "git://localhost:$SRC_GIT_DAEMON_PORT" \
|
|
--disable-push-git-auth \
|
|
--destination-token "token" \
|
|
--destination-url "http://localhost:$DEST_API_PORT" \
|
|
"$1" "$2" \
|
|
&> $OUTPUT ||
|
|
fail $3
|
|
}
|
|
|
|
function assert_cache_sha() {
|
|
nwo=$1
|
|
ref=$2
|
|
expected=$3
|
|
actual=$(cat "test/tmp/cache/$nwo/.git/refs/$ref")
|
|
[ "$actual" == "$expected" ] || fail "unexpected cache sha \`$expected != $actual\` - \`$nwo\` \`$ref\` - \`$4\`"
|
|
}
|
|
|
|
function assert_dest_sha() {
|
|
nwo=$1
|
|
ref=$2
|
|
expected=$3
|
|
actual=$(cat "test/tmp/dest/$nwo/.git/refs/$ref")
|
|
[ "$actual" == "$expected" ] || fail "unexpected dest sha \`$expected != $actual\` - \`$nwo\` \`$ref\` - \`$4\`"
|
|
}
|
|
|
|
function fail() {
|
|
MSG=$1
|
|
echo "FAIL: Failed $MSG"
|
|
echo -----output-----
|
|
cat $OUTPUT
|
|
echo -----/output-----
|
|
|
|
echo -----github git daemon output-----
|
|
cat $SRC_GIT_DAEMON_OUTPUT
|
|
echo -----/github git daemon output-----
|
|
|
|
echo -----ghes git daemon output-----
|
|
cat $DEST_GIT_DAEMON_OUTPUT
|
|
echo -----/ghes git daemon output-----
|
|
|
|
echo -----ghes api output-----
|
|
cat $DEST_API_OUTPUT
|
|
echo -----/ghes api output-----
|
|
exit 1
|
|
}
|
|
|
|
test_version
|
|
before_suite
|
|
test_pull
|
|
test_push
|
|
test_sync
|