1+ #include < Arduino.h>
2+ #include < unity.h>
3+ #include < ExecWithParameter.h>
4+ #include < IoLogging.h>
5+ #include " TaskManagerIO.h"
6+ #include " ../utils/test_utils.h"
7+
8+ TimingHelpFixture fixture;
9+
10+ void setUp () {
11+ fixture.setup ();
12+ }
13+
14+ void tearDown () {}
15+
16+ // these variables are set during test runs to time and verify tasks are run.
17+ bool scheduled = false ;
18+ bool scheduled2ndJob = false ;
19+ unsigned long microsStarted = 0 , microsExecuted = 0 , microsExecuted2ndJob = 0 ;
20+ int count1 = 0 , count2 = 0 ;
21+ uint8_t pinNo = 0 ;
22+
23+ void recordingJob () {
24+ microsExecuted = micros ();
25+ count1++;
26+ scheduled = true ;
27+ }
28+
29+ void recordingJob2 () {
30+ microsExecuted2ndJob = micros ();
31+ count2++;
32+ scheduled2ndJob = true ;
33+ }
34+
35+
36+ class TestingExec : public Executable {
37+ public:
38+ int noOfTimesRun;
39+
40+ TestingExec () {
41+ noOfTimesRun = 0 ;
42+ }
43+
44+ void exec () override {
45+ noOfTimesRun++;
46+ }
47+ };
48+
49+ TestingExec exec;
50+
51+ void testRunningUsingExecutorClass () {
52+ taskManager.scheduleFixedRate (10 , &::exec);
53+ taskManager.scheduleOnce (250 , recordingJob);
54+
55+ fixture.assertThatTaskRunsOnTime (250000L , MILLIS_ALLOWANCE);
56+ TEST_ASSERT_GREATER_THAN (10 , ::exec.noOfTimesRun );
57+ }
58+
59+ void testSchedulingTaskOnceInMicroseconds () {
60+ taskManager.scheduleOnce (800 , recordingJob, TIME_MICROS);
61+ fixture.assertThatTaskRunsOnTime (800 , MICROS_ALLOWANCE);
62+ fixture.assertTasksSpacesTaken (0 );
63+ }
64+
65+ void testSchedulingTaskOnceInMilliseconds () {
66+ taskManager.scheduleOnce (20 , recordingJob, TIME_MILLIS);
67+ fixture.assertThatTaskRunsOnTime (19500 , MILLIS_ALLOWANCE);
68+ fixture.assertTasksSpacesTaken (0 );
69+ }
70+
71+ void testSchedulingTaskOnceInSeconds () {
72+ taskManager.scheduleOnce (2 , recordingJob, TIME_SECONDS);
73+ // Second scheduling is not as granular, we need to allow +- 100mS.
74+ fixture.assertThatTaskRunsOnTime (2000000L , MILLIS_ALLOWANCE);
75+ fixture.assertTasksSpacesTaken (0 );
76+ }
77+
78+ void testScheduleManyJobsAtOnce () {
79+ taskManager.scheduleOnce (1 , [] {}, TIME_SECONDS);
80+ taskManager.scheduleOnce (200 , recordingJob, TIME_MILLIS);
81+ taskManager.scheduleOnce (250 , recordingJob2, TIME_MICROS);
82+
83+ fixture.assertThatTaskRunsOnTime (199500 , MILLIS_ALLOWANCE);
84+ fixture.assertThatSecondJobRan (250 , MICROS_ALLOWANCE);
85+ fixture.assertTasksSpacesTaken (1 );
86+ }
87+
88+ void testEnableAndDisableSupport () {
89+ static int myTaskCounter = 0 ;
90+ auto myTaskId = taskManager.scheduleFixedRate (1 , [] { myTaskCounter++; }, TIME_MILLIS);
91+ taskManager.yieldForMicros (20000 );
92+ TEST_ASSERT_NOT_EQUAL (0 , myTaskCounter);
93+
94+ // "turn off" the task
95+ taskManager.setTaskEnabled (myTaskId, false );
96+
97+ // It can take one cycle for the task to switch enablement state.
98+ taskManager.yieldForMicros (2000 );
99+ auto oldTaskCount = myTaskCounter;
100+
101+ // Now run the task for some time, it should never get scheduled.
102+ taskManager.yieldForMicros (20000 );
103+ TEST_ASSERT_EQUAL (myTaskCounter, oldTaskCount);
104+
105+ // "turn on" the task and see if it increases again
106+ taskManager.setTaskEnabled (myTaskId, true );
107+ taskManager.yieldForMicros (20000 );
108+ TEST_ASSERT_NOT_EQUAL (myTaskCounter, oldTaskCount);
109+ }
110+
111+ void testScheduleFixedRate () {
112+ TEST_ASSERT_EQUAL (nullptr , taskManager.getFirstTask ());
113+
114+ auto taskId1 = taskManager.scheduleFixedRate (10 , recordingJob, TIME_MILLIS);
115+ auto taskId2 = taskManager.scheduleFixedRate (100 , recordingJob2, TIME_MICROS);
116+
117+ // Now check the task registration in detail.
118+ TEST_ASSERT_NOT_EQUAL (TASKMGR_INVALIDID, taskId1);
119+ TimerTask* task = taskManager.getFirstTask ();
120+ TEST_ASSERT_NOT_EQUAL (nullptr , task);
121+ TEST_ASSERT_FALSE (task->isMillisSchedule ());
122+ TEST_ASSERT_TRUE (task->isMicrosSchedule ());
123+
124+ // Now check the task registration in detail.
125+ TEST_ASSERT_NOT_EQUAL (TASKMGR_INVALIDID, taskId2);
126+ task = task->getNext ();
127+ TEST_ASSERT_NOT_EQUAL (nullptr , task);
128+ TEST_ASSERT_TRUE (task->isMillisSchedule ());
129+ TEST_ASSERT_FALSE (task->isMicrosSchedule ());
130+
131+ dumpTasks ();
132+
133+ uint32_t timeStartYield = millis ();
134+ taskManager.yieldForMicros (secondsToMillis (22 ));
135+ uint32_t timeTaken = millis () - timeStartYield;
136+
137+ dumpTasks ();
138+
139+ // Make sure the yield timings were in range.
140+ TEST_ASSERT_LESS_THAN (25U , timeTaken);
141+ TEST_ASSERT_GREATER_THAN (19U , timeTaken);
142+
143+ // Now make sure that we got in the right ballpark of calls.
144+ TEST_ASSERT_GREATER_THAN (1 , count1);
145+ TEST_ASSERT_GREATER_THAN (150 , count2);
146+ }
147+
148+ void testCancellingAJobAfterCreation () {
149+ TEST_ASSERT_EQUAL (nullptr , taskManager.getFirstTask ());
150+
151+ auto taskId = taskManager.scheduleFixedRate (10 , recordingJob, TIME_MILLIS);
152+
153+ // Now check the task registration in detail.
154+ TEST_ASSERT_NOT_EQUAL (TASKMGR_INVALIDID, taskId);
155+ TimerTask* task = taskManager.getFirstTask ();
156+ TEST_ASSERT_NOT_EQUAL (nullptr , task);
157+ TEST_ASSERT_TRUE (task->isMillisSchedule ());
158+ TEST_ASSERT_FALSE (task->isMicrosSchedule ());
159+ TEST_ASSERT_GREATER_THAN (8000UL , task->microsFromNow ());
160+
161+ fixture.assertThatTaskRunsOnTime (10000 , MILLIS_ALLOWANCE);
162+
163+ // Cancel the task and make sure everything is cleared down
164+ fixture.assertTasksSpacesTaken (1 );
165+ taskManager.cancelTask (taskId);
166+ taskManager.yieldForMicros (100 ); // Needs to run the cancellation task.
167+ fixture.assertTasksSpacesTaken (0 );
168+
169+ TEST_ASSERT_EQUAL (nullptr , taskManager.getFirstTask ());
170+ }
171+
172+ void setup () {
173+ UNITY_BEGIN ();
174+ RUN_TEST (testRunningUsingExecutorClass);
175+ RUN_TEST (testSchedulingTaskOnceInMicroseconds);
176+ RUN_TEST (testSchedulingTaskOnceInMilliseconds);
177+ RUN_TEST (testSchedulingTaskOnceInSeconds);
178+ RUN_TEST (testScheduleManyJobsAtOnce);
179+ RUN_TEST (testEnableAndDisableSupport);
180+ RUN_TEST (testScheduleFixedRate);
181+ RUN_TEST (testCancellingAJobAfterCreation);
182+ UNITY_END ();
183+ }
184+
185+ void loop () {}
0 commit comments