All checks were successful
CI Code / Check spelling (pull_request) Successful in 13s
CI Code / Check coding style (pull_request) Successful in 23s
CI Code / Code Coverage (pull_request) Successful in 3m43s
CI Code / Linux (debian) (pull_request) Successful in 5m13s
CI Code / Linux (ubuntu) (pull_request) Successful in 5m20s
CI Code / Linux (arch) (pull_request) Successful in 7m6s
- bound _parse_responses scans to the output_text part's object and to
the content array, so a later sibling item's "text" (e.g. a reasoning
summary) can never be returned as the assistant reply
- do not retry the other flavour on a curl timeout: the request likely
reached the server and may still be generating, so a re-POST of the
conversation could trigger a second billed generation
- remember an unparseable 2xx from the first AUTO attempt and surface
stashed first-attempt errors in both error paths, instead of showing
only the final attempt's transport or HTTP error
- recognize Ollama's model-not-found wording in _names_model so a model
typo is not misread as a missing endpoint
- drop the dead, racy provider-lookup fallback in the generic request
thread: a missing provider ref is a caller bug and now fails loudly
- fix ai_providers_lists_defaults to expect the header the command
actually prints ("Configured providers:"); the test was broken since
its introduction but CI never ran it
- add functional test group 5 (AI command surface) to FUNC_TEST_GROUPS
so the CI parallel target runs it; proftest.c port ranges already
account for five groups
705 lines
28 KiB
Makefile
705 lines
28 KiB
Makefile
core_sources = \
|
||
src/xmpp/contact.c src/xmpp/contact.h \
|
||
src/log.c src/common.c \
|
||
src/chatlog.c src/chatlog.h \
|
||
src/database.h src/database.c \
|
||
src/database_flatfile.c src/database_flatfile.h \
|
||
src/database_flatfile_parser.c \
|
||
src/database_flatfile_verify.c \
|
||
src/database_export.c \
|
||
src/log.h src/profanity.c src/common.h \
|
||
src/profanity.h src/xmpp/chat_session.c \
|
||
src/xmpp/chat_session.h src/xmpp/muc.c src/xmpp/muc.h src/xmpp/jid.h src/xmpp/jid.c \
|
||
src/xmpp/chat_state.h src/xmpp/chat_state.c \
|
||
src/xmpp/resource.c src/xmpp/resource.h \
|
||
src/xmpp/roster_list.c src/xmpp/roster_list.h \
|
||
src/xmpp/xmpp.h src/xmpp/capabilities.c src/xmpp/session.c \
|
||
src/xmpp/connection.h src/xmpp/connection.c \
|
||
src/xmpp/iq.c src/xmpp/message.c src/xmpp/presence.c src/xmpp/stanza.c \
|
||
src/xmpp/stanza.h src/xmpp/message.h src/xmpp/iq.h src/xmpp/presence.h \
|
||
src/xmpp/capabilities.h src/xmpp/session.h \
|
||
src/xmpp/roster.c src/xmpp/roster.h \
|
||
src/xmpp/bookmark.c src/xmpp/bookmark.h \
|
||
src/xmpp/blocking.c src/xmpp/blocking.h \
|
||
src/xmpp/form.c src/xmpp/form.h \
|
||
src/xmpp/avatar.c src/xmpp/avatar.h \
|
||
src/xmpp/ox.c src/xmpp/ox.h \
|
||
src/xmpp/vcard.c src/xmpp/vcard.h src/xmpp/vcard_funcs.h \
|
||
src/event/common.c src/event/common.h \
|
||
src/event/server_events.c src/event/server_events.h \
|
||
src/event/client_events.c src/event/client_events.h \
|
||
src/ui/ui.h src/ui/window.c src/ui/window.h src/ui/core.c \
|
||
src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \
|
||
src/ui/titlebar.h src/ui/statusbar.h src/ui/inputwin.h \
|
||
src/ui/screen.h src/ui/screen.c \
|
||
src/ui/console.c src/ui/notifier.c \
|
||
src/ui/win_types.h \
|
||
src/ui/window_list.c src/ui/window_list.h \
|
||
src/ui/rosterwin.c src/ui/occupantswin.c \
|
||
src/ui/buffer.c src/ui/buffer.h \
|
||
src/ui/aiwin.c \
|
||
src/ui/chatwin.c \
|
||
src/ui/mucwin.c \
|
||
src/ui/privwin.c \
|
||
src/ui/confwin.c \
|
||
src/ui/xmlwin.c \
|
||
src/ui/vcardwin.c \
|
||
src/command/cmd_defs.h src/command/cmd_defs.c \
|
||
src/command/cmd_funcs.h src/command/cmd_funcs.c \
|
||
src/command/cmd_ac.h src/command/cmd_ac.c \
|
||
src/tools/parser.c \
|
||
src/tools/parser.h \
|
||
src/tools/http_common.c \
|
||
src/tools/http_common.h \
|
||
src/tools/http_upload.c \
|
||
src/tools/http_upload.h \
|
||
src/tools/http_download.c \
|
||
src/tools/http_download.h \
|
||
src/tools/plugin_download.c \
|
||
src/tools/plugin_download.h \
|
||
src/tools/bookmark_ignore.c \
|
||
src/tools/bookmark_ignore.h \
|
||
src/tools/autocomplete.c src/tools/autocomplete.h \
|
||
src/tools/clipboard.c src/tools/clipboard.h \
|
||
src/tools/editor.c src/tools/editor.h \
|
||
src/config/files.c src/config/files.h \
|
||
src/config/conflists.c src/config/conflists.h \
|
||
src/config/accounts.c src/config/accounts.h \
|
||
src/config/tlscerts.c src/config/tlscerts.h \
|
||
src/config/account.c src/config/account.h \
|
||
src/config/preferences.c src/config/preferences.h \
|
||
src/config/theme.c src/config/theme.h \
|
||
src/config/color.c src/config/color.h \
|
||
src/config/scripts.c src/config/scripts.h \
|
||
src/config/cafile.c src/config/cafile.h \
|
||
src/plugins/plugins.h src/plugins/plugins.c \
|
||
src/plugins/api.h src/plugins/api.c \
|
||
src/plugins/callbacks.h src/plugins/callbacks.c \
|
||
src/plugins/autocompleters.c src/plugins/autocompleters.h \
|
||
src/plugins/themes.c src/plugins/themes.h \
|
||
src/plugins/settings.c src/plugins/settings.h \
|
||
src/plugins/disco.c src/plugins/disco.h \
|
||
src/ui/tray.h src/ui/tray.c \
|
||
src/ai/ai_client.h src/ai/ai_client.c
|
||
|
||
unittest_sources = \
|
||
src/xmpp/contact.c src/xmpp/contact.h src/common.c \
|
||
src/log.h src/profanity.c src/common.h \
|
||
src/profanity.h src/xmpp/chat_session.c \
|
||
src/xmpp/chat_session.h src/xmpp/muc.c src/xmpp/muc.h src/xmpp/jid.h src/xmpp/jid.c \
|
||
src/xmpp/resource.c src/xmpp/resource.h \
|
||
src/xmpp/chat_state.h src/xmpp/chat_state.c \
|
||
src/xmpp/roster_list.c src/xmpp/roster_list.h \
|
||
src/xmpp/xmpp.h src/xmpp/form.c \
|
||
src/ai/ai_client.h src/ai/ai_client.c \
|
||
src/ui/ui.h \
|
||
src/otr/otr.h \
|
||
src/pgp/gpg.h \
|
||
src/pgp/ox.h \
|
||
src/omemo/omemo.h \
|
||
src/omemo/crypto.h \
|
||
src/omemo/store.h \
|
||
src/xmpp/vcard.h src/xmpp/vcard_funcs.h \
|
||
src/database_flatfile.h \
|
||
src/database_flatfile_parser.c \
|
||
src/command/cmd_defs.h src/command/cmd_defs.c \
|
||
src/command/cmd_funcs.h src/command/cmd_funcs.c \
|
||
src/command/cmd_ac.h src/command/cmd_ac.c \
|
||
src/tools/parser.c \
|
||
src/tools/parser.h \
|
||
src/tools/autocomplete.c src/tools/autocomplete.h \
|
||
src/tools/clipboard.c src/tools/clipboard.h \
|
||
src/tools/editor.c src/tools/editor.h \
|
||
src/tools/bookmark_ignore.c \
|
||
src/tools/bookmark_ignore.h \
|
||
src/config/accounts.h \
|
||
src/config/account.c src/config/account.h \
|
||
src/config/files.c src/config/files.h \
|
||
src/config/tlscerts.c src/config/tlscerts.h \
|
||
src/config/preferences.c src/config/preferences.h \
|
||
src/config/theme.c src/config/theme.h \
|
||
src/config/color.c src/config/color.h \
|
||
src/config/scripts.c src/config/scripts.h \
|
||
src/config/conflists.c src/config/conflists.h \
|
||
src/plugins/plugins.h src/plugins/plugins.c \
|
||
src/plugins/api.h src/plugins/api.c \
|
||
src/plugins/callbacks.h src/plugins/callbacks.c \
|
||
src/plugins/autocompleters.c src/plugins/autocompleters.h \
|
||
src/plugins/themes.c src/plugins/themes.h \
|
||
src/plugins/settings.c src/plugins/settings.h \
|
||
src/plugins/disco.c src/plugins/disco.h \
|
||
src/ui/window_list.c src/ui/window_list.h \
|
||
src/event/common.c src/event/common.h \
|
||
src/event/server_events.c src/event/server_events.h \
|
||
src/event/client_events.c src/event/client_events.h \
|
||
src/ui/tray.h src/ui/tray.c \
|
||
tests/prof_cmocka.h \
|
||
tests/unittests/xmpp/stub_vcard.c \
|
||
tests/unittests/xmpp/stub_avatar.c \
|
||
tests/unittests/xmpp/stub_ox.c \
|
||
tests/unittests/xmpp/stub_xmpp.c \
|
||
tests/unittests/xmpp/stub_message.c \
|
||
tests/unittests/ui/stub_ui.c tests/unittests/ui/stub_ui.h \
|
||
tests/unittests/ui/stub_vcardwin.c \
|
||
tests/unittests/ui/stub_ai.c \
|
||
tests/unittests/log/stub_log.c \
|
||
tests/unittests/chatlog/stub_chatlog.c \
|
||
tests/unittests/database/stub_database.c \
|
||
tests/unittests/config/stub_accounts.c \
|
||
tests/unittests/config/stub_cafile.c \
|
||
tests/unittests/tools/stub_http_upload.c \
|
||
tests/unittests/tools/stub_http_download.c \
|
||
tests/unittests/tools/stub_aesgcm_download.c \
|
||
tests/unittests/tools/stub_plugin_download.c \
|
||
tests/unittests/helpers.c tests/unittests/helpers.h \
|
||
tests/unittests/xmpp/test_form.c tests/unittests/xmpp/test_form.h \
|
||
tests/unittests/test_common.c tests/unittests/test_common.h \
|
||
tests/unittests/tools/test_autocomplete.c tests/unittests/tools/test_autocomplete.h \
|
||
tests/unittests/xmpp/test_jid.c tests/unittests/xmpp/test_jid.h \
|
||
tests/unittests/tools/test_parser.c tests/unittests/tools/test_parser.h \
|
||
tests/unittests/xmpp/test_roster_list.c tests/unittests/xmpp/test_roster_list.h \
|
||
tests/unittests/xmpp/test_chat_session.c tests/unittests/xmpp/test_chat_session.h \
|
||
tests/unittests/xmpp/test_contact.c tests/unittests/xmpp/test_contact.h \
|
||
tests/unittests/config/test_preferences.c tests/unittests/config/test_preferences.h \
|
||
tests/unittests/event/test_server_events.c tests/unittests/event/test_server_events.h \
|
||
tests/unittests/xmpp/test_muc.c tests/unittests/xmpp/test_muc.h \
|
||
tests/unittests/command/test_cmd_presence.c tests/unittests/command/test_cmd_presence.h \
|
||
tests/unittests/command/test_cmd_alias.c tests/unittests/command/test_cmd_alias.h \
|
||
tests/unittests/command/test_cmd_connect.c tests/unittests/command/test_cmd_connect.h \
|
||
tests/unittests/command/test_cmd_rooms.c tests/unittests/command/test_cmd_rooms.h \
|
||
tests/unittests/command/test_cmd_account.c tests/unittests/command/test_cmd_account.h \
|
||
tests/unittests/command/test_cmd_sub.c tests/unittests/command/test_cmd_sub.h \
|
||
tests/unittests/command/test_cmd_bookmark.c tests/unittests/command/test_cmd_bookmark.h \
|
||
tests/unittests/command/test_cmd_otr.c tests/unittests/command/test_cmd_otr.h \
|
||
tests/unittests/command/test_cmd_pgp.c tests/unittests/command/test_cmd_pgp.h \
|
||
tests/unittests/command/test_cmd_join.c tests/unittests/command/test_cmd_join.h \
|
||
tests/unittests/command/test_cmd_roster.c tests/unittests/command/test_cmd_roster.h \
|
||
tests/unittests/command/test_cmd_disconnect.c tests/unittests/command/test_cmd_disconnect.h \
|
||
tests/unittests/command/test_cmd_ac.c tests/unittests/command/test_cmd_ac.h \
|
||
tests/unittests/plugins/test_callbacks.c tests/unittests/plugins/test_callbacks.h \
|
||
tests/unittests/plugins/test_plugins_disco.c tests/unittests/plugins/test_plugins_disco.h \
|
||
tests/unittests/test_forced_encryption.c tests/unittests/test_forced_encryption.h \
|
||
tests/unittests/test_ai_client.c tests/unittests/test_ai_client.h \
|
||
tests/unittests/test_database_export.c tests/unittests/test_database_export.h \
|
||
tests/unittests/test_database_stress.c tests/unittests/test_database_stress.h \
|
||
tests/unittests/unittests.c
|
||
|
||
functionaltest_sources = \
|
||
tests/prof_cmocka.h \
|
||
tests/functionaltests/proftest.c tests/functionaltests/proftest.h \
|
||
tests/functionaltests/test_connect.c tests/functionaltests/test_connect.h \
|
||
tests/functionaltests/test_ping.c tests/functionaltests/test_ping.h \
|
||
tests/functionaltests/test_rooms.c tests/functionaltests/test_rooms.h \
|
||
tests/functionaltests/test_presence.c tests/functionaltests/test_presence.h \
|
||
tests/functionaltests/test_message.c tests/functionaltests/test_message.h \
|
||
tests/functionaltests/test_chat_session.c tests/functionaltests/test_chat_session.h \
|
||
tests/functionaltests/test_carbons.c tests/functionaltests/test_carbons.h \
|
||
tests/functionaltests/test_receipts.c tests/functionaltests/test_receipts.h \
|
||
tests/functionaltests/test_roster.c tests/functionaltests/test_roster.h \
|
||
tests/functionaltests/test_software.c tests/functionaltests/test_software.h \
|
||
tests/functionaltests/test_muc.c tests/functionaltests/test_muc.h \
|
||
tests/functionaltests/test_disconnect.c tests/functionaltests/test_disconnect.h \
|
||
tests/functionaltests/test_history.c tests/functionaltests/test_history.h \
|
||
tests/functionaltests/test_lastactivity.c tests/functionaltests/test_lastactivity.h \
|
||
tests/functionaltests/test_autoping.c tests/functionaltests/test_autoping.h \
|
||
tests/functionaltests/test_disco.c tests/functionaltests/test_disco.h \
|
||
tests/functionaltests/test_export_import.c tests/functionaltests/test_export_import.h \
|
||
tests/functionaltests/test_ai.c tests/functionaltests/test_ai.h \
|
||
tests/functionaltests/functionaltests.c
|
||
|
||
main_source = src/main.c
|
||
|
||
python_sources = \
|
||
src/plugins/python_plugins.h src/plugins/python_plugins.c \
|
||
src/plugins/python_api.h src/plugins/python_api.c
|
||
|
||
c_sources = \
|
||
src/plugins/c_plugins.h src/plugins/c_plugins.c \
|
||
src/plugins/c_api.h src/plugins/c_api.c
|
||
|
||
git_include = src/gitversion.h
|
||
|
||
pgp_sources = \
|
||
src/pgp/gpg.h src/pgp/gpg.c \
|
||
src/pgp/ox.h src/pgp/ox.c
|
||
|
||
pgp_unittest_sources = \
|
||
tests/unittests/pgp/stub_gpg.c \
|
||
tests/unittests/pgp/stub_ox.c
|
||
|
||
otr4_sources = \
|
||
src/otr/otrlib.h src/otr/otrlibv4.c src/otr/otr.h src/otr/otr.c
|
||
|
||
omemo_sources = \
|
||
src/omemo/omemo.h src/omemo/omemo.c src/omemo/crypto.h src/omemo/crypto.c \
|
||
src/omemo/store.h src/omemo/store.c src/xmpp/omemo.h src/xmpp/omemo.c \
|
||
src/tools/aesgcm_download.h src/tools/aesgcm_download.c
|
||
|
||
omemo_unittest_sources = \
|
||
tests/unittests/omemo/stub_omemo.c
|
||
|
||
if BUILD_PYTHON_API
|
||
core_sources += $(python_sources)
|
||
unittest_sources += $(python_sources)
|
||
endif
|
||
|
||
if BUILD_C_API
|
||
core_sources += $(c_sources)
|
||
unittest_sources += $(c_sources)
|
||
endif
|
||
|
||
otr_unittest_sources = \
|
||
tests/unittests/otr/stub_otr.c
|
||
|
||
themes_sources = $(top_srcdir)/themes/*
|
||
|
||
icons_sources = $(top_srcdir)/icons/*
|
||
|
||
script_sources = bootstrap.sh
|
||
|
||
man1_sources = $(wildcard $(top_srcdir)/docs/profanity*.1)
|
||
|
||
if BUILD_PGP
|
||
core_sources += $(pgp_sources)
|
||
unittest_sources += $(pgp_unittest_sources)
|
||
endif
|
||
|
||
if BUILD_OTR
|
||
unittest_sources += $(otr_unittest_sources)
|
||
core_sources += $(otr4_sources)
|
||
endif
|
||
|
||
if BUILD_OMEMO
|
||
core_sources += $(omemo_sources)
|
||
unittest_sources += $(omemo_unittest_sources)
|
||
endif
|
||
|
||
sqlite_sources = src/database_sqlite.c
|
||
|
||
if BUILD_SQLITE
|
||
core_sources += $(sqlite_sources)
|
||
endif
|
||
|
||
all_c_sources = $(core_sources) $(unittest_sources) \
|
||
$(pgp_sources) $(pgp_unittest_sources) \
|
||
$(otr4_sources) $(otr_unittest_sources) \
|
||
$(omemo_sources) $(omemo_unittest_sources) \
|
||
$(c_sources) $(python_sources) \
|
||
$(main_source)
|
||
|
||
AM_CFLAGS = @AM_CFLAGS@ -I$(srcdir)/src
|
||
|
||
bin_PROGRAMS = profanity
|
||
profanity_SOURCES = $(core_sources) $(main_source)
|
||
if THEMES_INSTALL
|
||
profanity_themesdir = @THEMES_PATH@
|
||
profanity_themes_DATA = $(themes_sources)
|
||
endif
|
||
if INCLUDE_GIT_VERSION
|
||
BUILT_SOURCES = $(git_include)
|
||
endif
|
||
profanity_iconsdir = @ICONS_PATH@
|
||
profanity_icons_DATA = $(icons_sources)
|
||
|
||
if BUILD_C_API
|
||
lib_LTLIBRARIES = libprofanity.la
|
||
libprofanity_la_LDFLAGS = -version-info 0:0:0 -shared -no-undefined
|
||
libprofanity_la_SOURCES = src/plugins/profapi.c
|
||
|
||
library_includedir=$(includedir)
|
||
library_include_HEADERS = src/plugins/profapi.h
|
||
endif
|
||
|
||
TESTS = tests/unittests/unittests
|
||
check_PROGRAMS = tests/unittests/unittests
|
||
tests_unittests_unittests_CPPFLAGS = -I$(srcdir)/tests -I$(srcdir)/tests/unittests
|
||
tests_unittests_unittests_SOURCES = $(unittest_sources)
|
||
tests_unittests_unittests_LDADD = -lcmocka
|
||
|
||
# Functional tests require libstabber.
|
||
# They are only built when libstabber is available.
|
||
# See: https://github.com/profanity-im/profanity/pull/1010
|
||
# https://github.com/profanity-im/stabber/issues/5
|
||
#
|
||
# Note: We use forkpty() instead of libexpect for PTY handling.
|
||
|
||
if HAVE_STABBER
|
||
if HAVE_FORKPTY
|
||
TESTS += tests/functionaltests/functionaltests
|
||
check_PROGRAMS += tests/functionaltests/functionaltests
|
||
tests_functionaltests_functionaltests_SOURCES = $(functionaltest_sources)
|
||
tests_functionaltests_functionaltests_CPPFLAGS = -I$(srcdir)/tests
|
||
tests_functionaltests_functionaltests_CFLAGS = $(AM_CFLAGS)
|
||
tests_functionaltests_functionaltests_LDADD = -lcmocka -lstabber @FORKPTY_LIB@
|
||
|
||
# Parallel functional tests target (~3x faster than sequential)
|
||
# Usage: make check-functional-parallel
|
||
# To add more groups: increase FUNC_TEST_GROUPS and add group in functionaltests.c
|
||
FUNC_TEST_GROUPS = 1 2 3 4 5
|
||
|
||
check-functional-parallel: tests/functionaltests/functionaltests
|
||
@echo "Running functional tests in parallel ($(words $(FUNC_TEST_GROUPS)) groups)..."
|
||
@mkdir -p $(builddir)/test-logs $(builddir)/test-files
|
||
@pids=""; \
|
||
for g in $(FUNC_TEST_GROUPS); do \
|
||
./tests/functionaltests/functionaltests $$g > $(builddir)/test-logs/group$$g.log 2>&1 & \
|
||
pids="$$pids $$!"; \
|
||
done; \
|
||
failed=0; i=1; \
|
||
for pid in $$pids; do \
|
||
wait $$pid || { echo "Group $$i FAILED"; cat $(builddir)/test-logs/group$$i.log; failed=1; }; \
|
||
i=$$((i + 1)); \
|
||
done; \
|
||
echo "=== Test Results Summary ==="; \
|
||
grep -E 'PASSED|FAILED|Running' $(builddir)/test-logs/group*.log || true; \
|
||
if [ $$failed -ne 0 ]; then echo "FUNCTIONAL TESTS FAILED"; exit 1; fi; \
|
||
echo "All functional test groups passed!"
|
||
|
||
# Run functional tests with the flat-file database backend
|
||
# Usage: make check-functional-flatfile
|
||
check-functional-flatfile: tests/functionaltests/functionaltests
|
||
@echo "Running functional tests with flat-file backend ($(words $(FUNC_TEST_GROUPS)) groups)..."
|
||
@mkdir -p $(builddir)/test-logs $(builddir)/test-files
|
||
@pids=""; \
|
||
for g in $(FUNC_TEST_GROUPS); do \
|
||
PROF_FLATFILE=1 ./tests/functionaltests/functionaltests $$g > $(builddir)/test-logs/group$$g-flatfile.log 2>&1 & \
|
||
pids="$$pids $$!"; \
|
||
done; \
|
||
failed=0; i=1; \
|
||
for pid in $$pids; do \
|
||
wait $$pid || { echo "Group $$i FAILED (flatfile)"; cat $(builddir)/test-logs/group$$i-flatfile.log; failed=1; }; \
|
||
i=$$((i + 1)); \
|
||
done; \
|
||
echo "=== Flat-file Test Results Summary ==="; \
|
||
grep -E 'PASSED|FAILED|Running' $(builddir)/test-logs/group*-flatfile.log || true; \
|
||
if [ $$failed -ne 0 ]; then echo "FLAT-FILE FUNCTIONAL TESTS FAILED"; exit 1; fi; \
|
||
echo "All flat-file functional test groups passed!"
|
||
endif
|
||
endif
|
||
|
||
man1_MANS = $(man1_sources)
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Bench harness — synthetic database load tests. Not part of `make check`.
|
||
# Build only when invoked via `make bench` / `make bench-quick`.
|
||
# Sources live in tests/bench/. See tests/bench/README.md.
|
||
|
||
bench_common_sources = \
|
||
tests/bench/bench_stubs.c \
|
||
tests/bench/bench_common.c tests/bench/bench_common.h \
|
||
tests/bench/bench_csv.c tests/bench/bench_csv.h \
|
||
src/database_flatfile.c src/database_flatfile.h \
|
||
src/database_flatfile_parser.c \
|
||
src/database_flatfile_verify.c \
|
||
src/common.c src/common.h
|
||
|
||
# Sources needed only by the export/import bench (S7/S8). Pulls in the SQLite
|
||
# backend, the cross-backend export/import code, and the dispatcher.
|
||
bench_export_sources = \
|
||
src/database.c src/database.h \
|
||
src/database_sqlite.c \
|
||
src/database_export.c
|
||
|
||
EXTRA_PROGRAMS = \
|
||
tests/bench/gen_history \
|
||
tests/bench/bench_runner \
|
||
tests/bench/bench_long_messages \
|
||
tests/bench/bench_failure_modes \
|
||
tests/bench/bench_export_import
|
||
|
||
tests_bench_gen_history_SOURCES = tests/bench/gen_history.c $(bench_common_sources)
|
||
tests_bench_gen_history_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/tests/bench
|
||
tests_bench_gen_history_CFLAGS = $(AM_CFLAGS)
|
||
tests_bench_gen_history_LDADD =
|
||
|
||
tests_bench_bench_runner_SOURCES = tests/bench/bench_runner.c $(bench_common_sources)
|
||
tests_bench_bench_runner_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/tests/bench
|
||
tests_bench_bench_runner_CFLAGS = $(AM_CFLAGS)
|
||
tests_bench_bench_runner_LDADD =
|
||
|
||
tests_bench_bench_long_messages_SOURCES = tests/bench/bench_long_messages.c $(bench_common_sources)
|
||
tests_bench_bench_long_messages_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/tests/bench
|
||
tests_bench_bench_long_messages_CFLAGS = $(AM_CFLAGS)
|
||
tests_bench_bench_long_messages_LDADD =
|
||
|
||
tests_bench_bench_failure_modes_SOURCES = tests/bench/bench_failure_modes.c $(bench_common_sources)
|
||
tests_bench_bench_failure_modes_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/tests/bench
|
||
tests_bench_bench_failure_modes_CFLAGS = $(AM_CFLAGS)
|
||
tests_bench_bench_failure_modes_LDADD =
|
||
|
||
tests_bench_bench_export_import_SOURCES = tests/bench/bench_export_import.c \
|
||
$(bench_common_sources) $(bench_export_sources)
|
||
tests_bench_bench_export_import_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/tests/bench
|
||
tests_bench_bench_export_import_CFLAGS = $(AM_CFLAGS)
|
||
tests_bench_bench_export_import_LDADD =
|
||
|
||
# Volume control: BENCH_VOLUME={small|medium|max}. Default `small` is safe
|
||
# even on tight disks (~5 MB). `max` is heavyweight — see README.
|
||
BENCH_VOLUME ?= small
|
||
BENCH_DATA_DIR ?= /tmp/cproof-bench-corpus
|
||
BENCH_CSV ?= tests/bench/current.csv
|
||
|
||
bench-build: tests/bench/gen_history tests/bench/bench_runner tests/bench/bench_long_messages tests/bench/bench_failure_modes tests/bench/bench_export_import
|
||
|
||
# Resolve --lines / --years for the configured volume.
|
||
bench-gen: bench-build
|
||
@mkdir -p $(BENCH_DATA_DIR)
|
||
@case "$(BENCH_VOLUME)" in \
|
||
small) L=10000; Y=1; P=mixed ;; \
|
||
medium) L=500000; Y=5; P=mixed ;; \
|
||
max) L=5000000; Y=10; P=long ;; \
|
||
*) echo "BENCH_VOLUME must be small|medium|max"; exit 2 ;; \
|
||
esac; \
|
||
echo "==> generating volume=$(BENCH_VOLUME) lines=$$L years=$$Y profile=$$P"; \
|
||
./tests/bench/gen_history --lines=$$L --years=$$Y --msg-len-profile=$$P \
|
||
--lmc-rate=3 --mam-ooo-rate=0 --resources-per-contact=3 \
|
||
--output=$(BENCH_DATA_DIR) --seed=42
|
||
|
||
bench-run: bench-build
|
||
@echo "==> running scenarios (csv=$(BENCH_CSV))"
|
||
@BENCH_VOLUME=$(BENCH_VOLUME) BENCH_DATA_DIR=$(BENCH_DATA_DIR) \
|
||
./tests/bench/bench_runner --data=$(BENCH_DATA_DIR) --csv=$(BENCH_CSV)
|
||
@echo "==> CSV: $(BENCH_CSV)"
|
||
@cat $(BENCH_CSV)
|
||
|
||
bench: bench-gen bench-run
|
||
|
||
bench-quick:
|
||
@$(MAKE) bench BENCH_VOLUME=small
|
||
|
||
# Long-message tests (L1–L14). Independent of corpus volume, uses its own tmp dir.
|
||
bench-longmsg: bench-build
|
||
@echo "==> long-message tests (csv=$(BENCH_CSV))"
|
||
@./tests/bench/bench_long_messages \
|
||
--tmp=$(BENCH_DATA_DIR)-longmsg --csv=$(BENCH_CSV)
|
||
@rm -rf $(BENCH_DATA_DIR)-longmsg
|
||
|
||
# Failure-injection (F1–F15). Independent corpus, asserts behaviour on bad data.
|
||
bench-failure: bench-build
|
||
@echo "==> failure-injection tests (csv=$(BENCH_CSV))"
|
||
@./tests/bench/bench_failure_modes \
|
||
--tmp=$(BENCH_DATA_DIR)-fail --csv=$(BENCH_CSV)
|
||
@rm -rf $(BENCH_DATA_DIR)-fail
|
||
|
||
# Export/import (S7/S8) pipeline. Independent corpus under BENCH_DATA_DIR-export.
|
||
# Default scale: 100k rows (~5–30 s). Override with BENCH_PIPE_ROWS=N.
|
||
BENCH_PIPE_ROWS ?= 100000
|
||
|
||
BENCH_PIPE_VOLUME ?= pipe$(BENCH_PIPE_ROWS)
|
||
|
||
bench-export: bench-build
|
||
@echo "==> S7 export pipeline ($(BENCH_PIPE_ROWS) rows, csv=$(BENCH_CSV))"
|
||
@rm -rf $(BENCH_DATA_DIR)-export
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import seed --rows=$(BENCH_PIPE_ROWS) --account=bench@bench.example
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import export --account=bench@bench.example \
|
||
--csv=$(BENCH_CSV) --label=S7a_export_cold --volume=$(BENCH_PIPE_VOLUME)
|
||
@echo " -- second pass (dedup hot path)"
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import export --account=bench@bench.example \
|
||
--csv=$(BENCH_CSV) --label=S7b_export_dedup --volume=$(BENCH_PIPE_VOLUME)
|
||
@rm -rf $(BENCH_DATA_DIR)-export
|
||
|
||
bench-import: bench-build
|
||
@echo "==> S8 import pipeline ($(BENCH_PIPE_ROWS) rows, csv=$(BENCH_CSV))"
|
||
@rm -rf $(BENCH_DATA_DIR)-export
|
||
@# Seed account A, export it, then wipe its DB but keep flatlog. Import
|
||
@# back into the same account — that way the to: header in flatfile
|
||
@# matches the importing account so dedup works correctly.
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import seed --rows=$(BENCH_PIPE_ROWS) --account=bench@bench.example
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import export --account=bench@bench.example \
|
||
--csv=$(BENCH_CSV) --label=S7_seed_export --volume=$(BENCH_PIPE_VOLUME)
|
||
@rm -f $(BENCH_DATA_DIR)-export/database/bench_at_bench.example/chatlog.db*
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import import --account=bench@bench.example \
|
||
--csv=$(BENCH_CSV) --label=S8a_import_cold --volume=$(BENCH_PIPE_VOLUME)
|
||
@echo " -- second import (idempotency)"
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import import --account=bench@bench.example \
|
||
--csv=$(BENCH_CSV) --label=S8b_import_idempotent --volume=$(BENCH_PIPE_VOLUME)
|
||
@rm -rf $(BENCH_DATA_DIR)-export
|
||
|
||
# Full roundtrip with content diff at default volume. PASSes only if
|
||
# every row in the rebuilt DB matches the source byte-for-byte.
|
||
bench-roundtrip: bench-build
|
||
@echo "==> S8e roundtrip+full diff ($(BENCH_PIPE_ROWS) rows, csv=$(BENCH_CSV))"
|
||
@rm -rf $(BENCH_DATA_DIR)-export
|
||
@BENCH_DATA_DIR=$(BENCH_DATA_DIR)-export \
|
||
./tests/bench/bench_export_import roundtrip --rows=$(BENCH_PIPE_ROWS) \
|
||
--csv=$(BENCH_CSV) --label=S8e_roundtrip --volume=$(BENCH_PIPE_VOLUME) --full-diff
|
||
@rm -rf $(BENCH_DATA_DIR)-export
|
||
|
||
# Pipeline at medium volume (default BENCH_PIPE_ROWS=100k).
|
||
bench-pipeline: bench-export bench-import bench-roundtrip
|
||
|
||
# Pipeline at MAX volume — 1M rows. Heavy: ~5–10 min, ~500MB SQLite + ~500MB
|
||
# flatfile + ~500MB second SQLite. Run only when you can afford the time
|
||
# and the disk. Set BENCH_PIPE_ROWS_MAX to override (default 1_000_000).
|
||
BENCH_PIPE_ROWS_MAX ?= 1000000
|
||
bench-pipeline-max: bench-build
|
||
@echo "==> bench-pipeline-max: $(BENCH_PIPE_ROWS_MAX) rows (heavy!)"
|
||
@$(MAKE) bench-export BENCH_PIPE_ROWS=$(BENCH_PIPE_ROWS_MAX)
|
||
@$(MAKE) bench-import BENCH_PIPE_ROWS=$(BENCH_PIPE_ROWS_MAX)
|
||
@$(MAKE) bench-roundtrip BENCH_PIPE_ROWS=$(BENCH_PIPE_ROWS_MAX)
|
||
|
||
# S9: 200 contacts × 50k lines per contact = 10M lines distributed.
|
||
bench-multicontact: bench-build
|
||
@mkdir -p $(BENCH_DATA_DIR)-multi
|
||
@echo "==> S9: 200 contacts x 5000 lines"
|
||
@./tests/bench/gen_history --lines=1000000 --contacts=200 --years=3 \
|
||
--msg-len-profile=mixed --output=$(BENCH_DATA_DIR)-multi --seed=42
|
||
@BENCH_VOLUME=multicontact BENCH_DATA_DIR=$(BENCH_DATA_DIR)-multi \
|
||
./tests/bench/bench_runner --data=$(BENCH_DATA_DIR)-multi --csv=$(BENCH_CSV) \
|
||
--scenarios=S4,S6
|
||
@rm -rf $(BENCH_DATA_DIR)-multi
|
||
|
||
# S10: 30% LMC corrections.
|
||
bench-lmc: bench-build
|
||
@mkdir -p $(BENCH_DATA_DIR)-lmc
|
||
@echo "==> S10: LMC-heavy corpus (30%% corrections)"
|
||
@./tests/bench/gen_history --lines=100000 --years=2 --lmc-rate=30 \
|
||
--msg-len-profile=mixed --output=$(BENCH_DATA_DIR)-lmc --seed=42
|
||
@BENCH_VOLUME=lmc BENCH_DATA_DIR=$(BENCH_DATA_DIR)-lmc \
|
||
./tests/bench/bench_runner --data=$(BENCH_DATA_DIR)-lmc --csv=$(BENCH_CSV)
|
||
@rm -rf $(BENCH_DATA_DIR)-lmc
|
||
|
||
# S11: 20% MAM out-of-order timestamps.
|
||
bench-ooo: bench-build
|
||
@mkdir -p $(BENCH_DATA_DIR)-ooo
|
||
@echo "==> S11: MAM-OOO corpus (20%% out-of-order)"
|
||
@./tests/bench/gen_history --lines=100000 --years=2 --mam-ooo-rate=20 \
|
||
--msg-len-profile=mixed --output=$(BENCH_DATA_DIR)-ooo --seed=42
|
||
@BENCH_VOLUME=ooo BENCH_DATA_DIR=$(BENCH_DATA_DIR)-ooo \
|
||
./tests/bench/bench_runner --data=$(BENCH_DATA_DIR)-ooo --csv=$(BENCH_CSV) \
|
||
--scenarios=S6
|
||
@rm -rf $(BENCH_DATA_DIR)-ooo
|
||
|
||
# Run everything: P1 scenarios + long messages + failure injection + multicontact + LMC + OOO.
|
||
bench-full: bench bench-longmsg bench-failure bench-multicontact bench-lmc bench-ooo
|
||
|
||
# Compare current.csv against baseline.csv and exit non-zero on regressions.
|
||
BENCH_BASELINE ?= tests/bench/baseline.csv
|
||
BENCH_THRESHOLD ?= 25
|
||
bench-compare:
|
||
@python3 tests/bench/compare_baseline.py \
|
||
--baseline=$(BENCH_BASELINE) --current=$(BENCH_CSV) \
|
||
--threshold=$(BENCH_THRESHOLD)
|
||
|
||
# Snapshot current.csv as the new baseline. Run this only after manually
|
||
# reviewing that the numbers look healthy.
|
||
bench-update-baseline:
|
||
@cp $(BENCH_CSV) $(BENCH_BASELINE)
|
||
@echo "baseline updated: $(BENCH_BASELINE)"
|
||
|
||
bench-clean:
|
||
rm -rf $(BENCH_DATA_DIR) $(BENCH_DATA_DIR)-longmsg $(BENCH_DATA_DIR)-fail \
|
||
$(BENCH_DATA_DIR)-multi $(BENCH_DATA_DIR)-lmc $(BENCH_DATA_DIR)-ooo \
|
||
$(BENCH_DATA_DIR)-export $(BENCH_CSV)
|
||
|
||
.PHONY: bench bench-quick bench-build bench-gen bench-run bench-clean \
|
||
bench-longmsg bench-failure bench-multicontact bench-lmc bench-ooo \
|
||
bench-full bench-compare bench-update-baseline \
|
||
bench-export bench-import bench-roundtrip bench-pipeline bench-pipeline-max
|
||
|
||
EXTRA_DIST = $(man1_sources) $(icons_sources) $(themes_sources) $(script_sources) profrc.example theme_template LICENSE.txt README.md CHANGELOG
|
||
|
||
# Ship API documentation with `make dist`
|
||
EXTRA_DIST += \
|
||
apidocs/c/c-prof.conf \
|
||
apidocs/c/gen.sh \
|
||
apidocs/c/profapi.h \
|
||
apidocs/c/profhooks.h \
|
||
apidocs/python/conf.py \
|
||
apidocs/python/gen.sh \
|
||
apidocs/python/index.rst \
|
||
apidocs/python/Makefile \
|
||
apidocs/python/src/plugin.py \
|
||
apidocs/python/src/prof.py
|
||
|
||
# Bench harness sources (not built by default; see EXTRA_PROGRAMS above)
|
||
EXTRA_DIST += \
|
||
tests/bench/README.md \
|
||
tests/bench/compare_baseline.py \
|
||
tests/bench/gen_history.c \
|
||
tests/bench/bench_runner.c \
|
||
tests/bench/bench_long_messages.c \
|
||
tests/bench/bench_failure_modes.c \
|
||
tests/bench/bench_export_import.c \
|
||
tests/bench/bench_stubs.c \
|
||
tests/bench/bench_common.c tests/bench/bench_common.h \
|
||
tests/bench/bench_csv.c tests/bench/bench_csv.h \
|
||
tests/bench/baseline.csv
|
||
|
||
if INCLUDE_GIT_VERSION
|
||
EXTRA_DIST += .git/HEAD .git/index
|
||
|
||
$(git_include).in: .git/HEAD .git/index
|
||
rm -f $@
|
||
echo "#ifndef PROF_GIT_BRANCH" >> $@
|
||
echo "#define PROF_GIT_BRANCH \"$(shell git rev-parse --symbolic-full-name --abbrev-ref HEAD)\"" >> $@
|
||
echo "#endif" >> $@
|
||
echo "#ifndef PROF_GIT_REVISION" >> $@
|
||
echo "#define PROF_GIT_REVISION \"$(shell git log --pretty=format:'%h' -n 1)\"" >> $@
|
||
echo "#endif" >> $@
|
||
|
||
#
|
||
# Create $(git_include) atomically to catch possible race. The race can occur
|
||
# when $(git_include) is generated in parallel with building of src/profanity.c.
|
||
# So this hack allows to find and fix the problem earlier.
|
||
#
|
||
$(git_include): $(git_include).in
|
||
cp $< $@
|
||
|
||
clean-local:
|
||
rm -f $(git_include) $(git_include).in
|
||
endif
|
||
|
||
clean-functional-tests:
|
||
rm -rf $(builddir)/test-files $(builddir)/test-logs
|
||
|
||
.PHONY: my-prof.supp clean-functional-tests
|
||
my-prof.supp:
|
||
@sed '/^# AUTO-GENERATED START/q' prof.supp > $@
|
||
@printf "\n\n# glib\n" >> $@
|
||
@cat /usr/share/glib-2.0/valgrind/glib.supp >> $@
|
||
@printf "\n\n# Python\n" >> $@
|
||
@wget -O- https://raw.githubusercontent.com/python/cpython/refs/tags/v`python3 --version | cut -d' ' -f2`/Misc/valgrind-python.supp >> $@
|
||
@printf "\n\n# gtk\n" >> $@
|
||
@test -z "@GTK_VERSION@" || wget -O- https://raw.githubusercontent.com/GNOME/gtk/refs/tags/@GTK_VERSION@/gtk.supp >> $@
|
||
@printf "\n\n# more gtk\n" >> $@
|
||
@test -z "@GTK_VERSION@" || cat /usr/share/gtk-3.0/valgrind/gtk.supp >> $@
|
||
|
||
check-unit: tests/unittests/unittests
|
||
tests/unittests/unittests
|
||
|
||
@VALGRIND_CHECK_RULES@
|
||
VALGRIND_SUPPRESSIONS_FILES=$(srcdir)/prof.supp
|
||
|
||
# Code coverage targets (requires --enable-coverage)
|
||
coverage-clean:
|
||
find . -name '*.gcda' -delete
|
||
find . -name '*.gcno' -delete
|
||
rm -rf coverage-html coverage.info
|
||
|
||
coverage-report: check
|
||
lcov --capture --directory . --output-file coverage.info --ignore-errors inconsistent
|
||
lcov --remove coverage.info '/usr/*' '*/tests/*' --output-file coverage.info --ignore-errors inconsistent
|
||
genhtml coverage.info --output-directory coverage-html
|
||
@echo "Coverage report generated in coverage-html/index.html"
|
||
|
||
.PHONY: coverage-clean coverage-report
|
||
|
||
format: $(all_c_sources)
|
||
clang-format -i $(all_c_sources)
|
||
|
||
format-sources: $(core_sources) $(main_source)
|
||
clang-format -i $^
|
||
|
||
spell:
|
||
codespell
|
||
|
||
doublecheck: format check spell
|