* test(search,daemon,storage): assert behaviour instead of frozen literals Several suites encoded exact internal values that legitimate tuning and ranking changes are allowed to move: SCIENTIFIC-era profile weights and rrfK values, corpus-statistic figures, and hardcoded timeout/cancellation numbers. They failed on every platform after those changes landed, so the real behaviour regressions they should catch were hidden behind noise. Replace the frozen literals with contract assertions: weights are finite, non-negative and normalize, state selection still holds, capability-gated sources stay zeroed, and hybrid results keep matching canonical hash/path sets. Deadlines are not widened and the daemon paths they cover are unchanged. Also add independent corpus and adapter oracles, deterministic collector cancellation and late-result gates, and synchronize ServiceManager shutdown observation, so the tests fail for the behaviour they name. The portability allowlist keeps its two reviewed raw test-env reads; only their line numbers moved. Signed-off-by: trvon <git@trevon.dev> * ci(tests): summarise Meson failures without flooding the log A failing test run printed the whole Meson suite output, so the actual failing test names and their assertion messages were buried and the uploaded logs were dominated by passing-test chatter. Add a bounded reporter that extracts the failing test names plus their surrounding diagnostics, keeps an overall cap on emitted lines, and is unit-tested against representative Meson output. Wire it into the Tests workflow so failures stay readable. Signed-off-by: trvon <git@trevon.dev> * build(deb): validate candidate identity, mapping and upgrade ordering The Debian packaging scripts took filenames and versions on trust, so a misnamed candidate or a wrong package ordering could pass validation while the real install path was never exercised. Fail closed on candidate identity, version and architecture, verify the package-to-source mapping, seed the legacy-only layout, wait on the actual services, and assert install/upgrade/remove ordering for both Debian and RPM in an offline container. Cases that cannot be proven on a host are reported as skipped rather than silently passing. Signed-off-by: trvon <git@trevon.dev> --------- Signed-off-by: trvon <git@trevon.dev>
177 lines
6.1 KiB
Meson
177 lines
6.1 KiB
Meson
plugin_build_dir = meson.project_build_root()
|
|
if host_machine.system() == 'windows'
|
|
plugin_ext = '.dll'
|
|
elif host_machine.system() == 'darwin'
|
|
plugin_ext = '.dylib'
|
|
else
|
|
plugin_ext = '.so'
|
|
endif
|
|
|
|
plugin_test_ld_library_path = ':'.join([
|
|
join_paths(plugin_build_dir, 'src/daemon/resource'),
|
|
plugin_build_dir,
|
|
'/opt/yams/usr/local/lib',
|
|
])
|
|
|
|
zyp_pdf_metadata_test_exe = executable('yams_zyp_pdf_metadata_tests',
|
|
files(
|
|
'zyp/pdf_metadata_catch2_test.cpp',
|
|
'../../plugins/zyp/pdf_metadata.cpp',
|
|
),
|
|
include_directories: incs,
|
|
dependencies: [catch2_dep, catch2_main_dep] + test_deps,
|
|
install: false,
|
|
)
|
|
|
|
test('zyp_pdf_metadata', zyp_pdf_metadata_test_exe,
|
|
suite: ['unit', 'plugins', 'zyp', 'catch2'],
|
|
timeout: 30,
|
|
)
|
|
|
|
# ONNX plugin ABI tests
|
|
onnx_plugin_runtime_deps = get_variable('yams_onnx_plugin_target', [])
|
|
if get_option('plugin-onnx') and onnx_plugin_runtime_deps.length() > 0
|
|
if host_machine.system() == 'windows'
|
|
onnx_plugin_filename = 'yams_onnx_plugin' + plugin_ext
|
|
else
|
|
onnx_plugin_filename = 'libyams_onnx_plugin' + plugin_ext
|
|
endif
|
|
onnx_plugin_path = join_paths(plugin_build_dir, 'plugins/onnx', onnx_plugin_filename)
|
|
onnx_plugin_exe = executable('yams_onnx_plugin_tests',
|
|
files(
|
|
'onnx_request_plugin_catch2_test.cpp',
|
|
'onnx_provider_plugin_catch2_test.cpp',
|
|
),
|
|
include_directories: incs,
|
|
dependencies: [catch2_dep, catch2_main_dep] + test_deps,
|
|
cpp_args: ['-DONNX_PLUGIN_PATH="' + onnx_plugin_path + '"'],
|
|
install: false,
|
|
)
|
|
|
|
foreach onnx_case : [
|
|
# Only model-free ABI/error contracts join the ordinary correctness lane.
|
|
['onnx_request_no_inputs', 'OnnxRequestPluginTest.NoInputsError', 'unit'],
|
|
['onnx_request_mock_batch_shape', 'OnnxRequestPluginTest.EmbeddingMockBatchShape', 'model'],
|
|
['onnx_provider_runtime_info', 'OnnxProviderPluginTest.RuntimeInfoIncludesHints', 'unit'],
|
|
['onnx_provider_missing_runtime', 'OnnxProviderPluginTest.MissingRuntimeReportedViaHealth', 'unit'],
|
|
['onnx_provider_config_preload', 'OnnxProviderPluginTest.ConfigPreloadParsingAndReady', 'runtime'],
|
|
['onnx_provider_batch_errors', 'OnnxProviderPluginTest.GenerateEmbeddingBatchErrors', 'unit'],
|
|
]
|
|
test(onnx_case[0], onnx_plugin_exe,
|
|
suite: ['plugins', 'onnx', 'catch2', onnx_case[2]],
|
|
args: [onnx_case[1]],
|
|
env: {
|
|
'YAMS_SKIP_MODEL_LOADING': '1',
|
|
'LD_LIBRARY_PATH': plugin_test_ld_library_path,
|
|
},
|
|
depends: onnx_plugin_runtime_deps,
|
|
timeout: 120,
|
|
)
|
|
endforeach
|
|
endif
|
|
|
|
# S3 object storage plugin smoke test (networked; skips when env is unset)
|
|
if get_option('build-plugins') and get_option('plugin-s3')
|
|
s3_plugin_dir = join_paths(plugin_build_dir, 'plugins/object_storage_s3')
|
|
s3_smoke_exe = executable('yams_s3_plugin_smoke',
|
|
files('s3/s3_plugin_smoke_test.cpp'),
|
|
include_directories: incs,
|
|
dependencies: test_deps,
|
|
install: false,
|
|
)
|
|
|
|
test('s3_plugin_smoke', s3_smoke_exe,
|
|
suite: ['plugins', 's3', 'smoke'],
|
|
env: {
|
|
'YAMS_SKIP_MODEL_LOADING': '1',
|
|
'YAMS_PLUGIN_DIR': s3_plugin_dir,
|
|
'LD_LIBRARY_PATH': plugin_test_ld_library_path,
|
|
},
|
|
depends: [yams_object_storage_s3],
|
|
timeout: 180,
|
|
)
|
|
endif
|
|
|
|
# Plugin export surface: only the yams_plugin_* C ABI may be visible.
|
|
plugin_export_args = []
|
|
plugin_export_deps = []
|
|
if get_option('build-plugins') and get_option('plugin-s3')
|
|
if host_machine.system() == 'windows'
|
|
s3_plugin_filename = 'yams_object_storage_s3' + plugin_ext
|
|
else
|
|
s3_plugin_filename = 'libyams_object_storage_s3' + plugin_ext
|
|
endif
|
|
plugin_export_args += ['-DYAMS_S3_PLUGIN_PATH="' + join_paths(plugin_build_dir, 'plugins/object_storage_s3', s3_plugin_filename) + '"']
|
|
plugin_export_deps += [yams_object_storage_s3]
|
|
endif
|
|
if is_variable('zyp_plugin')
|
|
plugin_export_args += ['-DYAMS_ZYP_PLUGIN_PATH="' + join_paths(plugin_build_dir, 'plugins/zyp/yams_zyp' + plugin_ext) + '"']
|
|
plugin_export_deps += [zyp_plugin]
|
|
endif
|
|
if plugin_export_deps.length() > 0 and host_machine.system() != 'windows'
|
|
plugin_export_surface_exe = executable('yams_plugin_export_surface_tests',
|
|
files('plugin_export_surface_catch2_test.cpp'),
|
|
include_directories: incs,
|
|
dependencies: [catch2_dep, catch2_main_dep] + test_deps,
|
|
cpp_args: plugin_export_args,
|
|
install: false,
|
|
)
|
|
test('plugin_export_surface', plugin_export_surface_exe,
|
|
suite: ['unit', 'plugins', 'catch2'],
|
|
env: {'LD_LIBRARY_PATH': plugin_test_ld_library_path},
|
|
depends: plugin_export_deps,
|
|
timeout: 30,
|
|
)
|
|
endif
|
|
|
|
# zyp (Zig YAMS PDF) plugin tests
|
|
zyp_plugin_runtime_deps = []
|
|
if is_variable('zyp_plugin')
|
|
zyp_plugin_runtime_deps = [zyp_plugin]
|
|
endif
|
|
if get_option('plugin-zyp') and zyp_plugin_runtime_deps.length() > 0
|
|
zyp_plugin_path = join_paths(plugin_build_dir, 'plugins/zyp/yams_zyp' + plugin_ext)
|
|
|
|
zyp_test_exe = executable('yams_zyp_tests',
|
|
files('zyp/zyp_plugin_catch2_test.cpp'),
|
|
include_directories: incs,
|
|
dependencies: [catch2_dep, catch2_main_dep] + test_deps,
|
|
cpp_args: ['-DZYP_PLUGIN_PATH="' + zyp_plugin_path + '"'],
|
|
install: false,
|
|
)
|
|
|
|
test('zyp_plugin', zyp_test_exe,
|
|
suite: ['unit', 'plugins', 'zyp', 'catch2'],
|
|
env: {
|
|
'YAMS_SKIP_MODEL_LOADING': '1',
|
|
'LD_LIBRARY_PATH': plugin_test_ld_library_path,
|
|
},
|
|
depends: zyp_plugin_runtime_deps,
|
|
timeout: 60,
|
|
)
|
|
endif
|
|
|
|
# Glint (GLiNER NL entity extractor) plugin tests
|
|
if get_option('plugin-glint')
|
|
glint_plugin_path = join_paths(plugin_build_dir, 'plugins/glint/yams_glint' + plugin_ext)
|
|
|
|
glint_test_exe = executable('yams_glint_tests',
|
|
files('glint/glint_plugin_catch2_test.cpp'),
|
|
include_directories: incs,
|
|
dependencies: [catch2_dep, catch2_main_dep, nlohmann_json_dep] + test_deps,
|
|
cpp_args: ['-DGLINT_PLUGIN_PATH="' + glint_plugin_path + '"'],
|
|
install: false,
|
|
)
|
|
|
|
catch2_allow_all_skipped = files('../scripts/catch2_allow_all_skipped.py')
|
|
test('glint_plugin', python_exe,
|
|
args: [catch2_allow_all_skipped, glint_test_exe],
|
|
suite: ['plugins', 'glint', 'catch2'],
|
|
env: {
|
|
'YAMS_SKIP_MODEL_LOADING': '1',
|
|
'LD_LIBRARY_PATH': plugin_test_ld_library_path,
|
|
},
|
|
depends: glint_test_exe,
|
|
timeout: 60,
|
|
)
|
|
endif
|