1 #pragma once
2 #include <memory>
3 
4 struct alarm_t;
5 
6 class AlarmMock {
7  public:
8   MOCK_METHOD1(AlarmNew, alarm_t*(const char*));
9   MOCK_METHOD1(AlarmFree, void(alarm_t*));
10   MOCK_METHOD1(AlarmCancel, void(alarm_t*));
11   MOCK_METHOD4(AlarmSet, void(alarm_t* alarm, uint64_t interval_ms,
12                               alarm_callback_t cb, void* data));
13   MOCK_METHOD4(AlarmSetOnMloop, void(alarm_t* alarm, uint64_t interval_ms,
14                                      alarm_callback_t cb, void* data));
15   MOCK_METHOD1(AlarmIsScheduled, bool(const alarm_t*));
16 
AlarmNewImpl(const char * name)17   alarm_t* AlarmNewImpl(const char* name) {
18     AlarmNew(name);
19     // We must return something from alarm_new in tests, if we just return null,
20     // unique_ptr will misbehave. Just reserve few bits they will be freed in
21     // AlarmFreeImpl
22     return (alarm_t*)new uint8_t[30];
23   }
24 
AlarmFreeImpl(alarm_t * alarm)25   void AlarmFreeImpl(alarm_t* alarm) {
26     uint8_t* ptr = (uint8_t*)alarm;
27     delete[] ptr;
28     return AlarmFree(alarm);
29   }
30 
Get()31   static inline AlarmMock* Get() {
32     if (!localAlarmMock) {
33       localAlarmMock = std::make_unique<AlarmMock>();
34     }
35     return localAlarmMock.get();
36   }
37 
Reset()38   static inline void Reset() { localAlarmMock = std::make_unique<AlarmMock>(); }
39 
40  private:
41   static std::unique_ptr<AlarmMock> localAlarmMock;
42 };
43 
44 std::unique_ptr<AlarmMock> AlarmMock::localAlarmMock;
45 
alarm_new(const char * name)46 alarm_t* alarm_new(const char* name) {
47   return AlarmMock::Get()->AlarmNewImpl(name);
48 }
49 
alarm_free(alarm_t * alarm)50 void alarm_free(alarm_t* alarm) { AlarmMock::Get()->AlarmFreeImpl(alarm); }
51 
alarm_set_on_mloop(alarm_t * alarm,uint64_t interval_ms,alarm_callback_t cb,void * data)52 void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms,
53                         alarm_callback_t cb, void* data) {
54   AlarmMock::Get()->AlarmSetOnMloop(alarm, interval_ms, cb, data);
55 }
56 
alarm_set(alarm_t * alarm,uint64_t interval_ms,alarm_callback_t cb,void * data)57 void alarm_set(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb,
58                void* data) {
59   AlarmMock::Get()->AlarmSet(alarm, interval_ms, cb, data);
60 }
61 
alarm_is_scheduled(const alarm_t * alarm)62 bool alarm_is_scheduled(const alarm_t* alarm) {
63   return AlarmMock::Get()->AlarmIsScheduled(alarm);
64 }
65 
alarm_cancel(alarm_t * alarm)66 void alarm_cancel(alarm_t* alarm) { AlarmMock::Get()->AlarmCancel(alarm); }
67