* Add unit test for psync_task_free refcount fix (#377)
Adds tests/unit-tests/test_ptask_free.c to verify all code paths of the
psync_task_free fix from #377: single-owner free, last-ref destroy,
non-last-ref decrement, READY task signaling, and lock-before-refcnt
ordering. All 5 tests pass. Also adds compiled binary to .gitignore.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Refactor test_ptask_free to link production code via --wrap
Extract psync_task_free + psync_task_destroy (and their static helpers
psync_task_dec_refcnt, psync_task_entry) from ptask.c into a new
separately-compilable unit pclsync/ptask_free.c. Add
pclsync/ptask_free_internal.h to expose the internal struct layout
(struct psync_task_manager_t_ / struct psync_task_t_) for test use
without pulling in ptask.c's heavyweight transitive dependencies.
Rewrite tests/unit-tests/test_ptask_free.c to:
- Include ptask_free_internal.h instead of duplicating structs inline
- Call the real psync_task_free() rather than a local replica
- Intercept pthread_mutex_lock/unlock and pmem_free via --wrap linker
flags to observe lock discipline and detect destroy invocations
Update the Makefile test_ptask_free target to link pclsync/ptask_free.c
and pass the required --wrap flags. Production build unchanged: ptask_free.o
is picked up automatically by the existing wildcard COBJ rule.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Implement Tasks #3, #4, #5: tree tests, pfstasks tree layer, DB harness
Task #3 — Unit tests for ptree and pintervaltree
tests/unit-tests/test_ptree.c: 8 tests covering single-node insert,
in-order traversal after arbitrary and reverse inserts, BST lookup,
leaf/root/all-node deletion, and ptree_for_each visitation.
tests/unit-tests/test_pintervaltree.c: 18 tests covering single add,
non-overlapping, overlapping/adjacent/contained/spanning merges,
chain merge, remove middle split, remove exact/left/right/spanning,
cut_end, first_interval_containing_or_after, and free(NULL).
Task #4 — Extract pfstasks tree layer
pclsync/pfstasks_tree.h + pclsync/pfstasks_tree.c: pure tree layer
(zero psql calls) extracted from pfstasks.c — pfs_task_search_tree,
pfs_task_walk_tree (static helpers), pfs_task_insert_into_tree,
pfs_task_find_mkdir/rmdir/creat/unlink,
pfs_task_find_mkdir_by_folderid, pfs_task_find_creat_by_fileid.
pclsync/pfstasks.c: #includes pfstasks_tree.h; all moved functions
removed; all callers unchanged.
tests/unit-tests/test_pfstasks_tree.c: 13 tests using direct tree
construction (no DB) to verify find-by-name, taskid discrimination,
find-by-numeric-id, and empty-folder edge cases.
Task #5 — psql in-memory harness + pfstasks DB tests
tests/helpers/psql_test_helpers.h + .c: lightweight harness that
opens :memory: via sqlite3_open, enables PRAGMA foreign_keys=ON, and
applies the full PSYNC_DATABASE_STRUCTURE schema. Exposes
psql_test_db(), psql_test_exec(), psql_test_insert_fstask(),
psql_test_count_fstask/fstaskdepend(). No dependency on psql.c.
tests/unit-tests/test_pfstasks_db.c: 10 tests verifying schema
creation, fstask insertion/query, fstaskdepend insertion, CASCADE
DELETE propagation, FK enforcement, rmdir-blocking SQL pattern,
creat-after-unlink sequencing, and open/close idempotence.
All 11 new tests pass; production build clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix P1 review findings in pfstasks_db test and helpers
1. Check psql_test_exec() return values in test_cascade_delete() and
test_creat_after_unlink() consistently with test_fstaskdepend_insert().
2. Remove dead dep_cnt variable and (void)dep_cnt suppressor from
test_creat_after_unlink().
3. Change SQLITE_STATIC → SQLITE_TRANSIENT for text1 binding in
psql_test_insert_fstask() to avoid dangling-pointer footgun on
future reuse.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix ASAN/LSAN failures: ppath_home stack-use-after-scope + intentional leak
pclsync/ppath.c: Move buff[4096] to function scope in ppath_home() so
the pointer stored in dir via result->pw_dir remains live through the
putil_strdup(dir) call. Previously buff went out of scope at the if-block
close, causing a stack-use-after-scope ASAN report on every call that fell
through the getpwuid_r path.
tests/unit-tests/test_ptools_errptr.c: run_unfixed() intentionally leaks
errPtr to demonstrate the pre-fix bug. Wrap the allocation with
LSAN_DISABLE() / LSAN_ENABLE() so LSAN does not abort the process at exit
before stdio flushes, which was causing a non-zero exit code. The guard
uses nested #ifdef/__has_feature to remain compatible with both GCC
(__SANITIZE_ADDRESS__) and Clang (__has_feature(address_sanitizer))
without triggering "missing binary operator" errors on GCC.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Implement Tasks #11 and #12: plocks stress test + pfsupload send tests
Task #11 — plocks.c stress test (test_plocks.c)
7 tests: basic rdlock/wrlock round-trip, recursive TLS counting (same
thread acquires rdlock N times; unlock only releases on final decrement),
upgrade under contention (N readers + towrlock; barrier-synchronized),
writer starvation prevention (sustained reader load; writer acquires
within 500ms), N-reader + M-writer counter-integrity stress test (ASAN),
and try-variant contention (trywrlock fails when another thread holds
rdlock). TSAN note documented: custom lock internals require ASAN-only
when ThreadSanitizer annotations are absent.
Task #12 — pfsupload send-function tests (pfsupload_send.c/h + test_pfsupload.c)
Extract psync_send_task_mkdir and psync_send_task_rmdir from pfsupload.c
into pclsync/pfsupload_send.c as non-static pfsupload_send_mkdir/rmdir.
Expose fsupload_task_t struct via pclsync/pfsupload_send.h. Add
__attribute__((weak)) get_urls() as an injectable URL seam for large-
upload paths. pfsupload.c updated to include pfsupload_send.h and use
the renamed functions in its dispatch table; pfsupload_send.o is
automatically picked up by the production wildcard build.
5 tests: mkdir (non-encrypted) command + folderid param, mkdir
(encrypted) key param present, rmdir command + sfolderid, API error path
(papi_send failure → -1), get_urls() weak override. Uses
--wrap=papi_send to intercept API calls and socketpair() to provide a
valid psock_t without real network I/O.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* P2 cleanup: comments, make_fake_api stack alloc, find_str_param fix
1. test_plocks.c: add comment to test_upgrade_under_contention clarifying
it verifies towrlock completion and holding_wrlock; notes that concurrent
exclusivity is covered by test_stress().
2. test_pfsupload.c / make_fake_api: replace static-local psock_t with
caller-supplied stack allocation (out parameter) to eliminate the
multiple-calls-per-test footgun.
3. test_pfsupload.c / find_str_param: replace ternary
`paramnamelen == strlen ? paramname : ""` with explicit length check +
strncmp, matching the cleaner pattern used in find_num_param.
4. Makefile: add comment next to -Wl,--wrap=papi_send noting it redirects
papi_send to __wrap_papi_send and is GNU ld only (not macOS Apple ld).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add unit test for psync_task_free refcount fix (#377)
Adds tests/unit-tests/test_ptask_free.c to verify all code paths of the
psync_task_free fix from #377: single-owner free, last-ref destroy,
non-last-ref decrement, READY task signaling, and lock-before-refcnt
ordering. All 5 tests pass. Also adds compiled binary to .gitignore.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add GitHub Actions CI workflow for unit tests
Triggers on push/PR to automated-testing branch. Installs cmake and
build-essential, builds all test targets via cmake, and runs ctest
--output-on-failure. Fails workflow on any test failure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Replace cmake CI with make tests/check targets
Adds tests and check targets to Makefile — no cmake required.
Each test binary is built with the correct flags (pthread, -lrt,
--wrap linker flags for prun/ptools_errptr). CI workflow installs
only build-essential, runs make tests then make check; exits non-zero
on any failure. All 8 test suites pass locally.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix CI: install libfuse3-dev so Makefile parses on Ubuntu
detect_fuse.sh runs at Makefile parse time; without fuse headers the
$(error) fires before any target runs. Adding libfuse3-dev unblocks
make tests (test binaries themselves don't link fuse).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix makefile
* Add automated testing infrastructure
- Update CI workflow to run unit tests and build verification
- Add Makefile targets for test compilation and execution
- Implement unit tests for pdbg_path, prun, and read_response
- Add test stubs for pCloud API mocking
- Add test binaries for pfs_lock_ordering and signal_safety verification
* Add missing dependencies to CI workflow
Install libfuse-dev and libssl-dev required for build
* Add test job to c-cpp.yml workflow
Include unit test execution in C/C++ workflow
* Add missing stubs to test_stubs.c
Complete stub implementations for all required pCloud API functions
* Fix stub signatures to match headers
Correct function signatures for pCloud API stubs
* Fix psql_* stub signatures
Correct all psql function signatures to match headers
* Fix stub implementations and Makefile
Update stub functions and build configuration
* Link real utility files instead of stubbing
Update Makefile to use actual implementation files for utilities
* Complete test framework with all 41 tests passing
- Makefile: Add test rules with real dependencies
- tests/stubs/test_stubs.c: Minimal stubs for external APIs
- tests/stubs/test_stubs_cpp.c: Stubs for C++ test
- pclsync/putil.c: Add null check in putil_strdup
- pclsync/pdbg.c: Add recursion guard in pdbg_printf
* Remove duplicate ci.yml workflow
Consolidate CI configuration into c-cpp.yml
* Remove compiled test binaries from git
- Remove test_pfs_lock_ordering and test_signal_safety binaries
- Add tests/test_* to .gitignore to prevent future commits
---------
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace fopen() with open()+fdopen() for all log file creation
in pdbg.c to ensure files are created with mode 0600, preventing
world-readable logs that may contain sensitive information.
Fixes#290
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
* small lsp error fixes
* simplify messaging and remove serialize/deserialize
- messaging is reverted to API requests and responses only
- remove serialize and deserialize functions
- implement shared memory (pshm) for overlay callback return values
* fix memory leak
Fix#64 and #71
* openssl is a dependency
* openssl is not a real dpendency
* static link by default
* wip: build containers
* rm comments
* build containers, fix DEADLYSIGNAL on run with no args
* debug tools in deb/ubuntu, fix#44
* no slack container :(
* ensure P_LINUX_OS always defined
* error check fuse unmount ops
* fsanitize=thread temporarily
* undo
* clang static analysis
* fix dead assignment
* makefile quality of life stuff
* make install and uninstall; ignore scan results
* addressed dead assignments from static analysis
* debug and release builds possible
* gcc still default compiler
* debug symbols on debug build only
* reorg source tree, link system mbedtls
* remove cmakelists.txt
* update ci workflow
* -Werror to -Wall
* libpcloudcc_so in makefile
* single makefile works
* removed extra makefiles
* tagged mbedtls lib with version
* added source tree for mbedtls 2.1.14
* pcloudcc compiles with upgraded library mbedtls-2.x
* working on a segfault
* Revert "pcloudcc compiles with upgraded library mbedtls-2.x"
This reverts commit 8ccdb71ab8.
* build with debugging symbols
* trying a different approach; upgrading pupload.c
* updated mbedtls headers, using compat header
* all but pssl now using new headers
* updated pssl.h dependencies
* mbedtls2 rename.pl on all but pssl.{c,h}
* removed more commented code
* removed mbedtls-1.x from cmakelists
* program compiles with mbedtls 2.x, but remains offline.. why?
* removed mbedtls-1.x from source tree
* fixed handshake, now peer cert returning null
* mbedtls upgrade to 2.x completed!
* compat header removed; startcrypto no longer working
* fix start_crypto handler; need to check ret == 0
* fix linking problem on first login
* fixed startcrypto!