yams/tests/plugins/meson.build
Trevon d398556ee5
fix(tests): replace frozen expectations and harden release gates (#323)
* 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>
2026-10-19 19:16:57 -06:00

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