Pure functions only, per AGENT-CORE.md's build order: no I/O, no JSON, no SQL,
no notion of the wire Rule type — DAEMON decodes its own stored/wire
representation into these plain structs and calls in.
- rules/filename.hpp: sanitize_filename() turns a raw candidate (from
net::parse_content_disposition or net::url_filename — neither is
filesystem-safe by design; both headers say so and point here) into one
safe to create on ext4/APFS/NTFS: strips separators and control bytes,
folds NTFS-illegal characters, neutralizes reserved Windows device names,
clamps length on a UTF-8 boundary. Total on hostile input; never empty.
Not the path-traversal security boundary — that's daemon/fs/safepath,
downstream of this and the one that actually matters adversarially.
- rules/collision.hpp: resolve_collision() finds the next free name
Explorer/Finder-style ("name (1).ext", ...) given an existence predicate,
or returns the desired name unchanged under an overwrite policy. Never
fabricates a guaranteed-unique name past its attempt bound — hands back
the last candidate tried rather than hiding a persistent collision.
- rules/match.hpp: match_rules() is the evaluation half of
contracts/schema/types/Rule.schema.json — priority order, first rule
whose present match clauses (extensions/mimeTypes/host & url glob/size
bounds) all hold, wins; a size clause never matches speculatively before
the probe fills in size_bytes. glob_match() is the iterative (not
recursive — bounded work on an all-'*' pattern) matcher both host_pattern
and url_pattern use.
Every header compiles standalone; tests (39 cases) pass under ASan+UBSan and
TSan. core/include/vdm/README.md documents the new public surface.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Q3QrF7rCt21bkAjt9BCDFQ
62 lines
3.0 KiB
CMake
62 lines
3.0 KiB
CMake
# CORE unit tests.
|
|
#
|
|
# Harness is the provisional header-only vtest (support/vtest.hpp); PKG owns the final
|
|
# framework choice (core/docs/pkg-requests-m1.md P2). vdm_add_test() is the only thing
|
|
# test files touch, so swapping harnesses is a one-function edit.
|
|
|
|
add_library(vtest_main STATIC support/vtest_main.cpp)
|
|
target_include_directories(vtest_main PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/support)
|
|
target_compile_features(vtest_main PUBLIC cxx_std_23)
|
|
|
|
function(vdm_add_test name)
|
|
add_executable(${name} ${ARGN})
|
|
target_link_libraries(${name} PRIVATE veloxcore vtest_main)
|
|
target_compile_options(${name} PRIVATE -Wall -Wextra -Wpedantic -Werror)
|
|
add_test(NAME ${name} COMMAND ${name})
|
|
endfunction()
|
|
|
|
vdm_add_test(veloxcore_result_test util/result_test.cpp)
|
|
vdm_add_test(veloxcore_event_bus_test util/event_bus_test.cpp)
|
|
vdm_add_test(veloxcore_thread_pool_test util/thread_pool_test.cpp)
|
|
vdm_add_test(veloxcore_bytes_test util/bytes_test.cpp)
|
|
vdm_add_test(veloxcore_log_test util/log_test.cpp)
|
|
|
|
# net/ integration tests drive tools/testserver (lane PKG/QA). Skip cleanly if it isn't
|
|
# in the tree yet (lanes merge independently).
|
|
vdm_add_test(veloxcore_content_disposition_test net/content_disposition_test.cpp)
|
|
vdm_add_test(veloxcore_url_test net/url_test.cpp)
|
|
vdm_add_test(veloxcore_sparse_file_test io/sparse_file_test.cpp)
|
|
vdm_add_test(veloxcore_write_buffer_test io/write_buffer_test.cpp)
|
|
vdm_add_test(veloxcore_veloxpart_test meta/veloxpart_test.cpp)
|
|
vdm_add_test(veloxcore_segmenter_test segment/segmenter_test.cpp)
|
|
vdm_add_test(veloxcore_budget_test segment/budget_test.cpp)
|
|
vdm_add_test(veloxcore_engine_api_test task/api_compiles_test.cpp)
|
|
vdm_add_test(veloxcore_token_bucket_test rate/token_bucket_test.cpp)
|
|
|
|
set(_testserver ${CMAKE_SOURCE_DIR}/tools/testserver/testserver.py)
|
|
vdm_add_test(veloxcore_engine_test task/engine_test.cpp)
|
|
target_include_directories(veloxcore_engine_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/net ${CMAKE_SOURCE_DIR}/core/src)
|
|
if(EXISTS ${_testserver})
|
|
target_compile_definitions(veloxcore_engine_test PRIVATE VDM_TESTSERVER_PY="${_testserver}")
|
|
set_tests_properties(veloxcore_engine_test PROPERTIES TIMEOUT 300)
|
|
endif()
|
|
|
|
foreach(net_it http_client probe)
|
|
vdm_add_test(veloxcore_${net_it}_test net/${net_it}_test.cpp)
|
|
target_include_directories(veloxcore_${net_it}_test
|
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/net)
|
|
if(EXISTS ${_testserver})
|
|
target_compile_definitions(veloxcore_${net_it}_test
|
|
PRIVATE VDM_TESTSERVER_PY="${_testserver}")
|
|
set_tests_properties(veloxcore_${net_it}_test PROPERTIES TIMEOUT 120)
|
|
endif()
|
|
endforeach()
|
|
if(NOT EXISTS ${_testserver})
|
|
message(STATUS "veloxcore: tools/testserver not present; net integration tests will "
|
|
"skip their server-backed cases.")
|
|
endif()
|
|
|
|
vdm_add_test(veloxcore_rules_filename_test rules/filename_test.cpp)
|
|
vdm_add_test(veloxcore_rules_collision_test rules/collision_test.cpp)
|
|
vdm_add_test(veloxcore_rules_match_test rules/match_test.cpp)
|