Commit Graph

80 Commits

Author SHA1 Message Date
3f36c303c2 feat(history): flat-file backend with bidirectional SQLite migration
All checks were successful
CI Code / Check spelling (push) Successful in 21s
CI Code / Check coding style (push) Successful in 31s
CI Code / Code Coverage (push) Successful in 2m21s
CI Code / Linux (ubuntu) (push) Successful in 4m30s
CI Code / Linux (debian) (push) Successful in 6m43s
CI Code / Linux (arch) (push) Successful in 10m8s
A flat-file alternative to the SQLite chatlog backend with runtime
switching, full migration tooling, integrity verification, and a
synthetic load harness. SQLite remains the default; both backends share
one dispatch layer (db_backend_t vtable) so callers don't change.

Storage layout
- Per-contact append-only `flatlog/<account>/<contact>/history.log`
  under XDG_DATA_HOME, one line per message
- Single-line file header with embedded format-version marker
  (FLATFILE_FORMAT_VERSION); reader warns on missing or mismatched
  marker, writer and checker stay in sync via preprocessor
  stringification
- Deterministic key=value metadata (`id`, `aid`, `corrects`, `to`,
  `to_res`, `read`) plus escaped body \u2014 `\|`, `\]`, `\\`, `\n`, `\r`
  literals prevent log injection
- Sparse byte-offset index (FF_INDEX_STEP=500) per contact for
  O(log n) time-range lookups; rebuilt on inode / size / mtime
  change, extended in-place when the file just grew
- Per-contact GHashTable caches for archive_id presence and
  stanza_id \u2192 from_jid mapping (O(1) MAM dedup, O(1) LMC sender
  validation)

Hardening
- Path-traversal protection: JID directory name normalisation
  (`@` \u2192 `_at_`, slashes and `..` rejected at construction); every
  per-contact path is anchored under the account's flatlog/
  directory and validated before open
- Symlink-attack protection: every fopen / open uses O_NOFOLLOW; on
  ELOOP the operation aborts with an error rather than following
- Filesystem permissions: log files created with mode 0600,
  directories with mode 0700; both enforced at creation, verified
  on each open and reported on drift by `/history verify`
- Atomic crash-safe export: write to a temp file via mkstemp (mode
  0600, random suffix, no name collisions between concurrent
  exports), fsync, then rename \u2014 partial state never replaces the
  live file
- Concurrency: advisory flock(LOCK_EX) held for the duration of
  every write, including append from live messages and full rewrite
  from export, so two profanity processes can't interleave bytes
  on the same log
- DoS / abuse guards:
    * FF_MAX_LINE_LEN = 10 MB \u2014 lines longer than this are rejected
      at read with a warning; the parser will not allocate
      unbounded memory for a single record
    * FF_MAX_LMC_DEPTH = 100 \u2014 `corrects:` chain walk stops at this
      depth and emits a warning, preventing a malicious correction
      cycle from spinning the apply pass
    * FF_VERSION_SCAN_MAX = 16 \u2014 header version probe never reads
      past 16 leading comment lines, even on garbage input
    * Empty / inverted byte-range early-return in page-up read path
      so a malformed time filter cannot cause an unbounded scan
    * Zero-entry index guard so a file whose every line failed to
      parse cannot cause a NULL deref on later page-up
- LMC sender validation: an incoming correction whose sender does
  not match the original message's sender is rejected at write
  time and surfaced via cons_show_error; a cycle in the apply pass
  is broken via a visited-set
- jid_create_from_bare_and_resource treats NULL, empty string, and
  the literal "(null)" as no resource and returns a bare jid;
  similar normalisation for barejid eliminates the legacy
  "user@host/(null)" artefact that leaked into stored fulljids
  whenever g_strdup_printf("%s", NULL) ran inside create_fulljid

Commands
- `/history switch sqlite|flatfile` \u2014 runtime backend swap, closes
  the old backend and opens the new one without reconnecting
- `/history export [<jid>]` \u2014 SQLite -> flat-file, merging with any
  existing flatlog (dedup keyed on a SHA-256 hash mixing stanza_id,
  timestamp, from_jid, body \u2014 robust against id reuse by older
  clients)
- `/history import [<jid>]` \u2014 flat-file -> SQLite, same merge
  semantics, runs inside a single SQLite transaction with rollback
  on per-contact failure
- `/history verify [<jid>]` \u2014 integrity check; emits a structured
  list of issues (ERROR / WARNING / INFO) per file:
    * file-level: missing log, wrong permissions (\u2260 0600), UTF-8
      BOM present, CRLF line endings, empty file
    * line-level: invalid UTF-8 (with byte offset), embedded
      control characters, unparsable lines, timestamps out of
      order, duplicate `id:` and `aid:` (tracked separately so a
      stanza/archive id collision isn't double-reported)
    * cross-line: broken `corrects:` references whose target id is
      not present in the file
- `/history backend` \u2014 show currently active backend
- Active backend indicator `[sqlite]` / `[flatfile]` in the status
  bar next to the JID
- Roster-JID autocomplete for verify / export / import
- export and import open a SQLite handle on demand when the
  flatfile backend is currently active, so migration works
  regardless of which backend is live

Tests
- Unit: database_export (parser round-trip, escape/unescape, dedup
  key stability, JID normalisation), database_stress (14 cases
  exercising rapid writes, large messages, deep LMC chains, MAM
  dedup, concurrent contacts)
- Functional: history persistence across reconnects, export /
  import round-trip with content equality, MUC migration,
  timestamp normalisation across timezones
- Bench harness P1\u2013P5 (synthetic load: bulk insert, time-range
  read, page-up scroll, MAM ingest, mixed workload) and failure
  modes F1\u2013F17 (page-up cursor and forward-iteration symmetry,
  oversized lines, MAM dedup, LMC depth and cycles, BOM/CRLF,
  missing log, empty file, mtime+inode flip, broken corrects, etc.)
- All bench tests integrate with the existing make targets and
  emit CSV rows for baseline comparison

Author: jabber.developer2 <jabber.developer2@jabber.space>
Reviewed-by: jabber.developer <jabber.developer@jabber.space>
2026-05-05 19:26:07 +00:00
f84ed1bf6a perf(functests): speedup — profrc pre-baking, pty-close shutdown, parallel port pools
All checks were successful
CI Code / Check spelling (pull_request) Successful in 18s
CI Code / Check coding style (pull_request) Successful in 32s
CI Code / Code Coverage (pull_request) Successful in 2m46s
CI Code / Linux (debian) (pull_request) Successful in 4m30s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m29s
CI Code / Linux (arch) (pull_request) Successful in 4m44s
CI Code / Check spelling (push) Successful in 18s
CI Code / Check coding style (push) Successful in 33s
CI Code / Code Coverage (push) Successful in 3m4s
CI Code / Linux (ubuntu) (push) Successful in 4m29s
CI Code / Linux (debian) (push) Successful in 4m33s
CI Code / Linux (arch) (push) Successful in 4m48s
Replace 16 interactive UI setup commands with pre-written profrc file
containing [ui] and [notifications] sections (~1800ms saved per test).

Replace sleep(1) + blocking waitpid with close(pty fd) → SIGHUP →
polling waitpid(WNOHANG) → SIGTERM/SIGKILL fallback chain (~4900ms
saved per test).

Remove post-stbbr_start() and post-stbbr_stop() sleeps — bind+listen
completes synchronously before stbbr_start() returns, and
pthread_join() in stbbr_stop() guarantees socket cleanup (~200ms saved).

Add PORTS_PER_GROUP=50 isolated port ranges per test group to enable
safe parallel execution of 4 groups without port conflicts.
2026-03-12 18:20:35 +03:00
9e1b95a814 test(disco): remove disco_items_error_handling test
All checks were successful
CI Code / Check spelling (pull_request) Successful in 22s
CI Code / Check coding style (pull_request) Successful in 40s
CI Code / Linux (debian) (pull_request) Successful in 6m59s
CI Code / Linux (arch) (pull_request) Successful in 7m21s
CI Code / Linux (ubuntu) (pull_request) Successful in 7m13s
CI Code / Code Coverage (pull_request) Successful in 10m59s
CI Code / Check spelling (push) Successful in 20s
CI Code / Check coding style (push) Successful in 36s
CI Code / Code Coverage (push) Successful in 5m43s
CI Code / Linux (ubuntu) (push) Successful in 7m9s
CI Code / Linux (debian) (push) Successful in 10m5s
CI Code / Linux (arch) (push) Successful in 12m0s
This test requires the fix from fix/xep-0030-disco-items-error-handling
branch. Moved there along with the source code fix.
2026-03-03 16:57:35 +01:00
24e1dac354 test(disco): add comprehensive XEP-0030 functional tests
Add 7 new tests for /disco command:
- disco_items_to_jid: query items to specific JID
- disco_info_empty_result: handle empty disco#info response
- disco_info_multiple_identities: multiple identity elements
- disco_info_without_name: identity without optional name attr
- disco_items_without_name: items without optional name attr
- disco_info_service_unavailable: error handling for info
- disco_items_error_handling: error handling for items (XEP-0030 §7)

The disco_items_error_handling test documents a bug where disco#items
errors are silently ignored (unlike disco#info which handles them).
This violates XEP-0030 Section 7 which requires error feedback to user.
2026-03-03 16:57:35 +01:00
f20a4da160 Add functional tests for /disco command (XEP-0030)
- Add 8 tests for disco info and disco items commands
- Fix XEP-0030 compliance bug: show message for empty disco#items results
- Tests cover: identity display, features, server/jid queries, error handling,
  items display, empty results, and connection requirement
2026-03-03 16:57:35 +01:00
663a959f9c test: add functional tests for autoping (XEP-0199)
- autoping_set_interval: verify /autoping set command
- autoping_set_zero_disables: verify disabling autoping
- autoping_timeout_set: verify /autoping timeout command
- autoping_timeout_zero_disables: verify disabling timeout
- autoping_sends_ping_after_interval: verify automatic ping IQ
- autoping_server_not_supporting_ping: verify error handling

Fast tests (command parsing) in Group 1, slow tests (timer-based) in Group 3.
2026-03-03 16:57:35 +01:00
467222d0ca fix(ui,db): harden NULL handling, fix CWE-134, optimize iterations
Some checks failed
CI Code / Code Coverage (push) Failing after 10m34s
CI Code / Check spelling (push) Failing after 10m47s
CI Code / Check coding style (push) Failing after 11m4s
CI Code / Linux (ubuntu) (push) Failing after 11m19s
CI Code / Linux (debian) (push) Failing after 11m28s
CI Code / Linux (arch) (push) Failing after 11m38s
security(CWE-134): fix format string injections + add CI check
fix(ui): subwindow lifecycle, newwin/newpad guards, fallback timestamps
fix(db): sqlite cleanup on failures, sqlite3_close_v2
fix(xmpp): queued_messages loop, barejid leak
perf(core): g_hash_table_iter_init instead of g_hash_table_get_keys
refactor(ui): CLAMP macro in _check_subwin_width
test: XEP-0012 and XEP-0045 functional tests

Author: jabber.developer2
Closes #58, #85
2026-02-06 19:27:40 +01:00
f8826b7c79 ci: improve CI stability with parallel builds and Valgrind
All checks were successful
CI Code / Check spelling (push) Successful in 20s
CI Code / Check coding style (push) Successful in 33s
CI Code / Code Coverage (push) Successful in 4m47s
CI Code / Linux (debian) (push) Successful in 6m9s
CI Code / Linux (ubuntu) (push) Successful in 6m13s
CI Code / Linux (arch) (push) Successful in 6m19s
Major changes:
Run 4 build configurations in parallel with Valgrind on Linux
Add test failure detection verification (meta-test)
Port allocation per build to prevent conflicts in parallel runs
Add --coverage-only flag for dedicated coverage builds
Code quality:

Add TEST_GROUPS constant, CMOCKA patterns, helper functions
Organize ci-build.sh into sections
2026-02-02 17:47:05 +01:00
85c817ee8c ci: speed up builds 4x with parallel tests, coverage, and ccache
All checks were successful
CI Code / Check spelling (push) Successful in 18s
CI Code / Check coding style (push) Successful in 31s
CI Code / Code Coverage (push) Successful in 15m25s
CI Code / Linux (debian) (push) Successful in 15m57s
CI Code / Linux (ubuntu) (push) Successful in 16m0s
CI Code / Linux (arch) (push) Successful in 16m6s
Split functional tests into 4 parallel groups and add check-functional-parallel target (~3x faster CI runs).
Add branch-aware LCOV coverage reporting with new --enable-coverage option and lcov summary in CI pipeline.
Enable ccache via -C configure flag for faster recompilations.
Install lcov in all Docker images and use --depth 1 git clones + parallel make -j$(nproc) for quicker container builds.
Update CONTRIBUTING.md with instructions for parallel test groups and adding new ones.

All changes are tightly related CI/performance improvements developed in sequence. No external service uploads (e.g. Codecov skipped due to Gitea incompatibility).
2026-01-21 16:35:17 +01:00
8f580f91a8 refactor(tests): migrate to content-based stubbing
- Replace stbbr_for_id() with stbbr_for_query()/stbbr_send()
- Content-based stubbing matches stanzas by namespace instead of ID
- Use regex assertions for flexible output matching
- Fix timing issues in chat_session and presence tests
2026-01-07 11:46:40 +01:00
2d7de2caf6 refactor(tests): replace libexpect with forkpty() for PTY handling
- Remove dependency on libexpect/tcl
- Implement native PTY handling with forkpty()
- Add prof_output_exact/regex for flexible output matching
- Improve timeout handling and synchronization
2026-01-07 11:46:40 +01:00
Steffen Jaeckel
988d3663d1 Introduce tests/prof_cmocka.h
As 9f2abc75 accidentally got the ordering of some of the includes wrong,
I decided to propose my initial solution again.

Additional to that, I've opened a MR against CMocka to solve this on
their side, since I believe that the current way this is done is not
sustainable [0].

[0] https://gitlab.com/cmocka/cmocka/-/merge_requests/91

Fixes: 9f2abc75 ("Fix tests with gcc15 (uintptr_t)")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>

CProof note: our new tests need to also be updated.
2025-09-10 14:11:03 +02:00
2808def933 fix(chatwin): Fix LMC autocompletion to suggest corrected message content
All checks were successful
CI / Check spelling (pull_request) Successful in 18s
CI / Check coding style (pull_request) Successful in 33s
CI / Linux (debian) (pull_request) Successful in 9m45s
CI / Linux (ubuntu) (pull_request) Successful in 10m0s
CI / Linux (arch) (pull_request) Successful in 16m48s
- Modified chatwin_outgoing_msg to call _chatwin_set_last_message for corrected messages, using replace_id per XEP-0308.
- Updated _chatwin_set_last_message to skip redundant and invalid free/strdup for same pointers.
- Added null checks in _chatwin_set_last_message for safety.
- Fixes autocompletion suggesting original message content instead of corrected content.

Fixes #24
2025-09-02 00:29:13 +02:00
5ed8ec30f0 Update name and license
All checks were successful
CI / Linux (debian) (pull_request) Successful in 11m26s
CI / Linux (arch) (pull_request) Successful in 13m51s
CI / Linux (fedora) (pull_request) Successful in 12m27s
CI / Check coding style (pull_request) Successful in 30s
CI / Check spelling (pull_request) Successful in 14s
CI / Linux (ubuntu) (pull_request) Successful in 11m43s
CI / Linux (debian) (push) Successful in 11m31s
CI / Linux (arch) (push) Successful in 13m51s
CI / Linux (fedora) (push) Successful in 12m16s
CI / Check coding style (push) Successful in 29s
CI / Check spelling (push) Successful in 17s
CI / Linux (ubuntu) (push) Successful in 11m49s
2025-07-19 14:32:26 +02:00
ike08
d35a7a7f7e Refactor tests to use the new cmocka test runner
## Summary

Fixes https://github.com/profanity-im/profanity/issues/1907  

Update functional and unit test code to comply with the current cmocka test runner.  

## Changes

- `UnitTest` struct to `CMUnitTest` struct
- `unit_test()` macro to `cmocka_unit_test(f)` macro
- `unit_test_setup_teardown()` macro to `cmocka_unit_test_setup_teardown` macro
- `run_tests()` macro to `cmocka_run_group_tests()` function
- Setup and teardown functions return `int` instead of `void`

## Testing

### Unit Tests

`make check`

### Functional Tests

I did not compile or run functional tests because they are *shelved* for now.

### Valgrind

I'm not entirely sure how to fun Valgrind in this case. I did not do fancy memory management, so it should be fine.
2023-11-01 18:30:08 -06:00
John Hernandez
5b8b9074a2 Add nickname support for /roster remove
Add support of name/nickname instead of only JID for `/roster remove` command.

Add tests for it as well.
2023-04-13 16:41:21 +02:00
a1346054
a1dc3d1237 Trim excess whitespace 2021-08-26 01:18:10 +00:00
Michael Vetter
693fdcce65 functest: Make char const 2020-10-15 10:12:33 +02:00
Michael Vetter
12cafe4e60 Add include for waitpid to functionaltest 2020-06-04 12:02:02 +02:00
Michael Vetter
a28f0d9e74 Update tests with new URL
https://github.com/profanity-im/profanity/issues/1085
2019-05-03 10:46:41 +02:00
Paul Fariello
a952776b89 Rename mucconf wins into conf wins
Configuration windows are now being used by both muc and cmd.
2018-09-05 13:51:00 +02:00
James Booth
ee664bf1d2 Add room /me functional tests 2018-04-21 20:40:11 +01:00
James Booth
e571ccd8ea Fix tests, move glob creation 2018-01-27 23:51:03 +00:00
James Booth
f189dbc687 Only send ping requests to client that support it 2017-06-16 00:59:21 +01:00
James Booth
970ab94ed3 Change server name in functional tests 2017-06-15 23:30:39 +01:00
James Booth
6511d61b13 Show message when server does not support ping 2017-06-15 23:27:30 +01:00
James Booth
8e75437a7e Add carbons from check 2017-01-23 22:25:36 +00:00
James Booth
2b7894ccff Remove status from cl_ev_presence_send
fixes #888
2017-01-15 23:59:31 +00:00
James Booth
e043029a50 Allow clearing account resource
issue #880
2016-11-22 00:39:52 +00:00
James Booth
609d05366c Use server features for account muc service
issue #878
2016-11-20 02:09:34 +00:00
James Booth
388a20813c Tests: disable occupants panel in functional tests 2016-09-26 00:39:37 +01:00
James Booth
e78684f689 Tests: longer timeout for failing functional test on travis 2016-09-26 00:16:12 +01:00
James Booth
fca59a3110 log_info on private carbons 2016-08-28 17:27:26 +01:00
James Booth
a978bb12bf Send receipt request only when receiver supports feature
issue #829
2016-08-18 22:53:23 +01:00
James Booth
b8c94376aa Add /blocked command 2016-05-01 19:39:39 +01:00
James Booth
167553ae8f Fixed functional test ID based stubs 2016-04-26 23:50:55 +02:00
James Booth
9b177a9e01 Removed #AX_PREFIX_CONFIG_H 2016-03-31 21:05:02 +01:00
James Booth
41fe8c22b1 Added C plugin code from plugins branch 2016-02-14 22:28:55 +00:00
James Booth
e1e0fda8b3 Call UI disconnect functions before disconnecting with /disconnect
fixes #703
2016-01-05 01:30:32 +00:00
James Booth
69ac809776 Added functional tests for /console command 2015-12-30 00:32:52 +00:00
James Booth
7f98e013e1 Use single quotes in functional test stanzas 2015-12-30 00:12:24 +00:00
James Booth
377a63d038 Uncommented functional tests 2015-12-22 00:45:15 +00:00
James Booth
6303e0e25a Added chat message functional tests 2015-12-22 00:27:37 +00:00
James Booth
d9f5a2bda6 Updated console new message text 2015-12-20 23:26:05 +00:00
James Booth
1b88b5706e Change console incoming message text to include "win" 2015-12-20 22:50:03 +00:00
James Booth
94169705b5 Added functional test for muc console message 2015-12-20 03:11:02 +00:00
James Booth
9f34373b46 Disable muc notifications for functional tests 2015-12-20 02:57:01 +00:00
James Booth
c61e9d80ea Added more muc functional tests 2015-12-20 02:42:11 +00:00
James Booth
46a0e6ebed Removed whitespace 2015-12-20 02:17:17 +00:00
James Booth
87b4d7cbab Added muc functional tests 2015-12-20 02:13:01 +00:00