xref: /aosp_15_r20/external/openthread/tests/unit/test_trickle_timer.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2023, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
30*cfb92d14SAndroid Build Coastguard Worker 
31*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
32*cfb92d14SAndroid Build Coastguard Worker #include "common/debug.hpp"
33*cfb92d14SAndroid Build Coastguard Worker #include "common/num_utils.hpp"
34*cfb92d14SAndroid Build Coastguard Worker #include "common/trickle_timer.hpp"
35*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
36*cfb92d14SAndroid Build Coastguard Worker 
37*cfb92d14SAndroid Build Coastguard Worker namespace ot {
38*cfb92d14SAndroid Build Coastguard Worker 
39*cfb92d14SAndroid Build Coastguard Worker static Instance *sInstance;
40*cfb92d14SAndroid Build Coastguard Worker 
41*cfb92d14SAndroid Build Coastguard Worker static uint32_t sNow = 0;
42*cfb92d14SAndroid Build Coastguard Worker static uint32_t sAlarmTime;
43*cfb92d14SAndroid Build Coastguard Worker static bool     sAlarmOn = false;
44*cfb92d14SAndroid Build Coastguard Worker 
45*cfb92d14SAndroid Build Coastguard Worker extern "C" {
46*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliStop(otInstance *)47*cfb92d14SAndroid Build Coastguard Worker void otPlatAlarmMilliStop(otInstance *) { sAlarmOn = false; }
48*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliStartAt(otInstance *,uint32_t aT0,uint32_t aDt)49*cfb92d14SAndroid Build Coastguard Worker void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
50*cfb92d14SAndroid Build Coastguard Worker {
51*cfb92d14SAndroid Build Coastguard Worker     sAlarmOn   = true;
52*cfb92d14SAndroid Build Coastguard Worker     sAlarmTime = aT0 + aDt;
53*cfb92d14SAndroid Build Coastguard Worker }
54*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliGetNow(void)55*cfb92d14SAndroid Build Coastguard Worker uint32_t otPlatAlarmMilliGetNow(void) { return sNow; }
56*cfb92d14SAndroid Build Coastguard Worker 
57*cfb92d14SAndroid Build Coastguard Worker } // extern "C"
58*cfb92d14SAndroid Build Coastguard Worker 
AdvanceTime(uint32_t aDuration)59*cfb92d14SAndroid Build Coastguard Worker void AdvanceTime(uint32_t aDuration)
60*cfb92d14SAndroid Build Coastguard Worker {
61*cfb92d14SAndroid Build Coastguard Worker     uint32_t time = sNow + aDuration;
62*cfb92d14SAndroid Build Coastguard Worker 
63*cfb92d14SAndroid Build Coastguard Worker     while (TimeMilli(sAlarmTime) <= TimeMilli(time))
64*cfb92d14SAndroid Build Coastguard Worker     {
65*cfb92d14SAndroid Build Coastguard Worker         sNow = sAlarmTime;
66*cfb92d14SAndroid Build Coastguard Worker         otPlatAlarmMilliFired(sInstance);
67*cfb92d14SAndroid Build Coastguard Worker     }
68*cfb92d14SAndroid Build Coastguard Worker 
69*cfb92d14SAndroid Build Coastguard Worker     sNow = time;
70*cfb92d14SAndroid Build Coastguard Worker }
71*cfb92d14SAndroid Build Coastguard Worker 
72*cfb92d14SAndroid Build Coastguard Worker class TrickleTimerTester : public TrickleTimer
73*cfb92d14SAndroid Build Coastguard Worker {
74*cfb92d14SAndroid Build Coastguard Worker public:
TrickleTimerTester(Instance & aInstance)75*cfb92d14SAndroid Build Coastguard Worker     explicit TrickleTimerTester(Instance &aInstance)
76*cfb92d14SAndroid Build Coastguard Worker         : TrickleTimer(aInstance, HandleTimerFired)
77*cfb92d14SAndroid Build Coastguard Worker         , mDidFire(false)
78*cfb92d14SAndroid Build Coastguard Worker     {
79*cfb92d14SAndroid Build Coastguard Worker     }
80*cfb92d14SAndroid Build Coastguard Worker 
GetFireTime(void) const81*cfb92d14SAndroid Build Coastguard Worker     Time     GetFireTime(void) const { return TimerMilli::GetFireTime(); }
GetInterval(void) const82*cfb92d14SAndroid Build Coastguard Worker     uint32_t GetInterval(void) const { return TrickleTimer::mInterval; }
GetTimeInInterval(void) const83*cfb92d14SAndroid Build Coastguard Worker     uint32_t GetTimeInInterval(void) const { return TrickleTimer::mTimeInInterval; }
84*cfb92d14SAndroid Build Coastguard Worker 
VerifyTimerDidFire(void)85*cfb92d14SAndroid Build Coastguard Worker     void VerifyTimerDidFire(void)
86*cfb92d14SAndroid Build Coastguard Worker     {
87*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mDidFire);
88*cfb92d14SAndroid Build Coastguard Worker         mDidFire = false;
89*cfb92d14SAndroid Build Coastguard Worker     }
90*cfb92d14SAndroid Build Coastguard Worker 
VerifyTimerDidNotFire(void) const91*cfb92d14SAndroid Build Coastguard Worker     void VerifyTimerDidNotFire(void) const { VerifyOrQuit(!mDidFire); }
92*cfb92d14SAndroid Build Coastguard Worker 
RemoveAll(Instance & aInstance)93*cfb92d14SAndroid Build Coastguard Worker     static void RemoveAll(Instance &aInstance) { TimerMilli::RemoveAll(aInstance); }
94*cfb92d14SAndroid Build Coastguard Worker 
95*cfb92d14SAndroid Build Coastguard Worker private:
HandleTimerFired(TrickleTimer & aTimer)96*cfb92d14SAndroid Build Coastguard Worker     static void HandleTimerFired(TrickleTimer &aTimer) { static_cast<TrickleTimerTester &>(aTimer).HandleTimerFired(); }
HandleTimerFired(void)97*cfb92d14SAndroid Build Coastguard Worker     void        HandleTimerFired(void) { mDidFire = true; }
98*cfb92d14SAndroid Build Coastguard Worker 
99*cfb92d14SAndroid Build Coastguard Worker     bool mDidFire;
100*cfb92d14SAndroid Build Coastguard Worker };
101*cfb92d14SAndroid Build Coastguard Worker 
AlarmFired(otInstance * aInstance)102*cfb92d14SAndroid Build Coastguard Worker void AlarmFired(otInstance *aInstance) { otPlatAlarmMilliFired(aInstance); }
103*cfb92d14SAndroid Build Coastguard Worker 
TestTrickleTimerPlainMode(void)104*cfb92d14SAndroid Build Coastguard Worker void TestTrickleTimerPlainMode(void)
105*cfb92d14SAndroid Build Coastguard Worker {
106*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint32_t kMinInterval = 2000;
107*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint32_t kMaxInterval = 5000;
108*cfb92d14SAndroid Build Coastguard Worker 
109*cfb92d14SAndroid Build Coastguard Worker     Instance          *instance = testInitInstance();
110*cfb92d14SAndroid Build Coastguard Worker     TrickleTimerTester timer(*instance);
111*cfb92d14SAndroid Build Coastguard Worker     uint32_t           interval;
112*cfb92d14SAndroid Build Coastguard Worker 
113*cfb92d14SAndroid Build Coastguard Worker     sInstance = instance;
114*cfb92d14SAndroid Build Coastguard Worker     TrickleTimerTester::RemoveAll(*instance);
115*cfb92d14SAndroid Build Coastguard Worker 
116*cfb92d14SAndroid Build Coastguard Worker     printf("TestTrickleTimerPlainMode() ");
117*cfb92d14SAndroid Build Coastguard Worker 
118*cfb92d14SAndroid Build Coastguard Worker     // Validate that timer picks a random interval between min and max
119*cfb92d14SAndroid Build Coastguard Worker     // on start.
120*cfb92d14SAndroid Build Coastguard Worker 
121*cfb92d14SAndroid Build Coastguard Worker     sNow = 1000;
122*cfb92d14SAndroid Build Coastguard Worker     timer.Start(TrickleTimer::kModePlainTimer, kMinInterval, kMaxInterval, 0);
123*cfb92d14SAndroid Build Coastguard Worker 
124*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
125*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == kMaxInterval);
126*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMin() == kMinInterval);
127*cfb92d14SAndroid Build Coastguard Worker 
128*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
129*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval >= kMinInterval) && (interval <= kMaxInterval));
130*cfb92d14SAndroid Build Coastguard Worker 
131*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter <= 10; iter++)
132*cfb92d14SAndroid Build Coastguard Worker     {
133*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(interval);
134*cfb92d14SAndroid Build Coastguard Worker 
135*cfb92d14SAndroid Build Coastguard Worker         timer.VerifyTimerDidFire();
136*cfb92d14SAndroid Build Coastguard Worker 
137*cfb92d14SAndroid Build Coastguard Worker         // The plain mode trickle timer restarts with a new random
138*cfb92d14SAndroid Build Coastguard Worker         // interval between min and max.
139*cfb92d14SAndroid Build Coastguard Worker 
140*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(timer.IsRunning());
141*cfb92d14SAndroid Build Coastguard Worker         interval = timer.GetInterval();
142*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit((interval >= kMinInterval) && (interval <= kMaxInterval));
143*cfb92d14SAndroid Build Coastguard Worker     }
144*cfb92d14SAndroid Build Coastguard Worker 
145*cfb92d14SAndroid Build Coastguard Worker     printf(" --> PASSED\n");
146*cfb92d14SAndroid Build Coastguard Worker 
147*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(instance);
148*cfb92d14SAndroid Build Coastguard Worker }
149*cfb92d14SAndroid Build Coastguard Worker 
TestTrickleTimerTrickleMode(uint32_t aRedundancyConstant,uint32_t aConsistentCalls)150*cfb92d14SAndroid Build Coastguard Worker void TestTrickleTimerTrickleMode(uint32_t aRedundancyConstant, uint32_t aConsistentCalls)
151*cfb92d14SAndroid Build Coastguard Worker {
152*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint32_t kMinInterval = 1000;
153*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint32_t kMaxInterval = 9000;
154*cfb92d14SAndroid Build Coastguard Worker 
155*cfb92d14SAndroid Build Coastguard Worker     Instance          *instance = testInitInstance();
156*cfb92d14SAndroid Build Coastguard Worker     TrickleTimerTester timer(*instance);
157*cfb92d14SAndroid Build Coastguard Worker     uint32_t           interval;
158*cfb92d14SAndroid Build Coastguard Worker     uint32_t           t;
159*cfb92d14SAndroid Build Coastguard Worker 
160*cfb92d14SAndroid Build Coastguard Worker     sInstance = instance;
161*cfb92d14SAndroid Build Coastguard Worker     TrickleTimerTester::RemoveAll(*instance);
162*cfb92d14SAndroid Build Coastguard Worker 
163*cfb92d14SAndroid Build Coastguard Worker     printf("TestTrickleTimerTrickleMode(aRedundancyConstant:%u, aConsistentCalls:%u) ", aRedundancyConstant,
164*cfb92d14SAndroid Build Coastguard Worker            aConsistentCalls);
165*cfb92d14SAndroid Build Coastguard Worker 
166*cfb92d14SAndroid Build Coastguard Worker     sNow = 1000;
167*cfb92d14SAndroid Build Coastguard Worker     timer.Start(TrickleTimer::kModeTrickle, kMinInterval, kMaxInterval, aRedundancyConstant);
168*cfb92d14SAndroid Build Coastguard Worker 
169*cfb92d14SAndroid Build Coastguard Worker     // Validate that trickle timer starts with random interval between
170*cfb92d14SAndroid Build Coastguard Worker     // min/max.
171*cfb92d14SAndroid Build Coastguard Worker 
172*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
173*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == kMaxInterval);
174*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMin() == kMinInterval);
175*cfb92d14SAndroid Build Coastguard Worker 
176*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
177*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((kMinInterval <= interval) && (interval <= kMaxInterval));
178*cfb92d14SAndroid Build Coastguard Worker     t = timer.GetTimeInInterval();
179*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t <= interval));
180*cfb92d14SAndroid Build Coastguard Worker 
181*cfb92d14SAndroid Build Coastguard Worker     // After `IndicateInconsistent()` should go back to min
182*cfb92d14SAndroid Build Coastguard Worker     // interval.
183*cfb92d14SAndroid Build Coastguard Worker 
184*cfb92d14SAndroid Build Coastguard Worker     timer.IndicateInconsistent();
185*cfb92d14SAndroid Build Coastguard Worker 
186*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
187*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
188*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == kMinInterval);
189*cfb92d14SAndroid Build Coastguard Worker     t = timer.GetTimeInInterval();
190*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t <= interval));
191*cfb92d14SAndroid Build Coastguard Worker 
192*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 10; iter++)
193*cfb92d14SAndroid Build Coastguard Worker     {
194*cfb92d14SAndroid Build Coastguard Worker         for (uint32_t index = 0; index < aConsistentCalls; index++)
195*cfb92d14SAndroid Build Coastguard Worker         {
196*cfb92d14SAndroid Build Coastguard Worker             timer.IndicateConsistent();
197*cfb92d14SAndroid Build Coastguard Worker         }
198*cfb92d14SAndroid Build Coastguard Worker 
199*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(t);
200*cfb92d14SAndroid Build Coastguard Worker 
201*cfb92d14SAndroid Build Coastguard Worker         if (aConsistentCalls < aRedundancyConstant)
202*cfb92d14SAndroid Build Coastguard Worker         {
203*cfb92d14SAndroid Build Coastguard Worker             timer.VerifyTimerDidFire();
204*cfb92d14SAndroid Build Coastguard Worker         }
205*cfb92d14SAndroid Build Coastguard Worker         else
206*cfb92d14SAndroid Build Coastguard Worker         {
207*cfb92d14SAndroid Build Coastguard Worker             timer.VerifyTimerDidNotFire();
208*cfb92d14SAndroid Build Coastguard Worker         }
209*cfb92d14SAndroid Build Coastguard Worker 
210*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(interval - t);
211*cfb92d14SAndroid Build Coastguard Worker 
212*cfb92d14SAndroid Build Coastguard Worker         // Verify that interval is doubling each time up
213*cfb92d14SAndroid Build Coastguard Worker         // to max interval.
214*cfb92d14SAndroid Build Coastguard Worker 
215*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(timer.IsRunning());
216*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(timer.GetInterval() == Min(interval * 2, kMaxInterval));
217*cfb92d14SAndroid Build Coastguard Worker 
218*cfb92d14SAndroid Build Coastguard Worker         interval = timer.GetInterval();
219*cfb92d14SAndroid Build Coastguard Worker         t        = timer.GetTimeInInterval();
220*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit((interval / 2 <= t) && (t <= interval));
221*cfb92d14SAndroid Build Coastguard Worker     }
222*cfb92d14SAndroid Build Coastguard Worker 
223*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(t);
224*cfb92d14SAndroid Build Coastguard Worker 
225*cfb92d14SAndroid Build Coastguard Worker     timer.IndicateInconsistent();
226*cfb92d14SAndroid Build Coastguard Worker 
227*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
228*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
229*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == kMinInterval);
230*cfb92d14SAndroid Build Coastguard Worker 
231*cfb92d14SAndroid Build Coastguard Worker     printf(" --> PASSED\n");
232*cfb92d14SAndroid Build Coastguard Worker 
233*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(instance);
234*cfb92d14SAndroid Build Coastguard Worker }
235*cfb92d14SAndroid Build Coastguard Worker 
TestTrickleTimerMinMaxIntervalChange(void)236*cfb92d14SAndroid Build Coastguard Worker void TestTrickleTimerMinMaxIntervalChange(void)
237*cfb92d14SAndroid Build Coastguard Worker {
238*cfb92d14SAndroid Build Coastguard Worker     Instance          *instance = testInitInstance();
239*cfb92d14SAndroid Build Coastguard Worker     TrickleTimerTester timer(*instance);
240*cfb92d14SAndroid Build Coastguard Worker     TimeMilli          fireTime;
241*cfb92d14SAndroid Build Coastguard Worker     uint32_t           interval;
242*cfb92d14SAndroid Build Coastguard Worker     uint32_t           t;
243*cfb92d14SAndroid Build Coastguard Worker 
244*cfb92d14SAndroid Build Coastguard Worker     sInstance = instance;
245*cfb92d14SAndroid Build Coastguard Worker     TrickleTimerTester::RemoveAll(*instance);
246*cfb92d14SAndroid Build Coastguard Worker 
247*cfb92d14SAndroid Build Coastguard Worker     printf("TestTrickleTimerMinMaxIntervalChange()");
248*cfb92d14SAndroid Build Coastguard Worker 
249*cfb92d14SAndroid Build Coastguard Worker     sNow = 1000;
250*cfb92d14SAndroid Build Coastguard Worker     timer.Start(TrickleTimer::kModeTrickle, 2000, 4000);
251*cfb92d14SAndroid Build Coastguard Worker 
252*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
253*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMin() == 2000);
254*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == 4000);
255*cfb92d14SAndroid Build Coastguard Worker 
256*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - -
257*cfb92d14SAndroid Build Coastguard Worker     // Validate that `SetIntervalMin()` to a larger value than
258*cfb92d14SAndroid Build Coastguard Worker     // previously set does not impact the current interval.
259*cfb92d14SAndroid Build Coastguard Worker 
260*cfb92d14SAndroid Build Coastguard Worker     timer.IndicateInconsistent();
261*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
262*cfb92d14SAndroid Build Coastguard Worker     t        = timer.GetTimeInInterval();
263*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
264*cfb92d14SAndroid Build Coastguard Worker 
265*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == 2000);
266*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t < interval));
267*cfb92d14SAndroid Build Coastguard Worker 
268*cfb92d14SAndroid Build Coastguard Worker     // Change `IntervalMin` before time `t`.
269*cfb92d14SAndroid Build Coastguard Worker 
270*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(3000);
271*cfb92d14SAndroid Build Coastguard Worker 
272*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
273*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMin() == 3000);
274*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == 4000);
275*cfb92d14SAndroid Build Coastguard Worker 
276*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == timer.GetInterval());
277*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(t == timer.GetTimeInInterval());
278*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime == timer.GetFireTime());
279*cfb92d14SAndroid Build Coastguard Worker 
280*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(t);
281*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidFire();
282*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
283*cfb92d14SAndroid Build Coastguard Worker 
284*cfb92d14SAndroid Build Coastguard Worker     // Change `IntervalMin` after time `t`.
285*cfb92d14SAndroid Build Coastguard Worker 
286*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(3500);
287*cfb92d14SAndroid Build Coastguard Worker 
288*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
289*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMin() == 3500);
290*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == 4000);
291*cfb92d14SAndroid Build Coastguard Worker 
292*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == timer.GetInterval());
293*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(t == timer.GetTimeInInterval());
294*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime == timer.GetFireTime());
295*cfb92d14SAndroid Build Coastguard Worker 
296*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - -
297*cfb92d14SAndroid Build Coastguard Worker     // Validate that `SetIntervalMin()` to a smaller value
298*cfb92d14SAndroid Build Coastguard Worker     // also does not impact the current interval.
299*cfb92d14SAndroid Build Coastguard Worker 
300*cfb92d14SAndroid Build Coastguard Worker     timer.IndicateInconsistent();
301*cfb92d14SAndroid Build Coastguard Worker 
302*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
303*cfb92d14SAndroid Build Coastguard Worker     t        = timer.GetTimeInInterval();
304*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
305*cfb92d14SAndroid Build Coastguard Worker 
306*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == 3500);
307*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t < interval));
308*cfb92d14SAndroid Build Coastguard Worker 
309*cfb92d14SAndroid Build Coastguard Worker     // Change `IntervalMin` before time `t`.
310*cfb92d14SAndroid Build Coastguard Worker 
311*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(3000);
312*cfb92d14SAndroid Build Coastguard Worker 
313*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
314*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMin() == 3000);
315*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == 4000);
316*cfb92d14SAndroid Build Coastguard Worker 
317*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == timer.GetInterval());
318*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(t == timer.GetTimeInInterval());
319*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime == timer.GetFireTime());
320*cfb92d14SAndroid Build Coastguard Worker 
321*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(t);
322*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidFire();
323*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
324*cfb92d14SAndroid Build Coastguard Worker 
325*cfb92d14SAndroid Build Coastguard Worker     // Change `IntervalMin` after time `t`.
326*cfb92d14SAndroid Build Coastguard Worker 
327*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(2000);
328*cfb92d14SAndroid Build Coastguard Worker 
329*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
330*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMin() == 2000);
331*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == 4000);
332*cfb92d14SAndroid Build Coastguard Worker 
333*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == timer.GetInterval());
334*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(t == timer.GetTimeInInterval());
335*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime == timer.GetFireTime());
336*cfb92d14SAndroid Build Coastguard Worker 
337*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - -
338*cfb92d14SAndroid Build Coastguard Worker     // Validate that changing `IntervalMax` to a larger value
339*cfb92d14SAndroid Build Coastguard Worker     // than the current interval being used by timer, does not
340*cfb92d14SAndroid Build Coastguard Worker     // impact the current internal.
341*cfb92d14SAndroid Build Coastguard Worker 
342*cfb92d14SAndroid Build Coastguard Worker     timer.IndicateInconsistent();
343*cfb92d14SAndroid Build Coastguard Worker 
344*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
345*cfb92d14SAndroid Build Coastguard Worker     t        = timer.GetTimeInInterval();
346*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
347*cfb92d14SAndroid Build Coastguard Worker 
348*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == 2000);
349*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t < interval));
350*cfb92d14SAndroid Build Coastguard Worker 
351*cfb92d14SAndroid Build Coastguard Worker     // Change `IntervalMax` before time `t`.
352*cfb92d14SAndroid Build Coastguard Worker 
353*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMax(2500);
354*cfb92d14SAndroid Build Coastguard Worker 
355*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetIntervalMax() == 2500);
356*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.IsRunning());
357*cfb92d14SAndroid Build Coastguard Worker 
358*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == timer.GetInterval());
359*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(t == timer.GetTimeInInterval());
360*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime == timer.GetFireTime());
361*cfb92d14SAndroid Build Coastguard Worker 
362*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(t);
363*cfb92d14SAndroid Build Coastguard Worker 
364*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidFire();
365*cfb92d14SAndroid Build Coastguard Worker 
366*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
367*cfb92d14SAndroid Build Coastguard Worker 
368*cfb92d14SAndroid Build Coastguard Worker     // Change `IntervalMax` after time `t`.
369*cfb92d14SAndroid Build Coastguard Worker 
370*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMax(3000);
371*cfb92d14SAndroid Build Coastguard Worker 
372*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == timer.GetInterval());
373*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(t == timer.GetTimeInInterval());
374*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime == timer.GetFireTime());
375*cfb92d14SAndroid Build Coastguard Worker 
376*cfb92d14SAndroid Build Coastguard Worker     timer.Stop();
377*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!timer.IsRunning());
378*cfb92d14SAndroid Build Coastguard Worker 
379*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - -
380*cfb92d14SAndroid Build Coastguard Worker     // Check behavior when the new `IntervalMax` is smaller
381*cfb92d14SAndroid Build Coastguard Worker     // than the current interval being used by timer.
382*cfb92d14SAndroid Build Coastguard Worker 
383*cfb92d14SAndroid Build Coastguard Worker     // New `Imax` is smaller than `t` and before now.
384*cfb92d14SAndroid Build Coastguard Worker     //
385*cfb92d14SAndroid Build Coastguard Worker     //   |<---- interval --^-------------------------------->|
386*cfb92d14SAndroid Build Coastguard Worker     //   |<---- t ---------^------------------>|             |
387*cfb92d14SAndroid Build Coastguard Worker     //   |<---- new Imax --^--->|              |             |
388*cfb92d14SAndroid Build Coastguard Worker     //   |                now   |              |             |
389*cfb92d14SAndroid Build Coastguard Worker 
390*cfb92d14SAndroid Build Coastguard Worker     timer.Start(TrickleTimer::kModeTrickle, 2000, 2000);
391*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
392*cfb92d14SAndroid Build Coastguard Worker     t        = timer.GetTimeInInterval();
393*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
394*cfb92d14SAndroid Build Coastguard Worker 
395*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == 2000);
396*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t < interval));
397*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(500);
398*cfb92d14SAndroid Build Coastguard Worker 
399*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
400*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidNotFire();
401*cfb92d14SAndroid Build Coastguard Worker 
402*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMax(500);
403*cfb92d14SAndroid Build Coastguard Worker 
404*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetInterval() == 500);
405*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetTimeInInterval() == 500);
406*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetFireTime() != fireTime);
407*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidNotFire();
408*cfb92d14SAndroid Build Coastguard Worker 
409*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(400);
410*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidFire();
411*cfb92d14SAndroid Build Coastguard Worker 
412*cfb92d14SAndroid Build Coastguard Worker     // New `Imax` is smaller than `t` and after now.
413*cfb92d14SAndroid Build Coastguard Worker     //
414*cfb92d14SAndroid Build Coastguard Worker     //   |<---- interval --------------^-------------------->|
415*cfb92d14SAndroid Build Coastguard Worker     //   |<---- t ---------------------^------>|             |
416*cfb92d14SAndroid Build Coastguard Worker     //   |<---- new Imax ------>|      ^       |             |
417*cfb92d14SAndroid Build Coastguard Worker     //   |                      |     now      |             |
418*cfb92d14SAndroid Build Coastguard Worker 
419*cfb92d14SAndroid Build Coastguard Worker     timer.Start(TrickleTimer::kModeTrickle, 2000, 2000);
420*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
421*cfb92d14SAndroid Build Coastguard Worker     t        = timer.GetTimeInInterval();
422*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
423*cfb92d14SAndroid Build Coastguard Worker 
424*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == 2000);
425*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t < interval));
426*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(500);
427*cfb92d14SAndroid Build Coastguard Worker 
428*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(800);
429*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidNotFire();
430*cfb92d14SAndroid Build Coastguard Worker 
431*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMax(500);
432*cfb92d14SAndroid Build Coastguard Worker 
433*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetInterval() == 500);
434*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetTimeInInterval() == 500);
435*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetFireTime() != fireTime);
436*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidNotFire();
437*cfb92d14SAndroid Build Coastguard Worker 
438*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(0);
439*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidFire();
440*cfb92d14SAndroid Build Coastguard Worker 
441*cfb92d14SAndroid Build Coastguard Worker     // New `Imax` is larger than `t` and before now.
442*cfb92d14SAndroid Build Coastguard Worker     //
443*cfb92d14SAndroid Build Coastguard Worker     //   |<---- interval --------------------------------^-->|
444*cfb92d14SAndroid Build Coastguard Worker     //   |<---- t ---------------------------->|         ^   |
445*cfb92d14SAndroid Build Coastguard Worker     //   |<---- new Imax --------------------------->|   ^   |
446*cfb92d14SAndroid Build Coastguard Worker     //   |                                     |     |  now  |
447*cfb92d14SAndroid Build Coastguard Worker 
448*cfb92d14SAndroid Build Coastguard Worker     timer.Start(TrickleTimer::kModeTrickle, 2000, 2000);
449*cfb92d14SAndroid Build Coastguard Worker 
450*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
451*cfb92d14SAndroid Build Coastguard Worker     t        = timer.GetTimeInInterval();
452*cfb92d14SAndroid Build Coastguard Worker 
453*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == 2000);
454*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t < interval));
455*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(500);
456*cfb92d14SAndroid Build Coastguard Worker 
457*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1999);
458*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidFire();
459*cfb92d14SAndroid Build Coastguard Worker 
460*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMax(t + 1);
461*cfb92d14SAndroid Build Coastguard Worker 
462*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetInterval() == t + 1);
463*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
464*cfb92d14SAndroid Build Coastguard Worker 
465*cfb92d14SAndroid Build Coastguard Worker     // Check that new interval is started immediately.
466*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(0);
467*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidNotFire();
468*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime != timer.GetFireTime());
469*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetInterval() == timer.GetIntervalMax());
470*cfb92d14SAndroid Build Coastguard Worker 
471*cfb92d14SAndroid Build Coastguard Worker     // New `Imax` is larger than `t` and after now.
472*cfb92d14SAndroid Build Coastguard Worker     //
473*cfb92d14SAndroid Build Coastguard Worker     //   |<---- interval -------------------------^--------->|
474*cfb92d14SAndroid Build Coastguard Worker     //   |<---- t ---------------------------->|  ^          |
475*cfb92d14SAndroid Build Coastguard Worker     //   |<---- new Imax -------------------------^->|       |
476*cfb92d14SAndroid Build Coastguard Worker     //   |                                     | now |       |
477*cfb92d14SAndroid Build Coastguard Worker 
478*cfb92d14SAndroid Build Coastguard Worker     timer.Start(TrickleTimer::kModeTrickle, 2000, 2000);
479*cfb92d14SAndroid Build Coastguard Worker 
480*cfb92d14SAndroid Build Coastguard Worker     interval = timer.GetInterval();
481*cfb92d14SAndroid Build Coastguard Worker     t        = timer.GetTimeInInterval();
482*cfb92d14SAndroid Build Coastguard Worker 
483*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(interval == 2000);
484*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit((interval / 2 <= t) && (t < interval));
485*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMin(500);
486*cfb92d14SAndroid Build Coastguard Worker 
487*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(t);
488*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidFire();
489*cfb92d14SAndroid Build Coastguard Worker 
490*cfb92d14SAndroid Build Coastguard Worker     timer.SetIntervalMax(t + 1);
491*cfb92d14SAndroid Build Coastguard Worker 
492*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetInterval() == t + 1);
493*cfb92d14SAndroid Build Coastguard Worker     fireTime = timer.GetFireTime();
494*cfb92d14SAndroid Build Coastguard Worker 
495*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
496*cfb92d14SAndroid Build Coastguard Worker     timer.VerifyTimerDidNotFire();
497*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(fireTime != timer.GetFireTime());
498*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(timer.GetInterval() == timer.GetIntervalMax());
499*cfb92d14SAndroid Build Coastguard Worker 
500*cfb92d14SAndroid Build Coastguard Worker     printf(" --> PASSED\n");
501*cfb92d14SAndroid Build Coastguard Worker 
502*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(instance);
503*cfb92d14SAndroid Build Coastguard Worker }
504*cfb92d14SAndroid Build Coastguard Worker 
505*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
506*cfb92d14SAndroid Build Coastguard Worker 
main(void)507*cfb92d14SAndroid Build Coastguard Worker int main(void)
508*cfb92d14SAndroid Build Coastguard Worker {
509*cfb92d14SAndroid Build Coastguard Worker     ot::TestTrickleTimerPlainMode();
510*cfb92d14SAndroid Build Coastguard Worker     ot::TestTrickleTimerTrickleMode(/* aRedundancyConstant */ 5, /* aConsistentCalls */ 3);
511*cfb92d14SAndroid Build Coastguard Worker     ot::TestTrickleTimerTrickleMode(/* aRedundancyConstant */ 3, /* aConsistentCalls */ 3);
512*cfb92d14SAndroid Build Coastguard Worker     ot::TestTrickleTimerMinMaxIntervalChange();
513*cfb92d14SAndroid Build Coastguard Worker 
514*cfb92d14SAndroid Build Coastguard Worker     printf("All tests passed\n");
515*cfb92d14SAndroid Build Coastguard Worker     return 0;
516*cfb92d14SAndroid Build Coastguard Worker }
517