Skip to content

Commit

Permalink
misc refactoring, renaming, formatting.
Browse files Browse the repository at this point in the history
  • Loading branch information
mattheweshleman committed Oct 16, 2024
1 parent 9bc21b6 commit 05dfb63
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 56 deletions.
99 changes: 53 additions & 46 deletions include/FakeTimers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,12 @@
namespace cms {
namespace test {

using TimerHandle = uint32_t;
using UserContext = void*;
using TimerCallback = std::function<void(TimerHandle, UserContext)>;
using TimerDuration = std::chrono::nanoseconds;

enum class TimerBehavior
{
SingleShot,
AutoReload
};

/**
* class FakeTimers implements a software timer functionality loosely equivalent
* The FakeTimers class implements a software timer functionality loosely equivalent
* to the Timer API provided by FreeRTOS. The intention, and the reason
* it is called "Fake", is for this to be used in a unit testing environment
* to replace any RTOS provided timer functionality, giving unit tests the
* ability to control "time" during unit testing.
* to replace RTOS timer functionality, giving unit tests the ability to
* control "time" during unit testing.
*
* @note: Underlying timebase uses std::chrono::nanoseconds.
* Sorry, unit testing is limited to 292 years of so of time.
Expand All @@ -57,7 +46,18 @@ enum class TimerBehavior
class FakeTimers
{
public:
explicit FakeTimers(TimerDuration sysTickPeriod = std::chrono::milliseconds(10)) :
using Handle = uint32_t;
using Context = void*;
using Callback = std::function<void(Handle, Context)>;
using Duration = std::chrono::nanoseconds;

enum class Behavior
{
SingleShot,
AutoReload
};

explicit FakeTimers(Duration sysTickPeriod = std::chrono::milliseconds(10)) :
mTimers(),
mSysTickPeriod(sysTickPeriod),
mCurrent(0)
Expand All @@ -82,19 +82,20 @@ class FakeTimers
* period.
* @note: Reference FreeRTOS xTimerCreate
*/
TimerHandle TimerCreate(
Handle TimerCreate(
const char * timerName,
const TimerDuration& period,
const TimerBehavior behavior,
UserContext context,
const TimerCallback& callback)
const Duration& period,
const Behavior behavior,
Context context,
const Callback& callback)
{
using namespace std::chrono_literals;

if (period <= 0ms)
{
return false;
}

if ((period.count() % mSysTickPeriod.count()) != 0)
{
return 0;
Expand All @@ -118,12 +119,13 @@ class FakeTimers
* @param handle
* @return true, deleted as expected. false, some error.
*/
bool TimerDelete(TimerHandle handle)
bool TimerDelete(Handle handle)
{
if (handle > mTimers.size())
{
return false;
}

if (handle == 0)
{
return false;
Expand All @@ -139,12 +141,13 @@ class FakeTimers
* @param handle
* @return true: started ok. false: some error.
*/
bool TimerStart(TimerHandle handle)
bool TimerStart(Handle handle)
{
if (handle > mTimers.size())
{
return false;
}

if (handle == 0)
{
return false;
Expand All @@ -164,14 +167,15 @@ class FakeTimers
* @return true: timer was found and stopped.
* false: some error, such as non-existent timer.
*/
bool TimerStop(TimerHandle handle)
bool TimerStop(Handle handle)
{
using namespace std::chrono_literals;

if (handle > mTimers.size())
{
return false;
}

if (handle == 0)
{
return false;
Expand All @@ -192,7 +196,7 @@ class FakeTimers
* @return
* @note: Reference FreeRTOS xTimerReset
*/
bool TimerReset(TimerHandle handle)
bool TimerReset(Handle handle)
{
return TimerStart(handle);
}
Expand All @@ -204,18 +208,20 @@ class FakeTimers
* @return: true: changed ok. false: some error.
* @note: Reference FreeRTOS xTimerChangePeriod
*/
bool TimerChangePeriod(TimerHandle handle, TimerDuration newPeriod)
bool TimerChangePeriod(Handle handle, Duration newPeriod)
{
using namespace std::chrono_literals;

if (handle > mTimers.size())
{
return false;
}

if (handle == 0)
{
return false;
}

if (newPeriod <= 0ms)
{
return false;
Expand All @@ -238,14 +244,15 @@ class FakeTimers
* @return: true: changed ok. false: some error.
* @note: Reference FreeRTOS vTimerSetReloadMode
*/
bool TimerSetBehavior(TimerHandle handle, TimerBehavior behavior)
bool TimerSetBehavior(Handle handle, Behavior behavior)
{
using namespace std::chrono_literals;

if (handle > mTimers.size())
{
return false;
}

if (handle == 0)
{
return false;
Expand All @@ -264,7 +271,7 @@ class FakeTimers
* @return: the user context provided when the timer was created
* @note: Reference FreeRTOS pvTimerGetTimerID
*/
UserContext TimerGetContext(TimerHandle handle) const
Context TimerGetContext(Handle handle) const
{
const Timer& timer = mTimers.at(handle - 1);
assert(timer.handle == handle);
Expand All @@ -279,7 +286,7 @@ class FakeTimers
* @return the timer name provided when created.
* @note: Reference FreeRTOS pcTimerGetName
*/
const char * TimerGetName(TimerHandle handle) const
const char * TimerGetName(Handle handle) const
{
const Timer& timer = mTimers.at(handle - 1);
assert(timer.handle == handle);
Expand All @@ -294,7 +301,7 @@ class FakeTimers
* @return
* @note: Reference FreeRTOS xTimerGetPeriod
*/
TimerDuration TimerGetPeriod(TimerHandle handle) const
Duration TimerGetPeriod(Handle handle) const
{
const Timer& timer = mTimers.at(handle - 1);
assert(timer.handle == handle);
Expand All @@ -309,7 +316,7 @@ class FakeTimers
* @return
* @note: Reference FreeRTOS xTimerGetReloadMode
*/
TimerBehavior TimerGetBehavior(TimerHandle handle) const
Behavior TimerGetBehavior(Handle handle) const
{
const Timer& timer = mTimers.at(handle - 1);
assert(timer.handle == handle);
Expand All @@ -324,7 +331,7 @@ class FakeTimers
* @param handle
* @return the tick. Will be negative if the timer is not active.
*/
TimerDuration TimerGetExpiryTime(TimerHandle handle) const
Duration TimerGetExpiryTime(Handle handle) const
{
const Timer& timer = mTimers.at(handle - 1);
assert(timer.handle == handle);
Expand All @@ -336,7 +343,7 @@ class FakeTimers
}
else
{
return TimerDuration(-1);
return Duration(-1);
}
}

Expand All @@ -350,7 +357,7 @@ class FakeTimers
* and not yet been restarted.
* @note: Reference FreeRTOS xTimerIsTimerActive
*/
bool TimerIsActive(TimerHandle handle) const
bool TimerIsActive(Handle handle) const
{
using namespace std::chrono_literals;

Expand All @@ -368,13 +375,13 @@ class FakeTimers
* to fire based on sys tick period.
* @param time
*/
void MoveTimeForward(const TimerDuration& time)
void MoveTimeForward(const Duration& time)
{
using namespace std::chrono_literals;

TimerDuration remaining = time;
Duration remaining = time;

while (remaining > TimerDuration(0))
while (remaining > Duration(0))
{
auto this_delta = std::min(remaining, mSysTickPeriod);
mCurrent += this_delta;
Expand All @@ -399,7 +406,7 @@ class FakeTimers
/**
* Get the internal current time base
*/
TimerDuration GetCurrentInternalTime() const
Duration GetCurrentInternalTime() const
{
return mCurrent;
}
Expand All @@ -408,14 +415,14 @@ class FakeTimers
struct Timer
{
const char * name = nullptr;
TimerDuration period = {};
TimerBehavior behavior = TimerBehavior::SingleShot;
UserContext context = nullptr;
TimerCallback callback = nullptr;
Duration period = {};
Behavior behavior = Behavior::SingleShot;
Context context = nullptr;
Callback callback = nullptr;

TimerHandle handle = 0;
Handle handle = 0;
bool allocated = false;
TimerDuration next = {};
Duration next = {};
};

uint32_t FindAvailableTimer()
Expand Down Expand Up @@ -460,7 +467,7 @@ class FakeTimers
timer.callback(timer.handle, timer.context);
}

if (timer.behavior == TimerBehavior::AutoReload)
if (timer.behavior == Behavior::AutoReload)
{
timer.next = mCurrent + timer.period;
}
Expand All @@ -472,8 +479,8 @@ class FakeTimers
}

std::vector<Timer> mTimers;
const TimerDuration mSysTickPeriod;
TimerDuration mCurrent;
const Duration mSysTickPeriod;
Duration mCurrent;
};

} //namespace test
Expand Down
20 changes: 10 additions & 10 deletions tests/FakeTimersTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,23 @@ TEST_GROUP(FakeTimersTests) {
mock().clear();
}

static void testCallback(TimerHandle handle, UserContext context)
static void testCallback(FakeTimers::Handle handle, FakeTimers::Context context)
{
(void)context;
mock().actualCall("testCallback")
.withParameter("handle", handle);
}

TimerHandle Create(std::chrono::milliseconds period = DEFAULT_TIMER_PERIOD,
TimerBehavior behavior = TimerBehavior::SingleShot) const
FakeTimers::Handle Create(std::chrono::milliseconds period = DEFAULT_TIMER_PERIOD,
FakeTimers::Behavior behavior = FakeTimers::Behavior::SingleShot) const
{
auto handle = mUnderTest->TimerCreate(
"TEST", period, behavior,
&TestContextObject, testCallback);
return handle;
}

TimerHandle CreateAndStartSingleShot(std::chrono::milliseconds period = DEFAULT_TIMER_PERIOD) const
FakeTimers::Handle CreateAndStartSingleShot(std::chrono::milliseconds period = DEFAULT_TIMER_PERIOD) const
{
auto handle = Create(period);
CHECK_TRUE(handle != 0);
Expand All @@ -75,9 +75,9 @@ TEST_GROUP(FakeTimersTests) {
return handle;
}

TimerHandle CreateAndStartAutoReload(std::chrono::milliseconds period = DEFAULT_TIMER_PERIOD) const
FakeTimers::Handle CreateAndStartAutoReload(std::chrono::milliseconds period = DEFAULT_TIMER_PERIOD) const
{
auto handle = Create(period, cms::test::TimerBehavior::AutoReload);
auto handle = Create(period, FakeTimers::Behavior::AutoReload);
CHECK_TRUE(handle != 0);

bool ok = mUnderTest->TimerStart(handle);
Expand Down Expand Up @@ -263,18 +263,18 @@ TEST(FakeTimersTests, access_timer_behavior_via_handle)
{
auto handle = Create();
auto behavior = mUnderTest->TimerGetBehavior(handle);
CHECK_TRUE(TimerBehavior::SingleShot == behavior);
CHECK_TRUE(FakeTimers::Behavior::SingleShot == behavior);
}

TEST(FakeTimersTests, set_timer_behavior_via_handle)
{
auto handle = Create();
auto behavior = mUnderTest->TimerGetBehavior(handle);
CHECK_TRUE(TimerBehavior::SingleShot == behavior);
CHECK_TRUE(FakeTimers::Behavior::SingleShot == behavior);

mUnderTest->TimerSetBehavior(handle, TimerBehavior::AutoReload);
mUnderTest->TimerSetBehavior(handle, FakeTimers::Behavior::AutoReload);
behavior = mUnderTest->TimerGetBehavior(handle);
CHECK_TRUE(TimerBehavior::AutoReload == behavior);
CHECK_TRUE(FakeTimers::Behavior::AutoReload == behavior);
}

TEST(FakeTimersTests, is_timer_active_method_works_as_expected)
Expand Down

0 comments on commit 05dfb63

Please sign in to comment.