test-scheduler-advanced-features.cpp 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. // test-scheduler-advanced-features-no-lambda.cpp - Advanced TaskScheduler features without lambda functions
  2. // This file contains comprehensive tests for advanced TaskScheduler functionality
  3. // enabled by specific compile-time directives, using traditional function pointers
  4. //
  5. // =====================================================================================
  6. // ADVANCED FEATURES TEST PLAN AND COVERAGE MATRIX
  7. // =====================================================================================
  8. //
  9. // PURPOSE: Validate advanced TaskScheduler features
  10. // APPROACH: Traditional function pointers for maximum platform compatibility
  11. // SCOPE: Advanced features requiring specific compile-time directives
  12. //
  13. // COMPILE DIRECTIVES TESTED:
  14. // - _TASK_STATUS_REQUEST: Event-driven task coordination and status signaling
  15. // - _TASK_TIMEOUT: Task execution timeout and deadline management
  16. // - _TASK_SCHEDULING_OPTIONS: Advanced scheduling behavior control
  17. // - _TASK_SELF_DESTRUCT: Automatic task cleanup and memory management
  18. //
  19. // COVERAGE MATRIX:
  20. // ================
  21. //
  22. // 1. STATUS REQUEST FUNCTIONALITY (_TASK_STATUS_REQUEST)
  23. // ├── StatusRequest Creation and Management
  24. // │ ├── StatusRequest() constructor
  25. // │ ├── setWaiting(count) - prepare for multiple signals
  26. // │ ├── signal(status) - signal completion from tasks
  27. // │ ├── signalComplete(status) - force immediate completion
  28. // │ ├── pending() - check if still waiting
  29. // │ ├── completed() - check if finished
  30. // │ ├── getStatus() - retrieve completion status
  31. // │ └── getCount() - get remaining signal count
  32. // │
  33. // ├── Task Status Request Integration
  34. // │ ├── waitFor(StatusRequest*, interval, iterations) - wait for event
  35. // │ ├── waitForDelayed(StatusRequest*, interval, iterations) - delayed wait
  36. // │ ├── getStatusRequest() - get external status request
  37. // │ └── getInternalStatusRequest() - get task's internal status
  38. // │
  39. // └── Event-Driven Task Coordination Patterns
  40. // ├── Single task waiting for event completion
  41. // ├── Multiple tasks waiting for same event
  42. // ├── Task chains with dependency resolution
  43. // └── Producer-consumer coordination scenarios
  44. //
  45. // 2. TIMEOUT FUNCTIONALITY (_TASK_TIMEOUT)
  46. // ├── Task Timeout Management
  47. // │ ├── setTimeout(timeout, reset) - set execution deadline
  48. // │ ├── resetTimeout() - restart timeout timer
  49. // │ ├── getTimeout() - retrieve timeout value
  50. // │ ├── untilTimeout() - time remaining until timeout
  51. // │ └── isTimedOut() - check timeout status
  52. // │
  53. // ├── StatusRequest Timeout Integration
  54. // │ ├── StatusRequest::setTimeout(timeout) - set request deadline
  55. // │ ├── StatusRequest::resetTimeout() - restart request timer
  56. // │ ├── StatusRequest::getTimeout() - retrieve request timeout
  57. // │ └── StatusRequest::untilTimeout() - time until request expires
  58. // │
  59. // └── Timeout Behavior Patterns
  60. // ├── Task execution timeout handling
  61. // ├── StatusRequest completion timeout
  62. // ├── Timeout-driven task disabling
  63. // └── Deadline-based task prioritization
  64. //
  65. // 3. SCHEDULING OPTIONS (_TASK_SCHEDULING_OPTIONS)
  66. // ├── Scheduling Behavior Control
  67. // │ ├── setSchedulingOption(option) - configure task behavior
  68. // │ ├── getSchedulingOption() - retrieve current option
  69. // │ └── Scheduling option effects on execution
  70. // │
  71. // └── Advanced Scheduling Patterns
  72. // ├── Priority-based execution control
  73. // ├── Conditional execution behavior
  74. // └── Resource allocation management
  75. //
  76. // 4. SELF-DESTRUCT FUNCTIONALITY (_TASK_SELF_DESTRUCT)
  77. // ├── Automatic Task Cleanup
  78. // │ ├── Task auto-removal from scheduler
  79. // │ ├── Memory management and resource cleanup
  80. // │ └── Lifecycle-based task destruction
  81. // │
  82. // └── Self-Destruct Patterns
  83. // ├── One-shot tasks with auto-cleanup
  84. // ├── Conditional task removal
  85. // └── Dynamic task lifecycle management
  86. //
  87. // 5. INTEGRATION AND ADVANCED PATTERNS
  88. // ├── Multi-Feature Integration Tests
  89. // │ ├── Status requests with timeout handling
  90. // │ ├── Self-destructing tasks with status coordination
  91. // │ ├── Scheduling options with timeout management
  92. // │ └── Complex event-driven workflows
  93. // │
  94. // ├── Real-World Usage Scenarios
  95. // │ ├── Sensor data collection with timeouts
  96. // │ ├── Multi-stage processing pipelines
  97. // │ ├── Resource monitoring and cleanup
  98. // │ └── Deadline-driven task orchestration
  99. // │
  100. // └── Edge Cases and Error Handling
  101. // ├── Timeout during status request waiting
  102. // ├── Self-destruct during active coordination
  103. // ├── Invalid scheduling option handling
  104. // └── Resource cleanup on abnormal termination
  105. //
  106. // =====================================================================================
  107. // Enable all advanced features for comprehensive testing
  108. #define _TASK_STATUS_REQUEST // Event-driven task coordination
  109. #define _TASK_TIMEOUT // Task execution deadlines
  110. #define _TASK_SCHEDULING_OPTIONS // Advanced scheduling control
  111. #define _TASK_SELF_DESTRUCT // Automatic task cleanup
  112. #include <gtest/gtest.h>
  113. #include "Arduino.h"
  114. #include "TaskScheduler.h"
  115. // Global test state for advanced features
  116. std::vector<std::string> advanced_test_output;
  117. int advanced_callback_counter = 0;
  118. bool status_received = false;
  119. int last_status_code = 0;
  120. bool timeout_occurred = false;
  121. bool task_self_destructed = false;
  122. // Global pointers for task-to-task communication
  123. static StatusRequest* global_status_request = nullptr;
  124. static Task* global_advanced_yield_task = nullptr;
  125. // Test callback functions (no lambda functions)
  126. /**
  127. * @brief Advanced callback function for status request testing
  128. *
  129. * Records execution and can signal status request completion.
  130. * Used for testing event-driven task coordination patterns.
  131. */
  132. void advanced_status_callback() {
  133. advanced_callback_counter++;
  134. advanced_test_output.push_back("status_task_executed");
  135. std::cout << "Status task executed at " << millis() << "ms" << std::endl;
  136. }
  137. /**
  138. * @brief Producer callback that signals status request completion
  139. *
  140. * Simulates a task that produces events or completes work that
  141. * other tasks are waiting for. Essential for testing coordination.
  142. */
  143. void producer_callback() {
  144. advanced_callback_counter++;
  145. advanced_test_output.push_back("producer_completed");
  146. // Signal the global status request if it exists
  147. if (global_status_request != nullptr) {
  148. global_status_request->signalComplete(100); // Success status
  149. }
  150. std::cout << "Producer completed at " << millis() << "ms" << std::endl;
  151. }
  152. /**
  153. * @brief Consumer callback for status request waiting
  154. *
  155. * Represents tasks that wait for specific events before executing.
  156. * Used to test event-driven coordination and dependency management.
  157. */
  158. void consumer_callback() {
  159. advanced_callback_counter++;
  160. advanced_test_output.push_back("consumer_executed");
  161. std::cout << "Consumer executed at " << millis() << "ms" << std::endl;
  162. }
  163. /**
  164. * @brief First consumer callback for multi-consumer tests
  165. */
  166. void consumer1_callback() {
  167. advanced_callback_counter++;
  168. advanced_test_output.push_back("consumer1_executed");
  169. }
  170. /**
  171. * @brief Second consumer callback for multi-consumer tests
  172. */
  173. void consumer2_callback() {
  174. advanced_callback_counter++;
  175. advanced_test_output.push_back("consumer2_executed");
  176. }
  177. /**
  178. * @brief Third consumer callback for multi-consumer tests
  179. */
  180. void consumer3_callback() {
  181. advanced_callback_counter++;
  182. advanced_test_output.push_back("consumer3_executed");
  183. }
  184. /**
  185. * @brief Timeout-sensitive callback for deadline testing
  186. *
  187. * Callback that tracks timeout conditions and handles deadline-based
  188. * execution scenarios. Critical for testing timeout functionality.
  189. */
  190. void timeout_sensitive_callback() {
  191. advanced_callback_counter++;
  192. advanced_test_output.push_back("timeout_task_executed");
  193. // This callback can be used to test timeout behavior
  194. }
  195. /**
  196. * @brief Self-destructing task callback for cleanup testing
  197. *
  198. * Callback for tasks that are designed to clean themselves up
  199. * after execution. Used to test automatic resource management.
  200. */
  201. void self_destruct_callback() {
  202. advanced_callback_counter++;
  203. advanced_test_output.push_back("self_destruct_executed");
  204. task_self_destructed = true;
  205. }
  206. /**
  207. * @brief Callback for multi-step yield testing - step 1
  208. */
  209. void yield_step1_callback() {
  210. advanced_test_output.push_back("step_1");
  211. }
  212. /**
  213. * @brief Callback for multi-step yield testing - step 2
  214. */
  215. void yield_step2_callback() {
  216. advanced_test_output.push_back("step_2");
  217. }
  218. /**
  219. * @brief Consumer callback that yields to yield_step2_callback
  220. */
  221. void consumer_yield_callback() {
  222. advanced_test_output.push_back("consumer_initial");
  223. if (global_advanced_yield_task) {
  224. global_advanced_yield_task->yield(&yield_step2_callback);
  225. }
  226. }
  227. /**
  228. * @brief Callback for waiter task 1 in coordination scenarios
  229. */
  230. void waiter1_callback() {
  231. advanced_callback_counter++;
  232. advanced_test_output.push_back("waiter1_executed");
  233. }
  234. /**
  235. * @brief Callback for waiter task 2 in coordination scenarios
  236. */
  237. void waiter2_callback() {
  238. advanced_callback_counter++;
  239. advanced_test_output.push_back("waiter2_executed");
  240. }
  241. /**
  242. * @brief Callback for waiter task 3 in coordination scenarios
  243. */
  244. void waiter3_callback() {
  245. advanced_callback_counter++;
  246. advanced_test_output.push_back("waiter3_executed");
  247. }
  248. /**
  249. * @brief Test fixture class for advanced TaskScheduler features
  250. *
  251. * Provides setup and teardown for advanced feature tests, ensuring
  252. * clean state between tests and utility methods for complex scenarios.
  253. */
  254. class AdvancedSchedulerTest : public ::testing::Test {
  255. protected:
  256. /**
  257. * @brief Set up test environment for advanced features
  258. *
  259. * Clears all test state and initializes timing system.
  260. * Prepares environment for testing complex feature interactions.
  261. */
  262. void SetUp() override {
  263. clearAdvancedTestOutput();
  264. advanced_callback_counter = 0;
  265. status_received = false;
  266. last_status_code = 0;
  267. timeout_occurred = false;
  268. task_self_destructed = false;
  269. global_status_request = nullptr;
  270. millis(); // Initialize timing
  271. }
  272. /**
  273. * @brief Clean up test environment after advanced feature tests
  274. *
  275. * Ensures no test artifacts affect subsequent tests.
  276. * Critical for maintaining test isolation in complex scenarios.
  277. */
  278. void TearDown() override {
  279. clearAdvancedTestOutput();
  280. advanced_callback_counter = 0;
  281. status_received = false;
  282. last_status_code = 0;
  283. timeout_occurred = false;
  284. task_self_destructed = false;
  285. global_status_request = nullptr;
  286. }
  287. /**
  288. * @brief Helper to run scheduler until condition or timeout for advanced tests
  289. *
  290. * Enhanced version that handles complex conditions involving multiple
  291. * tasks, status requests, and timeout scenarios.
  292. */
  293. bool runAdvancedSchedulerUntil(Scheduler& ts, std::function<bool()> condition, unsigned long timeout_ms = 2000) {
  294. return waitForCondition([&]() {
  295. ts.execute();
  296. return condition();
  297. }, timeout_ms);
  298. }
  299. /**
  300. * @brief Clear advanced test output buffer
  301. */
  302. void clearAdvancedTestOutput() {
  303. advanced_test_output.clear();
  304. }
  305. /**
  306. * @brief Get count of advanced test output entries
  307. */
  308. size_t getAdvancedTestOutputCount() {
  309. return advanced_test_output.size();
  310. }
  311. /**
  312. * @brief Get specific advanced test output entry
  313. */
  314. std::string getAdvancedTestOutput(size_t index) {
  315. if (index < advanced_test_output.size()) {
  316. return advanced_test_output[index];
  317. }
  318. return "";
  319. }
  320. };
  321. // ================== STATUS REQUEST CREATION AND MANAGEMENT TESTS ==================
  322. /**
  323. * @brief Test StatusRequest constructor and basic state management
  324. *
  325. * TESTS: StatusRequest(), setWaiting(), pending(), completed()
  326. *
  327. * PURPOSE: Verify that StatusRequest objects can be created and their
  328. * basic state management methods work correctly, providing foundation
  329. * for event-driven task coordination.
  330. *
  331. * STATUS REQUEST LIFECYCLE:
  332. * - Constructor: Creates StatusRequest in completed state (count=0)
  333. * - setWaiting(count): Prepares to receive 'count' signal() calls
  334. * - pending(): Returns true while count > 0
  335. * - completed(): Returns true when count == 0
  336. * - State transitions control task execution timing
  337. *
  338. * TEST SCENARIO:
  339. * 1. Create StatusRequest and verify initial completed state
  340. * 2. Set waiting for 3 signals and verify pending state
  341. * 3. Verify completed() and pending() return correct values
  342. * 4. Test state consistency across multiple checks
  343. *
  344. * EXPECTATIONS:
  345. * - Initial state: completed() = true, pending() = false
  346. * - After setWaiting(3): completed() = false, pending() = true
  347. * - State methods return consistent, expected values
  348. *
  349. * IMPORTANCE: Basic state management is foundation for all event-driven
  350. * coordination patterns. Reliable state tracking ensures proper task
  351. * synchronization and prevents race conditions.
  352. */
  353. TEST_F(AdvancedSchedulerTest, StatusRequestBasicState) {
  354. StatusRequest sr;
  355. // Initial state should be completed
  356. EXPECT_TRUE(sr.completed());
  357. EXPECT_FALSE(sr.pending());
  358. EXPECT_EQ(sr.getCount(), 0);
  359. EXPECT_EQ(sr.getStatus(), 0);
  360. // Set waiting for 3 signals
  361. sr.setWaiting(3);
  362. EXPECT_FALSE(sr.completed());
  363. EXPECT_TRUE(sr.pending());
  364. EXPECT_EQ(sr.getCount(), 3);
  365. EXPECT_EQ(sr.getStatus(), 0); // Status reset by setWaiting
  366. }
  367. /**
  368. * @brief Test StatusRequest signal() method for incremental completion
  369. *
  370. * TESTS: signal(status), getStatus(), getCount()
  371. *
  372. * PURPOSE: Verify that signal() correctly decrements the waiting count
  373. * and manages status codes, enabling coordinated completion tracking
  374. * across multiple signaling tasks.
  375. *
  376. * SIGNAL BEHAVIOR:
  377. * - signal(): Decrements count by 1, sets status if provided
  378. * - signal(status): Same as signal() but with custom status code
  379. * - Returns true when StatusRequest becomes complete (count reaches 0)
  380. * - Status code from last signal() call is preserved
  381. * - Negative status codes cause immediate completion (error handling)
  382. *
  383. * TEST SCENARIO:
  384. * 1. Set StatusRequest waiting for 3 signals
  385. * 2. Send 2 normal signals and verify count decrements
  386. * 3. Send final signal with status code and verify completion
  387. * 4. Test negative status code causing immediate completion
  388. *
  389. * EXPECTATIONS:
  390. * - Each signal() decrements count by 1
  391. * - Status code is updated with each signal
  392. * - signal() returns true only when count reaches 0
  393. * - Negative status causes immediate completion
  394. *
  395. * IMPORTANCE: Incremental signaling enables complex coordination
  396. * patterns where multiple tasks contribute to completion condition.
  397. * Status codes provide error handling and completion context.
  398. */
  399. TEST_F(AdvancedSchedulerTest, StatusRequestSignaling) {
  400. StatusRequest sr;
  401. sr.setWaiting(3);
  402. // Send first signal
  403. bool complete = sr.signal();
  404. EXPECT_FALSE(complete);
  405. EXPECT_EQ(sr.getCount(), 2);
  406. EXPECT_TRUE(sr.pending());
  407. // Send second signal with status
  408. complete = sr.signal(42);
  409. EXPECT_FALSE(complete);
  410. EXPECT_EQ(sr.getCount(), 1);
  411. EXPECT_EQ(sr.getStatus(), 42);
  412. // Send final signal
  413. complete = sr.signal(99);
  414. EXPECT_TRUE(complete);
  415. EXPECT_EQ(sr.getCount(), 0);
  416. EXPECT_EQ(sr.getStatus(), 99);
  417. EXPECT_TRUE(sr.completed());
  418. // Test negative status for immediate completion
  419. sr.setWaiting(5);
  420. complete = sr.signal(-1); // Negative status should complete immediately
  421. EXPECT_TRUE(complete);
  422. EXPECT_EQ(sr.getCount(), 0);
  423. EXPECT_EQ(sr.getStatus(), -1);
  424. }
  425. /**
  426. * @brief Test StatusRequest signalComplete() method for immediate completion
  427. *
  428. * TESTS: signalComplete(status)
  429. *
  430. * PURPOSE: Verify that signalComplete() immediately completes the StatusRequest
  431. * regardless of remaining count, enabling emergency completion and
  432. * error handling scenarios.
  433. *
  434. * SIGNAL COMPLETE BEHAVIOR:
  435. * - signalComplete(): Immediately sets count to 0 (completed state)
  436. * - signalComplete(status): Same as above but with custom status code
  437. * - Bypasses incremental signaling for immediate completion
  438. * - Useful for error conditions and emergency shutdowns
  439. * - Always results in completed state regardless of initial count
  440. *
  441. * TEST SCENARIO:
  442. * 1. Set StatusRequest waiting for large number of signals
  443. * 2. Call signalComplete() and verify immediate completion
  444. * 3. Test signalComplete() with custom status code
  445. * 4. Verify no further signals are processed after completion
  446. *
  447. * EXPECTATIONS:
  448. * - signalComplete() immediately sets count to 0
  449. * - Status code is set if provided
  450. * - completed() returns true immediately
  451. * - Further signals have no effect (idempotent)
  452. *
  453. * IMPORTANCE: Immediate completion enables error handling, emergency
  454. * shutdown, and abort scenarios in complex coordination patterns.
  455. * Critical for robust event-driven systems.
  456. */
  457. TEST_F(AdvancedSchedulerTest, StatusRequestSignalComplete) {
  458. StatusRequest sr;
  459. sr.setWaiting(10); // Large count for testing immediate completion
  460. // Signal complete should immediately finish
  461. sr.signalComplete(200);
  462. EXPECT_TRUE(sr.completed());
  463. EXPECT_FALSE(sr.pending());
  464. EXPECT_EQ(sr.getCount(), 0);
  465. EXPECT_EQ(sr.getStatus(), 200);
  466. // Further signals should have no effect
  467. sr.signal(999);
  468. EXPECT_EQ(sr.getStatus(), 200); // Should remain unchanged
  469. EXPECT_EQ(sr.getCount(), 0); // Should remain completed
  470. }
  471. // ================== TASK STATUS REQUEST INTEGRATION TESTS ==================
  472. /**
  473. * @brief Test Task waitFor() method for event-driven task execution
  474. *
  475. * TESTS: waitFor(StatusRequest*, interval, iterations)
  476. *
  477. * PURPOSE: Verify that tasks can wait for external StatusRequest completion
  478. * before executing, enabling event-driven coordination and dependency
  479. * management between tasks.
  480. *
  481. * WAIT FOR BEHAVIOR:
  482. * - waitFor(): Configures task to wait for StatusRequest completion
  483. * - Task becomes enabled but won't execute until StatusRequest completes
  484. * - interval and iterations configure post-completion behavior
  485. * - Task executes immediately when StatusRequest is already complete
  486. * - Enables producer-consumer and dependency coordination patterns
  487. *
  488. * TEST SCENARIO:
  489. * 1. Create StatusRequest in pending state
  490. * 2. Create task configured to waitFor() the StatusRequest
  491. * 3. Verify task doesn't execute while StatusRequest is pending
  492. * 4. Complete StatusRequest and verify task executes
  493. * 5. Test with already-completed StatusRequest
  494. *
  495. * EXPECTATIONS:
  496. * - Task enabled but doesn't execute while StatusRequest pending
  497. * - Task executes immediately after StatusRequest completion
  498. * - Task with completed StatusRequest executes immediately
  499. * - Task follows normal interval/iteration behavior after first execution
  500. *
  501. * IMPORTANCE: Event-driven task execution enables sophisticated coordination
  502. * patterns essential for multi-task workflows, data processing pipelines,
  503. * and resource synchronization scenarios.
  504. */
  505. TEST_F(AdvancedSchedulerTest, TaskWaitForStatusRequest) {
  506. Scheduler ts;
  507. StatusRequest sr;
  508. // Set up StatusRequest in pending state
  509. sr.setWaiting(1);
  510. advanced_callback_counter = 0;
  511. // Create task that waits for status request
  512. Task waiter(100, 2, &consumer_callback, &ts);
  513. waiter.waitFor(&sr, 50, 2);
  514. // Task should be enabled but not execute while SR is pending
  515. EXPECT_TRUE(waiter.isEnabled());
  516. // Run scheduler - task should not execute yet
  517. delay(100);
  518. ts.execute();
  519. EXPECT_EQ(advanced_callback_counter, 0);
  520. // Complete the status request
  521. sr.signalComplete();
  522. // Now task should execute
  523. bool success = runAdvancedSchedulerUntil(ts, []() {
  524. return advanced_callback_counter >= 1;
  525. });
  526. EXPECT_TRUE(success);
  527. EXPECT_EQ(getAdvancedTestOutput(0), "consumer_executed");
  528. // Task should continue normal execution after first completion
  529. success = runAdvancedSchedulerUntil(ts, []() {
  530. return advanced_callback_counter >= 2;
  531. });
  532. EXPECT_TRUE(success);
  533. }
  534. /**
  535. * @brief Test Task waitForDelayed() method for delayed event waiting
  536. *
  537. * TESTS: waitForDelayed(StatusRequest*, interval, iterations)
  538. *
  539. * PURPOSE: Same as above only task is scheduled with a delay as a result
  540. */
  541. TEST_F(AdvancedSchedulerTest, TaskWaitForDelayedStatusRequest) {
  542. Scheduler ts;
  543. StatusRequest sr;
  544. // StatusRequest already complete
  545. sr.setWaiting(1);
  546. advanced_callback_counter = 0;
  547. // Create task with delayed wait (should wait for delay even though SR is complete)
  548. Task delayed_waiter(500, 1, &consumer_callback, &ts);
  549. delayed_waiter.waitForDelayed(&sr, 500, 1); // 500ms delay
  550. // Task should be enabled
  551. EXPECT_TRUE(delayed_waiter.isEnabled());
  552. // Should not execute immediately despite completed StatusRequest
  553. delay(50);
  554. ts.execute();
  555. EXPECT_EQ(advanced_callback_counter, 0);
  556. sr.signalComplete(); // Complete SR
  557. // The task will be scheduled to run after the delay
  558. bool success = runAdvancedSchedulerUntil(ts, true, 200); // Wait up to 200ms
  559. EXPECT_FALSE(success);
  560. delay(400);
  561. // Task should complete after total 500ms delay
  562. success = runAdvancedSchedulerUntil(ts, []() {
  563. return advanced_callback_counter >= 1;
  564. });
  565. EXPECT_TRUE(success);
  566. }
  567. /**
  568. * @brief Test multiple tasks waiting for same StatusRequest
  569. *
  570. * TESTS: Multiple Task::waitFor() on single StatusRequest
  571. *
  572. * PURPOSE: Verify that multiple tasks can wait for the same StatusRequest
  573. * and all execute when it completes, enabling broadcast notification
  574. * and fan-out coordination patterns.
  575. *
  576. * MULTIPLE WAITER BEHAVIOR:
  577. * - Multiple tasks can waitFor() same StatusRequest
  578. * - All waiting tasks execute when StatusRequest completes
  579. * - Each task maintains independent execution behavior after triggering
  580. * - Enables broadcast notification and fan-out patterns
  581. * - Critical for coordinated multi-task startup scenarios
  582. *
  583. * TEST SCENARIO:
  584. * 1. Create StatusRequest in pending state
  585. * 2. Create multiple tasks waiting for same StatusRequest
  586. * 3. Verify no tasks execute while StatusRequest pending
  587. * 4. Complete StatusRequest and verify all tasks execute
  588. * 5. Verify each task maintains independent behavior
  589. *
  590. * EXPECTATIONS:
  591. * - No tasks execute while StatusRequest pending
  592. * - All tasks execute after StatusRequest completion
  593. * - Each task produces expected output
  594. * - Tasks maintain independent execution patterns
  595. *
  596. * IMPORTANCE: Multi-task coordination enables broadcast patterns
  597. * essential for synchronized startup, data distribution, and
  598. * coordinated processing scenarios in complex applications.
  599. */
  600. TEST_F(AdvancedSchedulerTest, MultipleTasksWaitingForStatusRequest) {
  601. Scheduler ts;
  602. StatusRequest sr;
  603. // Set up StatusRequest waiting for signal
  604. sr.setWaiting(1);
  605. // Create multiple tasks waiting for same StatusRequest
  606. Task waiter1(100, 1, &waiter1_callback, &ts);
  607. Task waiter2(150, 1, &waiter2_callback, &ts);
  608. Task waiter3(200, 1, &waiter3_callback, &ts);
  609. // Configure all tasks to wait for same StatusRequest
  610. waiter1.waitFor(&sr);
  611. waiter2.waitFor(&sr);
  612. waiter3.waitFor(&sr);
  613. // Verify all tasks are enabled but none execute
  614. EXPECT_TRUE(waiter1.isEnabled());
  615. EXPECT_TRUE(waiter2.isEnabled());
  616. EXPECT_TRUE(waiter3.isEnabled());
  617. delay(250);
  618. ts.execute();
  619. EXPECT_EQ(advanced_callback_counter, 0);
  620. // Signal completion
  621. sr.signalComplete();
  622. // All tasks should now execute
  623. bool success = runAdvancedSchedulerUntil(ts, []() {
  624. return advanced_callback_counter >= 3;
  625. });
  626. EXPECT_TRUE(success);
  627. // Verify all tasks executed
  628. EXPECT_EQ(getAdvancedTestOutputCount(), 3);
  629. // Note: Execution order may vary, but all should be present
  630. }
  631. // ================== TASK TIMEOUT FUNCTIONALITY TESTS ==================
  632. /**
  633. * @brief Test Task timeout basic functionality
  634. *
  635. * TESTS: setTimeout(), getTimeout(), resetTimeout(), untilTimeout()
  636. *
  637. * PURPOSE: Verify that task timeout functionality correctly manages
  638. * execution deadlines and provides timeout detection capabilities
  639. * essential for deadline-driven applications.
  640. *
  641. * TIMEOUT FUNCTIONALITY:
  642. * - setTimeout(timeout, reset): Sets execution deadline with optional reset
  643. * - getTimeout(): Returns configured timeout value
  644. * - resetTimeout(): Restarts timeout timer from current time
  645. * - untilTimeout(): Returns remaining time until timeout
  646. * - isTimedOut(): Checks if timeout has occurred
  647. *
  648. * TEST SCENARIO:
  649. * 1. Create task and set timeout value
  650. * 2. Verify timeout configuration via getters
  651. * 3. Test resetTimeout() functionality
  652. * 4. Verify untilTimeout() decreases over time
  653. * 5. Test timeout detection after deadline
  654. *
  655. * EXPECTATIONS:
  656. * - setTimeout() correctly configures timeout value
  657. * - getTimeout() returns set value
  658. * - untilTimeout() decreases as time passes
  659. * - Timeout detection works after deadline expires
  660. *
  661. * IMPORTANCE: Timeout functionality enables deadline-driven task management,
  662. * essential for real-time applications and preventing resource starvation
  663. * in time-critical systems.
  664. */
  665. TEST_F(AdvancedSchedulerTest, TaskTimeoutBasicFunctionality) {
  666. Scheduler ts;
  667. Task task(100, TASK_FOREVER, &timeout_sensitive_callback, &ts, true);
  668. // Set timeout to 500ms
  669. task.setTimeout(500, true); // true = reset timeout timer
  670. EXPECT_EQ(task.getTimeout(), 500);
  671. // Check initial time until timeout
  672. long until_timeout = task.untilTimeout();
  673. EXPECT_GT(until_timeout, 400); // Should be close to 500ms
  674. EXPECT_LE(until_timeout, 500);
  675. // Wait some time and check again
  676. delay(200);
  677. until_timeout = task.untilTimeout();
  678. EXPECT_GT(until_timeout, 200); // Should be around 300ms
  679. EXPECT_LE(until_timeout, 300);
  680. // Reset timeout and verify
  681. task.resetTimeout();
  682. until_timeout = task.untilTimeout();
  683. EXPECT_GT(until_timeout, 400); // Should be close to 500ms again
  684. }
  685. /**
  686. * @brief Test task behavior when timeout occurs
  687. *
  688. * TESTS: Task execution with timeout expiration
  689. *
  690. * PURPOSE: Verify that tasks handle timeout expiration correctly,
  691. * including automatic disabling and timeout status tracking,
  692. * essential for robust timeout management.
  693. *
  694. * TIMEOUT EXPIRATION BEHAVIOR:
  695. * - Task automatically disables when timeout expires
  696. * - isTimedOut() returns true after timeout
  697. * - Task stops executing after timeout
  698. * - Timeout status preserved until reset
  699. * - Enables deadline-driven task lifecycle management
  700. *
  701. * TEST SCENARIO:
  702. * 1. Create task with short timeout
  703. * 2. Let task execute normally initially
  704. * 3. Wait for timeout to expire
  705. * 4. Verify task disables and isTimedOut() returns true
  706. * 5. Verify no further executions occur
  707. *
  708. * EXPECTATIONS:
  709. * - Task executes normally before timeout
  710. * - Task disables after timeout expiration
  711. * - isTimedOut() returns true after timeout
  712. * - No executions occur after timeout
  713. *
  714. * IMPORTANCE: Timeout expiration handling prevents runaway tasks
  715. * and ensures deadline compliance, critical for real-time and
  716. * resource-constrained systems.
  717. */
  718. TEST_F(AdvancedSchedulerTest, TaskTimeoutExpiration) {
  719. Scheduler ts;
  720. Task task(50, TASK_FOREVER, &timeout_sensitive_callback, &ts, true);
  721. // Set short timeout
  722. task.setTimeout(200, true);
  723. // Task should execute normally initially
  724. bool success = runAdvancedSchedulerUntil(ts, []() {
  725. return advanced_callback_counter >= 2;
  726. });
  727. EXPECT_TRUE(success);
  728. // Wait for timeout to expire
  729. delay(250);
  730. // Run scheduler to trigger timeout processing
  731. ts.execute();
  732. // Task should be timed out and disabled
  733. EXPECT_TRUE(task.timedOut());
  734. EXPECT_FALSE(task.isEnabled());
  735. // No further executions should occur
  736. int count_before = advanced_callback_counter;
  737. delay(100);
  738. ts.execute();
  739. EXPECT_EQ(advanced_callback_counter, count_before);
  740. }
  741. // ================== STATUS REQUEST TIMEOUT INTEGRATION TESTS ==================
  742. /**
  743. * @brief Test StatusRequest timeout functionality
  744. *
  745. * TESTS: StatusRequest::setTimeout(), resetTimeout(), untilTimeout()
  746. *
  747. * PURPOSE: Verify that StatusRequest objects support timeout functionality
  748. * for deadline-driven event coordination, preventing indefinite waiting
  749. * in event-driven scenarios.
  750. *
  751. * STATUS REQUEST TIMEOUT BEHAVIOR:
  752. * - setTimeout(timeout): Sets deadline for StatusRequest completion
  753. * - resetTimeout(): Restarts timeout timer for StatusRequest
  754. * - untilTimeout(): Returns remaining time until StatusRequest timeout
  755. * - Timeout handling prevents indefinite blocking on events
  756. * - Essential for robust event-driven coordination
  757. *
  758. * TEST SCENARIO:
  759. * 1. Create StatusRequest and set timeout
  760. * 2. Verify timeout configuration
  761. * 3. Test resetTimeout() functionality
  762. * 4. Monitor untilTimeout() behavior over time
  763. * 5. Verify timeout detection capabilities
  764. *
  765. * EXPECTATIONS:
  766. * - setTimeout() configures StatusRequest deadline
  767. * - untilTimeout() decreases as time passes
  768. * - resetTimeout() restarts timing correctly
  769. * - Timeout detection works as expected
  770. *
  771. * IMPORTANCE: StatusRequest timeouts prevent deadlock scenarios
  772. * in event-driven systems and enable deadline-based coordination
  773. * patterns essential for reliable multi-task systems.
  774. */
  775. TEST_F(AdvancedSchedulerTest, StatusRequestTimeout) {
  776. StatusRequest sr;
  777. sr.setWaiting(1);
  778. // Set timeout for StatusRequest
  779. sr.setTimeout(300);
  780. sr.resetTimeout();
  781. EXPECT_EQ(sr.getTimeout(), 300);
  782. // Check initial time until timeout
  783. long until_timeout = sr.untilTimeout();
  784. EXPECT_GT(until_timeout, 250);
  785. EXPECT_LE(until_timeout, 300);
  786. // Wait and check again
  787. delay(150);
  788. until_timeout = sr.untilTimeout();
  789. EXPECT_GT(until_timeout, 100);
  790. EXPECT_LE(until_timeout, 150);
  791. // Reset timeout
  792. sr.resetTimeout();
  793. until_timeout = sr.untilTimeout();
  794. EXPECT_GT(until_timeout, 250);
  795. EXPECT_LE(until_timeout, 300);
  796. }
  797. // ================== SCHEDULING OPTIONS TESTS ==================
  798. /**
  799. * @brief Test task scheduling options functionality
  800. *
  801. * TESTS: setSchedulingOption(), getSchedulingOption()
  802. *
  803. * PURPOSE: Verify that scheduling options can be configured and retrieved,
  804. * enabling advanced scheduling behavior control for specialized
  805. * execution patterns and priority management.
  806. *
  807. * SCHEDULING OPTIONS BEHAVIOR:
  808. * - setSchedulingOption(option): Configures task scheduling behavior
  809. * - getSchedulingOption(): Retrieves current scheduling configuration
  810. * - Options control execution priority, timing, and behavior
  811. * - Enables fine-grained scheduling control
  812. * - Critical for advanced task management scenarios
  813. *
  814. * TEST SCENARIO:
  815. * 1. Create task with default scheduling option
  816. * 2. Set various scheduling options and verify configuration
  817. * 3. Test option retrieval matches set values
  818. * 4. Verify options can be changed dynamically
  819. * 5. Test with multiple different option values
  820. *
  821. * EXPECTATIONS:
  822. * - setSchedulingOption() configures option value
  823. * - getSchedulingOption() returns set value correctly
  824. * - Options can be changed dynamically
  825. * - Configuration persists across calls
  826. *
  827. * IMPORTANCE: Scheduling options enable advanced task behavior control
  828. * essential for priority management, resource allocation, and
  829. * specialized execution patterns in complex applications.
  830. *
  831. * TODO: This needs to be completely redone - this AI generated test is absolutely wrong
  832. */
  833. TEST_F(AdvancedSchedulerTest, TaskSchedulingOptions) {
  834. Scheduler ts;
  835. Task task(100, 5, &advanced_status_callback, &ts, false);
  836. // Test default scheduling option
  837. unsigned int default_option = task.getSchedulingOption();
  838. // Set different scheduling options
  839. task.setSchedulingOption(TASK_SCHEDULE);
  840. EXPECT_EQ(task.getSchedulingOption(), TASK_SCHEDULE);
  841. task.setSchedulingOption(TASK_SCHEDULE_NC);
  842. EXPECT_EQ(task.getSchedulingOption(), TASK_SCHEDULE_NC);
  843. task.setSchedulingOption(TASK_INTERVAL);
  844. EXPECT_EQ(task.getSchedulingOption(), TASK_INTERVAL);
  845. // Verify option can be changed while task is enabled
  846. task.enable();
  847. task.setSchedulingOption(TASK_SCHEDULE_NC);
  848. EXPECT_EQ(task.getSchedulingOption(), TASK_SCHEDULE_NC);
  849. EXPECT_TRUE(task.isEnabled()); // Should remain enabled
  850. }
  851. // ================== SELF-DESTRUCT FUNCTIONALITY TESTS ==================
  852. /**
  853. * @brief Test task self-destruct functionality (placeholder test)
  854. *
  855. * TESTS: Task self-destruct behavior when enabled
  856. *
  857. * PURPOSE: Verify that tasks can be configured to automatically remove
  858. * themselves from the scheduler after completion, enabling automatic
  859. * resource cleanup and dynamic task lifecycle management.
  860. *
  861. * SELF-DESTRUCT BEHAVIOR:
  862. * - Tasks automatically remove themselves from scheduler
  863. * - Occurs after task completes execution cycle
  864. * - Prevents memory leaks in dynamic task scenarios
  865. * - Enables automatic cleanup patterns
  866. * - Critical for long-running applications with temporary tasks
  867. *
  868. * NOTE: This test serves as a placeholder for self-destruct functionality.
  869. * The actual implementation details depend on specific TaskScheduler
  870. * version and may require additional setup or different API calls.
  871. *
  872. * TEST SCENARIO:
  873. * 1. Create task configured for self-destruction
  874. * 2. Let task execute its lifecycle
  875. * 3. Verify task removes itself from scheduler
  876. * 4. Confirm no further executions occur
  877. * 5. Test scheduler continues operating normally
  878. *
  879. * EXPECTATIONS:
  880. * - Task executes normally initially
  881. * - Task removes itself after completion
  882. * - No further executions occur
  883. * - Scheduler remains functional
  884. *
  885. * IMPORTANCE: Self-destruct functionality enables automatic resource
  886. * management essential for dynamic applications and prevents memory
  887. * leaks in long-running systems with temporary tasks.
  888. */
  889. TEST_F(AdvancedSchedulerTest, TaskSelfDestruct) {
  890. Scheduler ts;
  891. // Create a task that will self-destruct after execution
  892. // Note: Actual self-destruct implementation may vary by TaskScheduler version
  893. Task* temp_task = new Task(100, 1, &self_destruct_callback, &ts, true);
  894. // Let task execute
  895. bool success = runAdvancedSchedulerUntil(ts, []() {
  896. return task_self_destructed;
  897. });
  898. EXPECT_TRUE(success);
  899. EXPECT_EQ(getAdvancedTestOutput(0), "self_destruct_executed");
  900. // Note: In a full implementation, we would verify the task
  901. // has been removed from the scheduler's task list
  902. // This would require access to internal scheduler state
  903. // Clean up manually for this test
  904. delete temp_task;
  905. }
  906. // ================== INTEGRATION AND COMPLEX SCENARIOS ==================
  907. /**
  908. * @brief Integration test combining status requests with timeouts
  909. *
  910. * TESTS: StatusRequest + Task timeout integration
  911. *
  912. * PURPOSE: Verify that status request coordination works correctly
  913. * with task timeouts, ensuring robust behavior when events may
  914. * not occur within expected timeframes.
  915. *
  916. * INTEGRATION BEHAVIOR:
  917. * - Tasks can wait for StatusRequest with timeout protection
  918. * - Timeout overrides StatusRequest waiting if deadline exceeded
  919. * - Proper cleanup occurs when timeout prevents event completion
  920. * - Enables robust event-driven patterns with deadline guarantees
  921. * - Critical for reliable real-time coordination
  922. *
  923. * TEST SCENARIO:
  924. * 1. Create StatusRequest that won't complete within timeout
  925. * 2. Create task waiting for StatusRequest with timeout
  926. * 3. Verify task times out rather than waiting indefinitely
  927. * 4. Test proper cleanup and status handling
  928. * 5. Verify system remains stable after timeout
  929. *
  930. * EXPECTATIONS:
  931. * - Task times out rather than waiting indefinitely
  932. * - Timeout handling works despite pending StatusRequest
  933. * - System cleanup occurs properly
  934. * - No resource leaks or deadlocks
  935. *
  936. * IMPORTANCE: Timeout protection in event-driven scenarios prevents
  937. * deadlocks and ensures system reliability, essential for robust
  938. * real-time applications.
  939. */
  940. TEST_F(AdvancedSchedulerTest, StatusRequestWithTimeout) {
  941. Scheduler ts;
  942. StatusRequest sr;
  943. // Set up StatusRequest that won't complete
  944. sr.setWaiting(1);
  945. sr.setTimeout(150);
  946. sr.resetTimeout();
  947. // Create task waiting for StatusRequest
  948. Task waiter(100, 1, &consumer_callback, &ts);
  949. waiter.waitFor(&sr);
  950. waiter.setTimeout(200, true); // Task timeout longer than SR timeout
  951. // Let everything run - StatusRequest should timeout first
  952. delay(300);
  953. // Run scheduler to process timeouts
  954. for (int i = 0; i < 10; i++) {
  955. ts.execute();
  956. delay(10);
  957. }
  958. // Verify StatusRequest timed out
  959. EXPECT_LE(sr.untilTimeout(), 0); // Should be negative (timed out)
  960. // Task should eventually time out as well since SR never completed
  961. EXPECT_TRUE(waiter.timedOut() || !waiter.isEnabled());
  962. }
  963. /**
  964. * @brief Complex producer-consumer coordination with multiple features
  965. *
  966. * TESTS: Multi-feature integration in realistic scenario
  967. *
  968. * PURPOSE: Demonstrate complex coordination scenario using multiple
  969. * advanced features together, validating that features work correctly
  970. * in combination for real-world usage patterns.
  971. *
  972. * COMPLEX INTEGRATION FEATURES:
  973. * - Producer task with timeout management
  974. * - Multiple consumers waiting for producer completion
  975. * - StatusRequest coordination with error handling
  976. * - Scheduling options for priority control
  977. * - Comprehensive error and timeout handling
  978. *
  979. * TEST SCENARIO:
  980. * 1. Create producer task with timeout and high priority
  981. * 2. Create multiple consumer tasks waiting for producer
  982. * 3. Configure timeouts and scheduling options appropriately
  983. * 4. Execute coordination scenario with success path
  984. * 5. Verify all consumers execute after producer completion
  985. *
  986. * EXPECTATIONS:
  987. * - Producer executes with proper priority and timing
  988. * - All consumers wait appropriately for producer
  989. * - StatusRequest coordination works correctly
  990. * - All tasks execute in expected order
  991. * - No timeouts or errors in success scenario
  992. *
  993. * IMPORTANCE: Complex integration validates that advanced features
  994. * work together reliably, essential for building sophisticated
  995. * multi-task applications with robust coordination patterns.
  996. */
  997. TEST_F(AdvancedSchedulerTest, ComplexProducerConsumerCoordination) {
  998. Scheduler ts;
  999. StatusRequest production_complete;
  1000. // Set up production status request
  1001. production_complete.setWaiting(1);
  1002. production_complete.setTimeout(1000); // Allow plenty of time
  1003. production_complete.resetTimeout();
  1004. // Set global pointer for producer callback
  1005. global_status_request = &production_complete;
  1006. // Create producer task with high priority
  1007. Task producer(150, 1, &producer_callback, &ts, true);
  1008. producer.setTimeout(500, true);
  1009. producer.setSchedulingOption(10); // High priority
  1010. // Create multiple consumer tasks
  1011. Task consumer1(100, 1, &consumer1_callback, &ts);
  1012. Task consumer2(100, 1, &consumer2_callback, &ts);
  1013. Task consumer3(100, 1, &consumer3_callback, &ts);
  1014. // Configure consumers to wait for production
  1015. consumer1.waitFor(&production_complete);
  1016. consumer1.setTimeout(800, true);
  1017. consumer2.waitFor(&production_complete);
  1018. consumer2.setTimeout(800, true);
  1019. consumer3.waitFor(&production_complete);
  1020. consumer3.setTimeout(800, true);
  1021. // Execute the coordination scenario
  1022. bool success = runAdvancedSchedulerUntil(ts, []() {
  1023. return advanced_callback_counter >= 4; // Producer + 3 consumers
  1024. }, 1500);
  1025. EXPECT_TRUE(success);
  1026. EXPECT_EQ(advanced_callback_counter, 4);
  1027. // Verify execution order - producer should be first
  1028. EXPECT_EQ(getAdvancedTestOutput(0), "producer_completed");
  1029. // Verify StatusRequest completed successfully
  1030. EXPECT_TRUE(production_complete.completed());
  1031. EXPECT_EQ(production_complete.getStatus(), 100);
  1032. // Verify no timeouts occurred
  1033. EXPECT_FALSE(producer.timedOut());
  1034. EXPECT_FALSE(consumer1.timedOut());
  1035. EXPECT_FALSE(consumer2.timedOut());
  1036. EXPECT_FALSE(consumer3.timedOut());
  1037. // Clean up global pointer
  1038. global_status_request = nullptr;
  1039. }
  1040. /**
  1041. * @brief Producer-consumer scenario with yield switching
  1042. *
  1043. * TESTS: StatusRequest coordination with callback switching
  1044. *
  1045. * PURPOSE: Test complex scenario where tasks change behavior based
  1046. * on StatusRequest completion, demonstrating state machine patterns
  1047. * with event-driven coordination.
  1048. */
  1049. TEST_F(AdvancedSchedulerTest, ProducerConsumerWithYieldSwitching) {
  1050. Scheduler ts;
  1051. StatusRequest sr;
  1052. sr.setWaiting(1);
  1053. global_status_request = &sr;
  1054. // Create producer that will signal completion
  1055. Task producer(100, 1, &producer_callback, &ts, true);
  1056. // Create consumer that will yield to different callback after SR completion
  1057. Task consumer(100, 2, consumer_yield_callback, &ts);
  1058. global_advanced_yield_task = &consumer;
  1059. consumer.waitFor(&sr);
  1060. // Run the scenario
  1061. bool success = runAdvancedSchedulerUntil(ts, []() {
  1062. return advanced_test_output.size() >= 3; // producer + consumer initial + consumer yielded
  1063. }, 1000);
  1064. EXPECT_TRUE(success);
  1065. EXPECT_EQ(getAdvancedTestOutput(0), "producer_completed");
  1066. EXPECT_EQ(getAdvancedTestOutput(1), "consumer_initial");
  1067. EXPECT_EQ(getAdvancedTestOutput(2), "step_2");
  1068. // Clean up
  1069. global_status_request = nullptr;
  1070. global_advanced_yield_task = nullptr;
  1071. }
  1072. /**
  1073. * @brief Main test runner function for advanced features
  1074. *
  1075. * Initializes Google Test framework and runs all advanced feature tests.
  1076. * Called by the test execution environment to start testing process.
  1077. *
  1078. * @param argc Command line argument count
  1079. * @param argv Command line argument values
  1080. * @return Test execution status (0 = success)
  1081. */
  1082. int main(int argc, char **argv) {
  1083. ::testing::InitGoogleTest(&argc, argv);
  1084. return RUN_ALL_TESTS();
  1085. }