Skip to content

Commit

Permalink
Merge branch 'ps/ci-meson'
Browse files Browse the repository at this point in the history
The meson-build procedure is integrated into CI to catch and
prevent bitrotting.

* ps/ci-meson:
  ci: wire up Meson builds
  t: introduce compatibility options to clar-based tests
  t: fix out-of-tree tests for some git-p4 tests
  Makefile: detect missing Meson tests
  meson: detect missing tests at configure time
  t/unit-tests: rename clar-based unit tests to have a common prefix
  Makefile: drop -DSUPPRESS_ANNOTATED_LEAKS
  ci/lib: support custom output directories when creating test artifacts
  • Loading branch information
gitster committed Dec 23, 2024
2 parents e9a4054 + eab5dba commit 83c8f76
Show file tree
Hide file tree
Showing 17 changed files with 195 additions and 74 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ jobs:
- jobname: osx-gcc
cc: gcc-13
pool: macos-13
- jobname: osx-meson
cc: clang
pool: macos-13
- jobname: linux-gcc-default
cc: gcc
pool: ubuntu-latest
Expand All @@ -294,11 +297,15 @@ jobs:
- jobname: linux-asan-ubsan
cc: clang
pool: ubuntu-latest
- jobname: linux-meson
cc: gcc
pool: ubuntu-latest
env:
CC: ${{matrix.vector.cc}}
CC_PACKAGE: ${{matrix.vector.cc_package}}
jobname: ${{matrix.vector.jobname}}
distro: ${{matrix.vector.pool}}
TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t
runs-on: ${{matrix.vector.pool}}
steps:
- uses: actions/checkout@v4
Expand Down
8 changes: 8 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ test:linux:
- saas-linux-medium-amd64
variables:
CUSTOM_PATH: "/custom"
TEST_OUTPUT_DIRECTORY: "/tmp/test-output"
before_script:
- ./ci/install-dependencies.sh
script:
Expand All @@ -31,6 +32,7 @@ test:linux:
if test "$CI_JOB_STATUS" != 'success'
then
sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh
mv "$TEST_OUTPUT_DIRECTORY"/failed-test-artifacts t/
fi
parallel:
matrix:
Expand Down Expand Up @@ -67,6 +69,9 @@ test:linux:
image: fedora:latest
- jobname: linux-musl
image: alpine:latest
- jobname: linux-meson
image: ubuntu:latest
CC: gcc
artifacts:
paths:
- t/failed-test-artifacts
Expand Down Expand Up @@ -104,6 +109,9 @@ test:osx:
- jobname: osx-reftable
image: macos-14-xcode-15
CC: clang
- jobname: osx-meson
image: macos-14-xcode-15
CC: clang
artifacts:
paths:
- t/failed-test-artifacts
Expand Down
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1344,8 +1344,8 @@ THIRD_PARTY_SOURCES += sha1dc/%
THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/%
THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/%

CLAR_TEST_SUITES += ctype
CLAR_TEST_SUITES += strvec
CLAR_TEST_SUITES += u-ctype
CLAR_TEST_SUITES += u-strvec
CLAR_TEST_PROG = $(UNIT_TEST_BIN)/unit-tests$(X)
CLAR_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(CLAR_TEST_SUITES))
CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/clar/clar.o
Expand Down Expand Up @@ -1490,7 +1490,6 @@ ifneq ($(filter undefined,$(SANITIZERS)),)
BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS
endif
ifneq ($(filter leak,$(SANITIZERS)),)
BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS
BASIC_CFLAGS += -O0
SANITIZE_LEAK = YesCompiledWithIt
endif
Expand Down
7 changes: 7 additions & 0 deletions ci/install-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ ubuntu-*|ubuntu32-*|debian-*)
make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \
tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \
libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \
libpcre2-dev meson ninja-build pkg-config \
${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE

case "$distro" in
Expand Down Expand Up @@ -90,6 +91,12 @@ macos-*)
sudo xattr -d com.apple.quarantine "$CUSTOM_PATH/p4" "$CUSTOM_PATH/p4d" 2>/dev/null || true
rm helix-core-server.tgz

case "$jobname" in
osx-meson)
brew install meson ninja pcre2
;;
esac

if test -n "$CC_PACKAGE"
then
BREW_PACKAGE=${CC_PACKAGE/-/@}
Expand Down
14 changes: 7 additions & 7 deletions ci/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ handle_failed_tests () {
}

create_failed_test_artifacts () {
mkdir -p t/failed-test-artifacts
mkdir -p "${TEST_OUTPUT_DIRECTORY:-t}"/failed-test-artifacts

for test_exit in t/test-results/*.exit
for test_exit in "${TEST_OUTPUT_DIRECTORY:-t}"/test-results/*.exit
do
test 0 != "$(cat "$test_exit")" || continue

Expand All @@ -192,11 +192,11 @@ create_failed_test_artifacts () {
printf "\\e[33m\\e[1m=== Failed test: ${test_name} ===\\e[m\\n"
echo "The full logs are in the 'print test failures' step below."
echo "See also the 'failed-tests-*' artifacts attached to this run."
cat "t/test-results/$test_name.markup"
cat "${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.markup"

trash_dir="t/trash directory.$test_name"
cp "t/test-results/$test_name.out" t/failed-test-artifacts/
tar czf t/failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir"
trash_dir="${TEST_OUTPUT_DIRECTORY:-t}/trash directory.$test_name"
cp "${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.out" "${TEST_OUTPUT_DIRECTORY:-t}"/failed-test-artifacts/
tar czf "${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts/$test_name.trash.tar.gz" "$trash_dir"
done
}

Expand Down Expand Up @@ -237,7 +237,7 @@ then
CC="${CC_PACKAGE:-${CC:-gcc}}"
DONT_SKIP_TAGS=t
handle_failed_tests () {
echo "FAILED_TEST_ARTIFACTS=t/failed-test-artifacts" >>$GITHUB_ENV
echo "FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts" >>$GITHUB_ENV
create_failed_test_artifacts
return 1
}
Expand Down
2 changes: 1 addition & 1 deletion ci/print-test-failures.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ do
;;
github-actions)
mkdir -p failed-test-artifacts
echo "FAILED_TEST_ARTIFACTS=t/failed-test-artifacts" >>$GITHUB_ENV
echo "FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:t}/failed-test-artifacts" >>$GITHUB_ENV
cp "${TEST_EXIT%.exit}.out" failed-test-artifacts/
tar czf failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir"
continue
Expand Down
31 changes: 24 additions & 7 deletions ci/run-build-and-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,29 @@ pedantic)
;;
esac

group Build make
if test -n "$run_tests"
then
group "Run tests" make test ||
handle_failed_tests
fi
check_unignored_build_artifacts
case "$jobname" in
*-meson)
group "Configure" meson setup build . \
--warnlevel 2 --werror \
--wrap-mode nofallback
group "Build" meson compile -C build --
if test -n "$run_tests"
then
group "Run tests" meson test -C build --print-errorlogs --test-args="$GIT_TEST_OPTS" || (
./t/aggregate-results.sh "${TEST_OUTPUT_DIRECTORY:-t}/test-results"
handle_failed_tests
)
fi
;;
*)
group Build make
if test -n "$run_tests"
then
group "Run tests" make test ||
handle_failed_tests
fi
;;
esac

check_unignored_build_artifacts
save_good_tree
1 change: 0 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,6 @@ else
build_options_config.set('SANITIZE_ADDRESS', '')
endif
if get_option('b_sanitize').contains('leak')
libgit_c_args += '-DSUPPRESS_ANNOTATED_LEAKS'
build_options_config.set('SANITIZE_LEAK', 'YesCompiledWithIt')
else
build_options_config.set('SANITIZE_LEAK', '')
Expand Down
12 changes: 12 additions & 0 deletions parse-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,18 @@ struct option {
.callback = parse_opt_noop_cb, \
}

static char *parse_options_noop_ignored_value MAYBE_UNUSED;
#define OPT_NOOP_ARG(s, l) { \
.type = OPTION_CALLBACK, \
.short_name = (s), \
.long_name = (l), \
.value = &parse_options_noop_ignored_value, \
.argh = "ignored", \
.help = N_("no-op (backward compatibility)"), \
.flags = PARSE_OPT_HIDDEN, \
.callback = parse_opt_noop_cb, \
}

#define OPT_ALIAS(s, l, source_long_name) { \
.type = OPTION_ALIAS, \
.short_name = (s), \
Expand Down
18 changes: 17 additions & 1 deletion t/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ CHAINLINTSUPPRESS = GIT_TEST_EXT_CHAIN_LINT=0 && export GIT_TEST_EXT_CHAIN_LINT

all:: $(DEFAULT_TEST_TARGET)

test: pre-clean check-chainlint $(TEST_LINT)
test: pre-clean check-chainlint check-meson $(TEST_LINT)
$(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup

failed:
Expand Down Expand Up @@ -114,6 +114,22 @@ check-chainlint:
{ $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \
diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual

check-meson:
@# awk acts up when trying to match single quotes, so we use \047 instead.
@printf "%s\n" \
"integration_tests t[0-9][0-9][0-9][0-9]-*.sh" \
"unit_test_programs unit-tests/t-*.c" \
"clar_test_suites unit-tests/u-*.c" | \
while read -r variable pattern; do \
meson_tests=$$(awk "/^$$variable = \[\$$/ {flag=1 ; next } /^]$$/ { flag=0 } flag { gsub(/^ \047/, \"\"); gsub(/\047,\$$/, \"\"); print }" meson.build) && \
actual_tests=$$(ls $$pattern) && \
if test "$$meson_tests" != "$$actual_tests"; then \
echo "Meson tests differ from actual tests:"; \
diff -u <(echo "$$meson_tests") <(echo "$$actual_tests"); \
exit 1; \
fi; \
done

test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \
test-lint-filenames
ifneq ($(GIT_TEST_CHAIN_LINT),0)
Expand Down
40 changes: 38 additions & 2 deletions t/meson.build
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
clar_test_suites = [
'unit-tests/ctype.c',
'unit-tests/strvec.c',
'unit-tests/u-ctype.c',
'unit-tests/u-strvec.c',
]

clar_sources = [
Expand Down Expand Up @@ -1092,6 +1092,42 @@ integration_tests = [
't9903-bash-prompt.sh',
]

# Sanity check that we are not missing any tests present in 't/'. This check
# only runs once at configure time and is thus best-effort, only. It is
# sufficient to catch missing test suites in our CI though.
foreach glob, tests : {
't[0-9][0-9][0-9][0-9]-*.sh': integration_tests,
'unit-tests/t-*.c': unit_test_programs,
'unit-tests/u-*.c': clar_test_suites,
}
actual_tests = run_command(shell, '-c', 'ls ' + glob,
check: true,
env: script_environment,
).stdout().strip().split('\n')

if tests != actual_tests
missing_tests = [ ]
foreach actual_test : actual_tests
if actual_test not in tests
missing_tests += actual_test
endif
endforeach
if missing_tests.length() > 0
error('Test files found, but not configured:\n\n - ' + '\n - '.join(missing_tests))
endif

superfluous_tests = [ ]
foreach integration_test : tests
if integration_test not in actual_tests
superfluous_tests += integration_test
endif
endforeach
if superfluous_tests.length() > 0
error('Test files configured, but not found:\n\n - ' + '\n - '.join(superfluous_tests))
endif
endif
endforeach

# GIT_BUILD_DIR needs to be Unix-style without drive prefixes as it get added
# to the PATH variable. And given that drive prefixes contain a colon we'd
# otherwise end up with a broken PATH if we didn't convert it.
Expand Down
Loading

0 comments on commit 83c8f76

Please sign in to comment.