Skip to content

Commit

Permalink
Make System::Layer mockable
Browse files Browse the repository at this point in the history
#### Problem

System::Layer is now an abstract base class, but in normal builds is
still accessed through a static global variable.

#### Change overview

Replace the direct global access `DeviceLayer::SystemLayer` with
a function indirecting through a pointer. In the normal case, the
pointer is initialized by `InitChipStack()` with the global, but
it can be set with a mock implementation before that.

#### Testing

Added a unit test case to TestPlatformMgr.
  • Loading branch information
kpschoedel committed Sep 9, 2021
1 parent 7251dd6 commit a184f57
Show file tree
Hide file tree
Showing 50 changed files with 249 additions and 177 deletions.
6 changes: 3 additions & 3 deletions examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ void IdentifyTimerHandler(Layer * systemLayer, void * appState)

if (identifyTimerCount)
{
SystemLayer.StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, appState);
systemLayer->StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, appState);
// Decrement the timer count.
identifyTimerCount--;
}
Expand All @@ -235,8 +235,8 @@ void DeviceCallbacks::OnIdentifyPostAttributeChangeCallback(EndpointId endpointI
// Also, we want timerCount to be odd number, so the ligth state ends in the same state it starts.
identifyTimerCount = (*value) * 4;

SystemLayer.CancelTimer(IdentifyTimerHandler, this);
SystemLayer.StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, this);
DeviceLayer::SystemLayer().CancelTimer(IdentifyTimerHandler, this);
DeviceLayer::SystemLayer().StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, this);

exit:
return;
Expand Down
2 changes: 1 addition & 1 deletion examples/chip-tool/commands/common/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ static void OnResponseTimeout(chip::System::Layer *, void *)

CHIP_ERROR Command::ScheduleWaitForResponse(uint16_t seconds)
{
CHIP_ERROR err = chip::DeviceLayer::SystemLayer.StartTimer(seconds * 1000, OnResponseTimeout, this);
CHIP_ERROR err = chip::DeviceLayer::SystemLayer().StartTimer(seconds * 1000, OnResponseTimeout, this);
if (err != CHIP_NO_ERROR)
{
ChipLogError(chipTool, "Failed to allocate timer %" CHIP_ERROR_FORMAT, err.Format());
Expand Down
2 changes: 1 addition & 1 deletion examples/chip-tool/commands/tests/TestCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,5 @@ void TestCommand::OnWaitForMsFn(chip::System::Layer * systemLayer, void * contex

CHIP_ERROR TestCommand::WaitForMs(uint32_t ms)
{
return chip::DeviceLayer::SystemLayer.StartTimer(ms, OnWaitForMsFn, this);
return chip::DeviceLayer::SystemLayer().StartTimer(ms, OnWaitForMsFn, this);
}
4 changes: 2 additions & 2 deletions examples/lighting-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,15 +374,15 @@ void AppTask::FunctionHandler(AppEvent * aEvent)

void AppTask::CancelTimer()
{
SystemLayer.CancelTimer(TimerEventHandler, this);
SystemLayer().CancelTimer(TimerEventHandler, this);
mFunctionTimerActive = false;
}

void AppTask::StartTimer(uint32_t aTimeoutInMs)
{
CHIP_ERROR err;

err = SystemLayer.StartTimer(aTimeoutInMs, TimerEventHandler, this);
err = SystemLayer().StartTimer(aTimeoutInMs, TimerEventHandler, this);
SuccessOrExit(err);

mFunctionTimerActive = true;
Expand Down
6 changes: 3 additions & 3 deletions examples/lock-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,16 +389,16 @@ void AppTask::FunctionHandler(AppEvent * aEvent)

void AppTask::CancelTimer()
{
SystemLayer.CancelTimer(TimerEventHandler, this);
chip::DeviceLayer::SystemLayer().CancelTimer(TimerEventHandler, this);
mFunctionTimerActive = false;
}

void AppTask::StartTimer(uint32_t aTimeoutInMs)
{
CHIP_ERROR err;

SystemLayer.CancelTimer(TimerEventHandler, this);
err = SystemLayer.StartTimer(aTimeoutInMs, TimerEventHandler, this);
chip::DeviceLayer::SystemLayer().CancelTimer(TimerEventHandler, this);
err = chip::DeviceLayer::SystemLayer().StartTimer(aTimeoutInMs, TimerEventHandler, this);
SuccessOrExit(err);

mFunctionTimerActive = true;
Expand Down
4 changes: 2 additions & 2 deletions examples/minimal-mdns/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,9 @@ int main(int argc, char ** args)

BroadcastPacket(&mdnsServer);

CHIP_ERROR err = DeviceLayer::SystemLayer.StartTimer(
CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(
gOptions.runtimeMs,
[](System::Layer *, void *, CHIP_ERROR err) {
[](System::Layer *, void *) {
DeviceLayer::PlatformMgr().StopEventLoopTask();
DeviceLayer::PlatformMgr().Shutdown();
},
Expand Down
2 changes: 1 addition & 1 deletion examples/ota-provider-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ int main(int argc, char * argv[])

BitFlags<TransferControlFlags> bdxFlags;
bdxFlags.Set(TransferControlFlags::kReceiverDrive);
err = bdxServer.PrepareForTransfer(&chip::DeviceLayer::SystemLayer, chip::bdx::TransferRole::kSender, bdxFlags,
err = bdxServer.PrepareForTransfer(&chip::DeviceLayer::SystemLayer(), chip::bdx::TransferRole::kSender, bdxFlags,
kMaxBdxBlockSize, kBdxTimeoutMs, kBdxPollFreqMs);
if (err != CHIP_NO_ERROR)
{
Expand Down
10 changes: 5 additions & 5 deletions examples/shell/shell_common/cmd_ping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Transport::PeerAddress GetEchoPeerAddress()

void Shutdown()
{
chip::DeviceLayer::SystemLayer.CancelTimer(EchoTimerHandler, NULL);
chip::DeviceLayer::SystemLayer().CancelTimer(EchoTimerHandler, NULL);
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
if (gPingArguments.IsUsingTCP())
{
Expand Down Expand Up @@ -212,7 +212,7 @@ CHIP_ERROR SendEchoRequest(streamer_t * stream)
}

gPingArguments.SetLastEchoTime(System::Clock::GetMonotonicMilliseconds());
SuccessOrExit(chip::DeviceLayer::SystemLayer.StartTimer(gPingArguments.GetEchoInterval(), EchoTimerHandler, NULL));
SuccessOrExit(chip::DeviceLayer::SystemLayer().StartTimer(gPingArguments.GetEchoInterval(), EchoTimerHandler, NULL));

streamer_printf(stream, "\nSend echo request message with payload size: %d bytes to Node: %" PRIu64 "\n", payloadSize,
kTestDeviceNodeId);
Expand All @@ -226,7 +226,7 @@ CHIP_ERROR SendEchoRequest(streamer_t * stream)
}
else
{
chip::DeviceLayer::SystemLayer.CancelTimer(EchoTimerHandler, NULL);
chip::DeviceLayer::SystemLayer().CancelTimer(EchoTimerHandler, NULL);
}

exit:
Expand Down Expand Up @@ -306,7 +306,7 @@ void StartPinging(streamer_t * stream, char * destination)
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
if (gPingArguments.IsUsingTCP())
{
err = gSessionManager.Init(&DeviceLayer::SystemLayer, &gTCPManager, &gFabrics, &gMessageCounterManager);
err = gSessionManager.Init(&DeviceLayer::SystemLayer(), &gTCPManager, &gFabrics, &gMessageCounterManager);
SuccessOrExit(err);

err = gExchangeManager.Init(&gSessionManager);
Expand All @@ -315,7 +315,7 @@ void StartPinging(streamer_t * stream, char * destination)
else
#endif
{
err = gSessionManager.Init(&DeviceLayer::SystemLayer, &gUDPManager, &gFabrics, &gMessageCounterManager);
err = gSessionManager.Init(&DeviceLayer::SystemLayer(), &gUDPManager, &gFabrics, &gMessageCounterManager);
SuccessOrExit(err);

err = gExchangeManager.Init(&gSessionManager);
Expand Down
4 changes: 2 additions & 2 deletions examples/shell/shell_common/cmd_send.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,15 @@ void ProcessCommand(streamer_t * stream, char * destination)
{
peerAddress = Transport::PeerAddress::TCP(gDestAddr, gSendArguments.GetPort());

err = gSessionManager.Init(&DeviceLayer::SystemLayer, &gTCPManager, &fabrics, &gMessageCounterManager);
err = gSessionManager.Init(&DeviceLayer::SystemLayer(), &gTCPManager, &fabrics, &gMessageCounterManager);
SuccessOrExit(err);
}
else
#endif
{
peerAddress = Transport::PeerAddress::UDP(gDestAddr, gSendArguments.GetPort(), INET_NULL_INTERFACEID);

err = gSessionManager.Init(&DeviceLayer::SystemLayer, &gUDPManager, &fabrics, &gMessageCounterManager);
err = gSessionManager.Init(&DeviceLayer::SystemLayer(), &gUDPManager, &fabrics, &gMessageCounterManager);
SuccessOrExit(err);
}

Expand Down
11 changes: 6 additions & 5 deletions examples/tv-casting-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void RequestUserDirectedCommissioning(System::SocketEvents events, intptr_t data
int selectedCommissionerNumber = CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES;
scanf("%d", &selectedCommissionerNumber);
printf("%d\n", selectedCommissionerNumber);
chip::DeviceLayer::SystemLayer.StopWatchingSocket(&token);
chip::DeviceLayer::SystemLayerSockets().StopWatchingSocket(&token);

const Mdns::DiscoveredNodeData * selectedCommissioner =
commissionableNodeController.GetDiscoveredCommissioner(selectedCommissionerNumber - 1);
Expand Down Expand Up @@ -105,9 +105,10 @@ void InitCommissioningFlow(intptr_t commandArg)
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
VerifyOrReturn(fcntl(0, F_SETFL, flags | O_NONBLOCK) == 0,
ChipLogError(Zcl, "Could not set non-blocking mode for user input!"));
ReturnOnFailure(chip::DeviceLayer::SystemLayer.StartWatchingSocket(STDIN_FILENO, &token));
ReturnOnFailure(chip::DeviceLayer::SystemLayer.SetCallback(token, RequestUserDirectedCommissioning, (intptr_t) NULL));
ReturnOnFailure(chip::DeviceLayer::SystemLayer.RequestCallbackOnPendingRead(token));
ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().StartWatchingSocket(STDIN_FILENO, &token));
ReturnOnFailure(
chip::DeviceLayer::SystemLayerSockets().SetCallback(token, RequestUserDirectedCommissioning, (intptr_t) NULL));
ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().RequestCallbackOnPendingRead(token));
}
else
{
Expand All @@ -127,7 +128,7 @@ int main(int argc, char * argv[])
Mdns::DiscoveryFilter(Mdns::DiscoveryFilterType::kDeviceType, kTvDeviceType)));

// Give commissioners some time to respond and then ScheduleWork to initiate commissioning
DeviceLayer::SystemLayer.StartTimer(
DeviceLayer::SystemLayer().StartTimer(
commissionerDiscoveryTimeoutInMs,
[](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(InitCommissioningFlow); }, nullptr);

Expand Down
6 changes: 3 additions & 3 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ CHIP_ERROR OpenBasicCommissioningWindow(ResetFabrics resetFabrics, uint16_t comm
if (commissioningTimeoutSeconds != kNoCommissioningTimeout)
{
ReturnErrorOnFailure(
DeviceLayer::SystemLayer.StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr));
DeviceLayer::SystemLayer().StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr));
}

return CHIP_NO_ERROR;
Expand All @@ -313,7 +313,7 @@ CHIP_ERROR OpenEnhancedCommissioningWindow(uint16_t commissioningTimeoutSeconds,
if (commissioningTimeoutSeconds != kNoCommissioningTimeout)
{
ReturnErrorOnFailure(
DeviceLayer::SystemLayer.StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr));
DeviceLayer::SystemLayer().StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr));
}

return CHIP_NO_ERROR;
Expand Down Expand Up @@ -384,7 +384,7 @@ void InitServer(AppDelegate * delegate)

SuccessOrExit(err);

err = gSessions.Init(&DeviceLayer::SystemLayer, &gTransports, &gFabrics, &gMessageCounterManager);
err = gSessions.Init(&DeviceLayer::SystemLayer(), &gTransports, &gFabrics, &gMessageCounterManager);
SuccessOrExit(err);

err = gExchangeMgr.Init(&gSessions);
Expand Down
16 changes: 8 additions & 8 deletions src/app/tests/integration/chip_im_initiator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,12 @@ void CommandRequestTimerHandler(chip::System::Layer * systemLayer, void * appSta
err = SendCommandRequest(commandSender);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send command request with error: %s\n", chip::ErrorStr(err)));

err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalMsec, CommandRequestTimerHandler, NULL);
err = chip::DeviceLayer::SystemLayer().StartTimer(gMessageIntervalMsec, CommandRequestTimerHandler, NULL);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err)));
}
else
{
err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalMsec, BadCommandRequestTimerHandler, NULL);
err = chip::DeviceLayer::SystemLayer().StartTimer(gMessageIntervalMsec, BadCommandRequestTimerHandler, NULL);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err)));
}

Expand All @@ -351,7 +351,7 @@ void BadCommandRequestTimerHandler(chip::System::Layer * systemLayer, void * app
err = SendBadCommandRequest(commandSender);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send bad command request with error: %s\n", chip::ErrorStr(err)));

err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalMsec, ReadRequestTimerHandler, NULL);
err = chip::DeviceLayer::SystemLayer().StartTimer(gMessageIntervalMsec, ReadRequestTimerHandler, NULL);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err)));

exit:
Expand All @@ -378,12 +378,12 @@ void ReadRequestTimerHandler(chip::System::Layer * systemLayer, void * appState)
err = SendReadRequest();
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send read request with error: %s\n", chip::ErrorStr(err)));

err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalMsec, ReadRequestTimerHandler, NULL);
err = chip::DeviceLayer::SystemLayer().StartTimer(gMessageIntervalMsec, ReadRequestTimerHandler, NULL);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err)));
}
else
{
err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalMsec, WriteRequestTimerHandler, NULL);
err = chip::DeviceLayer::SystemLayer().StartTimer(gMessageIntervalMsec, WriteRequestTimerHandler, NULL);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err)));
}

Expand Down Expand Up @@ -415,7 +415,7 @@ void WriteRequestTimerHandler(chip::System::Layer * systemLayer, void * appState
err = SendWriteRequest(writeClient);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send write request with error: %s\n", chip::ErrorStr(err)));

err = chip::DeviceLayer::SystemLayer.StartTimer(gMessageIntervalMsec, WriteRequestTimerHandler, NULL);
err = chip::DeviceLayer::SystemLayer().StartTimer(gMessageIntervalMsec, WriteRequestTimerHandler, NULL);
VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err)));
}
else
Expand Down Expand Up @@ -583,7 +583,7 @@ int main(int argc, char * argv[])
.SetListenPort(IM_CLIENT_PORT));
SuccessOrExit(err);

err = gSessionManager.Init(&chip::DeviceLayer::SystemLayer, &gTransportManager, &fabrics, &gMessageCounterManager);
err = gSessionManager.Init(&chip::DeviceLayer::SystemLayer(), &gTransportManager, &fabrics, &gMessageCounterManager);
SuccessOrExit(err);

err = gExchangeManager.Init(&gSessionManager);
Expand All @@ -599,7 +599,7 @@ int main(int argc, char * argv[])
err = EstablishSecureSession();
SuccessOrExit(err);

err = chip::DeviceLayer::SystemLayer.StartTimer(0, CommandRequestTimerHandler, NULL);
err = chip::DeviceLayer::SystemLayer().StartTimer(0, CommandRequestTimerHandler, NULL);
SuccessOrExit(err);

chip::DeviceLayer::PlatformMgr().RunEventLoop();
Expand Down
2 changes: 1 addition & 1 deletion src/app/tests/integration/chip_im_responder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ int main(int argc, char * argv[])
chip::Transport::UdpListenParameters(&chip::DeviceLayer::InetLayer).SetAddressType(chip::Inet::kIPAddressType_IPv4));
SuccessOrExit(err);

err = gSessionManager.Init(&chip::DeviceLayer::SystemLayer, &gTransportManager, &fabrics, &gMessageCounterManager);
err = gSessionManager.Init(&chip::DeviceLayer::SystemLayer(), &gTransportManager, &fabrics, &gMessageCounterManager);
SuccessOrExit(err);

err = gExchangeManager.Init(&gSessionManager);
Expand Down
6 changes: 3 additions & 3 deletions src/app/util/af-event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ EmberStatus emberEventControlSetDelayMS(EmberEventControl * control, uint32_t de
{
control->status = EMBER_EVENT_MS_TIME;
#if !CHIP_DEVICE_LAYER_NONE
chip::DeviceLayer::SystemLayer.StartTimer(delayMs, EventControlHandler, control);
chip::DeviceLayer::SystemLayer().StartTimer(delayMs, EventControlHandler, control);
#endif
}
else
Expand All @@ -164,7 +164,7 @@ void emberEventControlSetInactive(EmberEventControl * control)
{
control->status = EMBER_EVENT_INACTIVE;
#if !CHIP_DEVICE_LAYER_NONE
chip::DeviceLayer::SystemLayer.CancelTimer(EventControlHandler, control);
chip::DeviceLayer::SystemLayer().CancelTimer(EventControlHandler, control);
#endif
}
}
Expand All @@ -178,7 +178,7 @@ void emberEventControlSetActive(EmberEventControl * control)
{
control->status = EMBER_EVENT_ZERO_DELAY;
#if !CHIP_DEVICE_LAYER_NONE
chip::DeviceLayer::SystemLayer.ScheduleWork(EventControlHandler, control);
chip::DeviceLayer::SystemLayer().ScheduleWork(EventControlHandler, control);
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ CHIP_ERROR DeviceController::Init(ControllerInitParams params)
#if CONFIG_DEVICE_LAYER
ReturnErrorOnFailure(DeviceLayer::PlatformMgr().InitChipStack());

mSystemLayer = &DeviceLayer::SystemLayer;
mSystemLayer = &DeviceLayer::SystemLayer();
mInetLayer = &DeviceLayer::InetLayer;
#endif // CONFIG_DEVICE_LAYER
}
Expand Down
2 changes: 1 addition & 1 deletion src/controller/python/chip/internal/CommissionerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ extern "C" chip::Controller::DeviceCommissioner * pychip_internal_Commissioner_N
chip::Controller::CommissionerInitParams params;

params.storageDelegate = &gServerStorage;
params.systemLayer = &chip::DeviceLayer::SystemLayer;
params.systemLayer = &chip::DeviceLayer::SystemLayer();
params.inetLayer = &chip::DeviceLayer::InetLayer;
params.pairingDelegate = &gPairingDelegate;

Expand Down
21 changes: 20 additions & 1 deletion src/include/platform/CHIPDeviceLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,28 @@ namespace chip {
namespace DeviceLayer {

struct ChipDeviceEvent;
extern chip::System::LayerImpl SystemLayer;
extern Inet::InetLayer InetLayer;

inline chip::System::Layer & SystemLayer()
{
extern chip::System::Layer * globalSystemLayer;
return *globalSystemLayer;
}

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
inline chip::System::LayerSockets & SystemLayerSockets()
{
extern chip::System::Layer * globalSystemLayer;
return *static_cast<chip::System::LayerSockets *>(globalSystemLayer);
}
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

inline void SetSystemLayerForTesting(System::Layer * layer)
{
extern chip::System::Layer * globalSystemLayer;
globalSystemLayer = layer;
}

} // namespace DeviceLayer
} // namespace chip

Expand Down
Loading

0 comments on commit a184f57

Please sign in to comment.