3 * Copyright (c) 2020 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 * This is a unit test suite for <tt>chip::System::SystemWakeEvent</tt>
24 #ifndef __STDC_LIMIT_MACROS
25 #define __STDC_LIMIT_MACROS
28 #include <system/SystemConfig.h>
30 #include <nlunit-test.h>
31 #include <support/CodeUtils.h>
32 #include <support/ErrorStr.h>
33 #include <support/UnitTestRegistration.h>
34 #include <system/SystemError.h>
35 #include <system/SystemLayer.h>
36 #include <system/SystemWakeEvent.h>
38 #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
40 #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
42 using namespace chip::System;
44 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
49 SystemWakeEvent mWakeEvent;
54 TestContext() { mWakeEvent.Open(); }
55 ~TestContext() { mWakeEvent.Close(); }
57 int SelectWakeEvent(timeval timeout = {})
62 FD_SET(mWakeEvent.GetNotifFD(), &mReadSet);
63 return select(mWakeEvent.GetNotifFD() + 1, &mReadSet, &mWriteSet, &mErrorSet, &timeout);
67 void TestOpen(nlTestSuite * inSuite, void * aContext)
69 TestContext & lContext = *static_cast<TestContext *>(aContext);
70 NL_TEST_ASSERT(inSuite, lContext.mWakeEvent.GetNotifFD() >= 0);
71 NL_TEST_ASSERT(inSuite, lContext.SelectWakeEvent() == 0);
74 void TestNotify(nlTestSuite * inSuite, void * aContext)
76 TestContext & lContext = *static_cast<TestContext *>(aContext);
77 NL_TEST_ASSERT(inSuite, lContext.SelectWakeEvent() == 0);
79 // Check that select() succeeds after Notify() has been called
80 lContext.mWakeEvent.Notify();
81 NL_TEST_ASSERT(inSuite, lContext.SelectWakeEvent() == 1);
82 NL_TEST_ASSERT(inSuite, FD_ISSET(lContext.mWakeEvent.GetNotifFD(), &lContext.mReadSet));
84 // ...and state of the event is not cleared automatically
85 NL_TEST_ASSERT(inSuite, lContext.SelectWakeEvent() == 1);
86 NL_TEST_ASSERT(inSuite, FD_ISSET(lContext.mWakeEvent.GetNotifFD(), &lContext.mReadSet));
89 void TestConfirm(nlTestSuite * inSuite, void * aContext)
91 TestContext & lContext = *static_cast<TestContext *>(aContext);
93 // Check that select() succeeds after Notify() has been called
94 lContext.mWakeEvent.Notify();
95 NL_TEST_ASSERT(inSuite, lContext.SelectWakeEvent() == 1);
96 NL_TEST_ASSERT(inSuite, FD_ISSET(lContext.mWakeEvent.GetNotifFD(), &lContext.mReadSet));
98 // Check that Confirm() clears state of the event
99 lContext.mWakeEvent.Confirm();
100 NL_TEST_ASSERT(inSuite, lContext.SelectWakeEvent() == 0);
103 #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
104 void * WaitForEvent(void * aContext)
106 TestContext & lContext = *static_cast<TestContext *>(aContext);
108 return reinterpret_cast<void *>(lContext.SelectWakeEvent(timeval{ 5, 0 }));
111 void TestBlockingSelect(nlTestSuite * inSuite, void * aContext)
113 TestContext & lContext = *static_cast<TestContext *>(aContext);
115 // Spawn a thread waiting for the event
117 NL_TEST_ASSERT(inSuite, 0 == pthread_create(&tid, nullptr, WaitForEvent, aContext));
119 lContext.mWakeEvent.Notify();
120 void * selectResult = nullptr;
121 NL_TEST_ASSERT(inSuite, 0 == pthread_join(tid, &selectResult));
122 NL_TEST_ASSERT(inSuite, selectResult == reinterpret_cast<void *>(1));
124 #else // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
125 void TestBlockingSelect(nlTestSuite *, void *) {}
126 #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
128 void TestClose(nlTestSuite * inSuite, void * aContext)
130 TestContext & lContext = *static_cast<TestContext *>(aContext);
131 lContext.mWakeEvent.Close();
133 const auto notifFD = lContext.mWakeEvent.GetNotifFD();
135 // Check that Close() has cleaned up itself and reopen is possible
136 NL_TEST_ASSERT(inSuite, lContext.mWakeEvent.Open() == CHIP_SYSTEM_NO_ERROR);
137 NL_TEST_ASSERT(inSuite, notifFD < 0);
144 * Test Suite. It lists all the test functions.
147 static const nlTest sTests[] =
149 NL_TEST_DEF("WakeEvent::TestOpen", TestOpen),
150 NL_TEST_DEF("WakeEvent::TestNotify", TestNotify),
151 NL_TEST_DEF("WakeEvent::TestConfirm", TestConfirm),
152 NL_TEST_DEF("WakeEvent::TestBlockingSelect", TestBlockingSelect),
153 NL_TEST_DEF("WakeEvent::TestClose", TestClose),
159 static nlTestSuite kTheSuite =
161 "chip-system-wake-event",
166 int TestSystemWakeEvent(void)
170 // Run test suit againt one lContext.
171 nlTestRunner(&kTheSuite, &context);
173 return nlTestRunnerStats(&kTheSuite);
176 CHIP_REGISTER_TEST_SUITE(TestSystemWakeEvent)
177 #else // CHIP_SYSTEM_CONFIG_USE_SOCKETS
178 int TestSystemWakeEvent(void)
182 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS