diff --git a/docker/smoke_test.sh b/docker/smoke_test.sh index c6f09a0..06ad0db 100755 --- a/docker/smoke_test.sh +++ b/docker/smoke_test.sh @@ -2,22 +2,29 @@ # Integration smoke test for the sas_core thin wrapper. # # Runs inside the docker environment provided by docker/compose.yml: -# [1/3] colcon build of the wrapper package -# [2/3] Python shim smoke test (sas_core -> marinholab.sas.core) -# [3/3] C++ compatibility-header consumer compiled against the installed +# [1/4] colcon build of the wrapper package +# [2/4] Python shim smoke test (sas_core -> marinholab.sas.core) +# [3/4] C++ compatibility-header consumer compiled against the installed # libmarinholab_sas_core (legacy include path + namespace sas) +# [4/4] C++ namespace-ambiguity regression test (downstream-style consumer +# with `using namespace rclcpp;` + bare `Clock` in `namespace sas`) +# +# Note on CI gating: the `run` step uses `docker compose up`, which does not +# propagate the container's exit code. The checks here are therefore +# informational in CI today; run this script manually (or via +# `docker compose run --rm sas_core`) to get a real pass/fail signal. set -e cd /root/sas_core_devel/src/ -echo '=== [1/3] colcon build (thin wrapper) ===' +echo '=== [1/4] colcon build (thin wrapper) ===' colcon build -echo '=== [2/3] Python shim smoke test ===' +echo '=== [2/4] Python shim smoke test ===' source install/setup.bash python3 sas_core/scripts/sas_core_smoke_test.py -echo '=== [3/3] C++ compatibility header + installed library test ===' +echo '=== [3/4] C++ compatibility header + installed library test ===' # Wrapper-installed compat headers and the .deb-installed shared library. SAS_INC=/root/sas_core_devel/src/install/sas_core/include LIBDIR="$(dirname "$(ldconfig -p | awk '/libmarinholab_sas_core\.so/ {print $NF; exit}')")" @@ -43,4 +50,61 @@ g++ /tmp/sas_core_compat_test.cpp -o /tmp/sas_core_compat_test \ -Wl,-rpath,"${LIBDIR}" /tmp/sas_core_compat_test +echo '=== [4/4] C++ namespace-ambiguity regression test (downstream-style) ===' +# Reproduces SmartArmStack/smart_arm_stack_ROS2 PPA build failure: +# a downstream package does `using namespace rclcpp;` and declares a bare +# `Clock` inside `namespace sas`. With the thin wrapper's using-directive +# shim, `Clock` was ambiguous between rclcpp::Clock and +# marinholab::sas::core::Clock. The `using Clock = ...` declaration in the +# shim makes it a real member of `namespace sas`, shadowing rclcpp::Clock. +# +# A minimal `rclcpp` stub (Clock + Node) is used instead of the full rclcpp +# runtime: the bug is purely about *name lookup*, and a stub rclcpp::Clock / +# rclcpp::Node is name-lookup-identical to the real ones. This keeps the test +# hermetic and independent of the ROS include layout. +STUB=/tmp/sas_ambig_stub/rclcpp +mkdir -p "${STUB}" +cat > "${STUB}/rclcpp.hpp" <<'CPP' +#pragma once +#include +namespace rclcpp +{ + class Clock {}; + class Node { public: std::shared_ptr get_clock() { return nullptr; } }; +} +CPP + +cat > /tmp/sas_core_ambig_test.cpp <<'CPP' +#include +#include +#include + +using namespace rclcpp; + +namespace sas +{ +class Consumer +{ +private: + std::shared_ptr node_; // must resolve to rclcpp::Node + Clock clock_; // must resolve to marinholab::sas::core::Clock +public: + void use() + { + clock_.init(); // core Clock::init() + (void)node_; + } +}; +} + +int main() +{ + return 0; +} +CPP + +g++ /tmp/sas_core_ambig_test.cpp -c -o /tmp/sas_core_ambig_test.o \ + -I"${STUB%/*}" -I"${SAS_INC}" +echo 'Ambiguity regression test compiled (no ambiguous Clock).' + echo '=== ALL CHECKS PASSED ===' diff --git a/include/sas_core/sas_clock.hpp b/include/sas_core/sas_clock.hpp index af12b98..fe00023 100644 --- a/include/sas_core/sas_clock.hpp +++ b/include/sas_core/sas_clock.hpp @@ -7,4 +7,12 @@ namespace sas { using namespace marinholab::sas::core; + // `Clock` must be a *real member* of namespace sas (a using-declaration), + // not merely findable via the using-directive above. Otherwise a downstream + // package that also does `using namespace rclcpp;` sees a bare `Clock` + // reference as ambiguous between marinholab::sas::core::Clock and + // rclcpp::Clock (name lookup through the directive finds both). Declaring + // it here shadows rclcpp::Clock, matching the old monolithic sas_core where + // `namespace sas` had its own `class Clock`. + using Clock = marinholab::sas::core::Clock; }