feat(clients)+test(interop): C++ client + Java validation of the daemon (B7)
tests / build-and-test (push) Successful in 2m54s
tests / thread-sanitizer (push) Successful in 3m48s
tests / tshark-dissector (push) Successful in 2m24s
tests / secs4j-interop (push) Successful in 1m44s
tests / python-interop (push) Successful in 3m10s
tests / libfuzzer (push) Successful in 3m38s

B7 — the daemon's HSMS face under the Java reference: Dockerfile.server now
bakes secs_gemd alongside secs_server (grpc deps in both stages), and
secs4j_validate.sh gains TARGET=gemd to point the 55-check secs4java8 suite
at the daemon instead. Result: 55/55 green. With secsgem-py already
validating both faces, byte-identical GEM between secs_server and secs_gemd
is now proven by both reference implementations, not inferred from shared
code. CI runs the daemon target as an extra step (image layers shared).

Second client — clients/cpp: a header-only C++ twin of the Python client
over the same proto. eq.set("ChamberPressure", 2.5) with bare literals
(integral/floating dispatch avoids variant ambiguity), get/fire/alarm/
clear, control_state/request_control_state/health, on("START", fn) +
listen()/listen_async()/stop() with auto-CompleteCommand, SecsGemError
carrying the daemon's message. cpp_mini_tool (~30 lines) mirrors the
Python mini_tool. Tested end-to-end over real loopback TCP against the
service inside secs_gemd_tests — now 4 cases / 141 assertions — including
set/get round-trips, error text, alarm-by-name into the model, health,
and the full HCACK-4 command loop with parameters.

(Build note: two grpc-heavy TUs at -O3 OOM even at -j2 on Docker Desktop;
built -j1. Known environment limitation, roadmap-documented.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 23:37:14 +02:00
parent 4f3031aeb9
commit b30443089f
9 changed files with 515 additions and 13 deletions
+11 -1
View File
@@ -170,6 +170,15 @@ if(SECSGEM_DAEMON)
${PROTO_OUT}/secsgem/v1/equipment.grpc.pb.cc)
target_include_directories(secs_gemd PRIVATE ${PROTO_OUT} ${Protobuf_INCLUDE_DIRS})
target_link_libraries(secs_gemd PRIVATE secsgem PkgConfig::GRPCPP ${Protobuf_LIBRARIES})
# The header-only C++ client's worked example (clients/cpp).
add_executable(cpp_mini_tool
clients/cpp/examples/mini_tool.cpp
${PROTO_OUT}/secsgem/v1/equipment.pb.cc
${PROTO_OUT}/secsgem/v1/equipment.grpc.pb.cc)
target_include_directories(cpp_mini_tool PRIVATE
${PROTO_OUT} ${Protobuf_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/clients/cpp/include)
target_link_libraries(cpp_mini_tool PRIVATE PkgConfig::GRPCPP ${Protobuf_LIBRARIES} Threads::Threads)
set(SECSGEM_DAEMON_BUILT TRUE)
message(STATUS "secs_gemd daemon enabled (grpc++ ${GRPCPP_VERSION})")
else()
@@ -266,10 +275,11 @@ add_test(NAME secsgem_tests COMMAND secsgem_tests)
if(SECSGEM_DAEMON_BUILT)
add_executable(secs_gemd_tests
tests/test_daemon_service.cpp
tests/test_cpp_client.cpp
${PROTO_OUT}/secsgem/v1/equipment.pb.cc
${PROTO_OUT}/secsgem/v1/equipment.grpc.pb.cc)
target_include_directories(secs_gemd_tests PRIVATE
${PROTO_OUT} ${Protobuf_INCLUDE_DIRS})
${PROTO_OUT} ${Protobuf_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/clients/cpp/include)
target_link_libraries(secs_gemd_tests PRIVATE
secsgem PkgConfig::GRPCPP ${Protobuf_LIBRARIES} doctest::doctest)
target_compile_definitions(secs_gemd_tests PRIVATE