1515
1616#include " handlers/st20p_handler.hpp"
1717#include " handlers/st30p_handler.hpp"
18+ #include " handlers/st40p_handler.hpp"
1819#include " session.hpp"
1920#include " strategy.hpp"
2021
22+ namespace {
23+
24+ struct TestPtpClockState {
25+ std::atomic<uint64_t > start_ns{0 };
26+ std::atomic<bool > running{false };
27+ };
28+
29+ TestPtpClockState g_test_ptp_clock;
30+
31+ uint64_t monotonicNowNs () {
32+ struct timespec spec;
33+ clock_gettime (CLOCK_MONOTONIC, &spec);
34+ return (uint64_t )spec.tv_sec * NS_PER_S + spec.tv_nsec ;
35+ }
36+
37+ void startClock (uint64_t now) {
38+ g_test_ptp_clock.start_ns .store (now, std::memory_order_release);
39+ g_test_ptp_clock.running .store (true , std::memory_order_release);
40+ }
41+
42+ void resetClock () {
43+ g_test_ptp_clock.running .store (false , std::memory_order_release);
44+ g_test_ptp_clock.start_ns .store (0 , std::memory_order_release);
45+ }
46+
47+ } /* namespace */
48+
2149void NoCtxTest::SetUp () {
2250 ctx = new st_tests_context;
2351 if (!ctx) {
@@ -42,10 +70,12 @@ void NoCtxTest::SetUp() {
4270 ctx->para .tx_queues_cnt [MTL_PORT_R] = 16 ;
4371 ctx->para .rx_queues_cnt [MTL_PORT_P] = 16 ;
4472 ctx->para .rx_queues_cnt [MTL_PORT_R] = 16 ;
73+ ResetFakePtpClock ();
4574 defaultTestDuration = 20 ;
4675}
4776
4877void NoCtxTest::TearDown () {
78+ st40pHandlers.clear ();
4979 st30pHandlers.clear ();
5080 st20pHandlers.clear ();
5181 frameTestStrategies.clear ();
@@ -61,34 +91,37 @@ void NoCtxTest::TearDown() {
6191 }
6292}
6393
64- uint64_t NoCtxTest::TestPtpSourceSinceEpoch (void * priv) {
65- struct timespec spec;
66- static std::atomic<uint64_t > adjustment_ns{0 };
67-
68- if (adjustment_ns.load () == 0 || priv == nullptr ) {
69- struct timespec spec_adjustment_to_epoch;
70- clock_gettime (CLOCK_MONOTONIC, &spec_adjustment_to_epoch);
71- uint64_t temp_adjustment = (uint64_t )spec_adjustment_to_epoch.tv_sec * NS_PER_S +
72- spec_adjustment_to_epoch.tv_nsec ;
94+ uint64_t NoCtxTest::FakePtpClockNow (void * priv) {
95+ (void )priv;
96+ if (!g_test_ptp_clock.running .load (std::memory_order_acquire)) {
97+ StartFakePtpClock ();
98+ }
7399
74- adjustment_ns.store (temp_adjustment);
100+ const uint64_t start = g_test_ptp_clock.start_ns .load (std::memory_order_acquire);
101+ const uint64_t now = monotonicNowNs ();
102+ if (now <= start) {
103+ return 0 ;
75104 }
76105
77- clock_gettime (CLOCK_MONOTONIC, &spec);
78- uint64_t result =
79- ((uint64_t )spec.tv_sec * NS_PER_S + spec.tv_nsec ) - adjustment_ns.load ();
106+ return now - start;
107+ }
108+
109+ void NoCtxTest::StartFakePtpClock () {
110+ startClock (monotonicNowNs ());
111+ }
80112
81- return result;
113+ void NoCtxTest::ResetFakePtpClock () {
114+ resetClock ();
82115}
83116
84117void NoCtxTest::sleepUntilFailure (int sleep_duration) {
85118 if (!sleep_duration) {
86119 sleep_duration = defaultTestDuration;
87120 }
88121
89- for (int i = 0 ; i < sleep_duration; ++i) {
122+ for (int i = 0 ; i < sleep_duration * 10 ; ++i) {
90123 if (HasFailure ()) break ;
91- sleep ( 1 );
124+ std::this_thread::sleep_for ( std::chrono::milliseconds ( 100 ) );
92125 }
93126}
94127
@@ -106,6 +139,8 @@ NoCtxTest::St20pHandlerBundle NoCtxTest::createSt20pHandlerBundle(
106139 configure (handler);
107140 }
108141
142+ handler->normalizeSessionOps ();
143+
109144 std::unique_ptr<FrameTestStrategy> strategyOwned;
110145 FrameTestStrategy* strategy = nullptr ;
111146 if (strategyFactory) {
@@ -153,6 +188,8 @@ NoCtxTest::St30pHandlerBundle NoCtxTest::createSt30pHandlerBundle(
153188 configure (handler);
154189 }
155190
191+ handler->normalizeSessionOps ();
192+
156193 std::unique_ptr<FrameTestStrategy> strategyOwned;
157194 FrameTestStrategy* strategy = nullptr ;
158195 if (strategyFactory) {
@@ -185,12 +222,58 @@ NoCtxTest::St30pHandlerBundle NoCtxTest::registerSt30pResources(
185222 return bundle;
186223}
187224
188- void NoCtxTest::initSt20pDefaultContext () {
225+ NoCtxTest::St40pHandlerBundle NoCtxTest::createSt40pHandlerBundle (
226+ bool createTx, bool createRx,
227+ std::function<FrameTestStrategy*(St40pHandler*)> strategyFactory,
228+ std::function<void(St40pHandler*)> configure) {
229+ if (!ctx) {
230+ throw std::runtime_error (" createSt40pHandlerBundle expects initialized ctx" );
231+ }
232+
233+ auto handlerOwned = std::make_unique<St40pHandler>(ctx);
234+ auto * handler = handlerOwned.get ();
235+ if (configure) {
236+ configure (handler);
237+ }
238+
239+ std::unique_ptr<FrameTestStrategy> strategyOwned;
240+ FrameTestStrategy* strategy = nullptr ;
241+ if (strategyFactory) {
242+ strategyOwned.reset (strategyFactory (handler));
243+ strategy = strategyOwned.get ();
244+ handler->setFrameTestStrategy (strategy);
245+ }
246+
247+ if (createRx) {
248+ handler->createSessionRx ();
249+ }
250+ if (createTx) {
251+ handler->createSessionTx ();
252+ }
253+
254+ return registerSt40pResources (std::move (handlerOwned), std::move (strategyOwned));
255+ }
256+
257+ NoCtxTest::St40pHandlerBundle NoCtxTest::registerSt40pResources (
258+ std::unique_ptr<St40pHandler> handler, std::unique_ptr<FrameTestStrategy> strategy) {
259+ St40pHandlerBundle bundle;
260+ if (handler) {
261+ bundle.handler = handler.get ();
262+ st40pHandlers.emplace_back (std::move (handler));
263+ }
264+ if (strategy) {
265+ bundle.strategy = strategy.get ();
266+ frameTestStrategies.emplace_back (std::move (strategy));
267+ }
268+ return bundle;
269+ }
270+
271+ void NoCtxTest::initDefaultContext () {
189272 if (!ctx) {
190- throw std::runtime_error (" initSt20pDefaultContext expects initialized ctx" );
273+ throw std::runtime_error (" initDefaultContext expects initialized ctx" );
191274 }
192275
193- ctx->para .ptp_get_time_fn = NoCtxTest::TestPtpSourceSinceEpoch ;
276+ ctx->para .ptp_get_time_fn = NoCtxTest::FakePtpClockNow ;
194277 ctx->para .log_level = MTL_LOG_LEVEL_INFO;
195278 ctx->para .flags &= ~MTL_FLAG_DEV_AUTO_START_STOP;
196279 ctx->handle = mtl_init (&ctx->para );
0 commit comments