Changeset View
Changeset View
Standalone View
Standalone View
contrib/arcanist/test/test-autopatch.sh
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/bin/env bash | |||||
# Copyright (c) 2019 The Bitcoin developers | |||||
# Distributed under the MIT software license, see the accompanying | |||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
export LC_ALL=C.UTF-8 | |||||
set -euxo pipefail | |||||
TOPLEVEL=$(git rev-parse --show-toplevel) | |||||
CURRENT_DIR=$(dirname $(readlink -f "$0")) | |||||
TEST_PATCH="${CURRENT_DIR}/test-commit.patch" | |||||
: "${REMOTE:=origin}" | |||||
: "${MASTER_BRANCH:=master}" | |||||
REMOTE_AND_BRANCH="${REMOTE}/${MASTER_BRANCH}" | |||||
LATEST_MASTER=$(git rev-parse "${REMOTE_AND_BRANCH}") | |||||
test_autopatch() { | |||||
PATCH_FILE="$1" | |||||
EXPECTED_EXIT_CODE="$2" | |||||
PATCH_ARGS="--patch ${PATCH_FILE}" | |||||
# Setting the remote to this repo allows us to simulate an upstream without | |||||
# relying on external services for unit tests. | |||||
export EDITOR="${CURRENT_DIR}/test-commit-message.sh" | |||||
# Note: Do not use `-o ${REMOTE}` here because REMOTE may be on the local filesystem. | |||||
EXIT_CODE=0 | |||||
"${CURRENT_DIR}/../autopatch.sh" -o testorigin -b "${MASTER_BRANCH}" --patch-args "${PATCH_ARGS}" || EXIT_CODE=$? | |||||
if [ "${EXIT_CODE}" -ne "${EXPECTED_EXIT_CODE}" ]; then | |||||
echo "Error: autopatch exited with '${EXIT_CODE}' when '${EXPECTED_EXIT_CODE}' was expected." | |||||
exit 1 | |||||
fi | |||||
# Autopatch failed as expected, so sanity checks are not necessary | |||||
if [ "${EXPECTED_EXIT_CODE}" -ne 0 ]; then | |||||
exit 0 | |||||
fi | |||||
# Sanity checks | |||||
if [ -n "$(git status --porcelain)" ]; then | |||||
echo "Error: There should be no uncommitted changes." | |||||
exit 10 | |||||
fi | |||||
if [ "${LATEST_MASTER}" != "$(git rev-parse HEAD~)" ]; then | |||||
echo "Error: Failed to patch on latest master." | |||||
exit 11 | |||||
fi | |||||
# Note: Remove 'index ...' line from 'git diff' as the SHA1 hash is unlikely | |||||
# to match. | |||||
DIFF_HEAD_AGAINST_PATCH="$(git diff HEAD~ | grep -v "^index " | diff - "${PATCH_FILE}" || :)" | |||||
if [ -n "${DIFF_HEAD_AGAINST_PATCH}" ]; then | |||||
echo "Error: Rebased changes do not match the given patch. Difference was:" | |||||
echo "${DIFF_HEAD_AGAINST_PATCH}" | |||||
exit 12 | |||||
fi | |||||
} | |||||
TEST_STATUS="FAILED" | |||||
final_cleanup() { | |||||
# Cleanup the temporary test directory | |||||
rm -rf "$1" | |||||
# Nicely print the final test status | |||||
set +x | |||||
echo | |||||
echo "${0}:" | |||||
echo "${TEST_STATUS}" | |||||
} | |||||
TEMP_DIR=$(mktemp -d) | |||||
trap 'final_cleanup ${TEMP_DIR}' RETURN EXIT | |||||
cd "${TEMP_DIR}" | |||||
git init | |||||
git remote add testorigin "${TOPLEVEL}" | |||||
git pull testorigin "${REMOTE_AND_BRANCH}" | |||||
test_cleanup() { | |||||
# Cleanup current branch so that arcanist doesn't run out of branch names | |||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) | |||||
git checkout "${MASTER_BRANCH}" | |||||
git reset --hard HEAD | |||||
git branch -D "${CURRENT_BRANCH}" || true | |||||
} | |||||
( | |||||
trap 'test_cleanup' RETURN ERR EXIT | |||||
echo "TEST: Simply sanity check that autopatch fast-forwards as expected" | |||||
git reset --hard HEAD~10 | |||||
test_autopatch "${TEST_PATCH}" 0 | |||||
) | |||||
test_file_not_present() { | |||||
if [ -n "$1" ] && [ -f "$1" ]; then | |||||
echo "Error: '$1' file was found but not expected!" | |||||
exit 51 | |||||
fi | |||||
} | |||||
( | |||||
trap 'test_cleanup' RETURN ERR EXIT | |||||
echo "TEST: Locally committed changes cause the script to bail" | |||||
TEST_FILE="test-committed-changes" | |||||
touch "${TEST_FILE}" | |||||
git add "${TEST_FILE}" | |||||
git commit -m "test local commit" | |||||
test_autopatch "${TEST_PATCH}" 11 | |||||
) | |||||
( | |||||
trap 'test_cleanup' RETURN ERR EXIT | |||||
echo "TEST: Staged changes are not included after autopatching" | |||||
TEST_FILE="test-staged-changes" | |||||
touch "${TEST_FILE}" | |||||
git add "${TEST_FILE}" | |||||
test_autopatch "${TEST_PATCH}" 10 | |||||
test_file_not_present "${TEST_FILE}" | |||||
) | |||||
( | |||||
trap 'test_cleanup' RETURN ERR EXIT | |||||
echo "TEST: Unstaged changes are not included after autopatching" | |||||
TEST_FILE="test-unstaged-changes" | |||||
touch "${TEST_FILE}" | |||||
test_autopatch "${TEST_PATCH}" 10 | |||||
test_file_not_present "${TEST_FILE}" | |||||
) | |||||
TEST_STATUS="PASSED" |