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 file implements a unit test suite for the Platform Time
31 #include <nlunit-test.h>
32 #include <support/CodeUtils.h>
33 #include <support/UnitTestRegistration.h>
34 #include <system/SystemClock.h>
36 #include <platform/internal/CHIPDeviceLayerInternal.h>
38 #define TEST_TIME_MARGIN_MS 2
39 #define TEST_TIME_MARGIN_US 500
42 using namespace chip::Logging;
43 using namespace chip::System::Platform::Layer;
45 // =================================
47 // =================================
49 struct time_test_vector
54 static const struct time_test_vector test_vector_system_time_ms[] = {
60 static const struct time_test_vector test_vector_system_time_us[] = {
66 // =================================
68 // =================================
69 // TODO: Make tests OS agnostic
73 void test_os_sleep_ms(uint64_t millisecs)
75 struct timespec sleep_time;
76 int s = millisecs / 1000;
78 millisecs -= s * 1000;
79 sleep_time.tv_sec = s;
80 sleep_time.tv_nsec = millisecs * 1000000;
82 nanosleep(&sleep_time, nullptr);
85 void test_os_sleep_us(uint64_t microsecs)
87 struct timespec sleep_time;
88 int s = microsecs / 1000000;
90 microsecs -= s * 1000000;
91 sleep_time.tv_sec = s;
92 sleep_time.tv_nsec = microsecs * 1000;
94 nanosleep(&sleep_time, nullptr);
97 // =================================
99 // =================================
101 static void TestDevice_GetClock_Monotonic(nlTestSuite * inSuite, void * inContext)
103 int numOfTestVectors = ArraySize(test_vector_system_time_us);
104 int numOfTestsRan = 0;
105 const struct time_test_vector * test_params;
107 uint64_t margin = TEST_TIME_MARGIN_US;
108 uint64_t Tstart, Tend, Tdelta, Tdelay;
110 for (int vectorIndex = 0; vectorIndex < numOfTestVectors; vectorIndex++)
112 test_params = &test_vector_system_time_us[vectorIndex];
113 Tdelay = test_params->delay;
114 Tstart = GetClock_Monotonic();
116 test_os_sleep_us(test_params->delay);
118 Tend = GetClock_Monotonic();
119 Tdelta = Tend - Tstart;
121 ChipLogProgress(DeviceLayer, "Start=%" PRIu64 " End=%" PRIu64 " Delta=%" PRIu64 " Expected=%" PRIu64, Tstart, Tend, Tdelta,
123 // verify that timers don't fire early
124 NL_TEST_ASSERT(inSuite, Tdelta > (Tdelay - margin));
125 // verify they're not too late
126 // NL_TEST_ASSERT(inSuite, Tdelta < (Tdelay + margin));
129 NL_TEST_ASSERT(inSuite, numOfTestsRan > 0);
132 static void TestDevice_GetClock_MonotonicMS(nlTestSuite * inSuite, void * inContext)
134 int numOfTestVectors = ArraySize(test_vector_system_time_ms);
135 int numOfTestsRan = 0;
136 const struct time_test_vector * test_params;
138 uint64_t margin = TEST_TIME_MARGIN_MS;
139 uint64_t Tstart, Tend, Tdelta, Tdelay;
141 for (int vectorIndex = 0; vectorIndex < numOfTestVectors; vectorIndex++)
143 test_params = &test_vector_system_time_ms[vectorIndex];
144 Tdelay = test_params->delay;
145 Tstart = GetClock_MonotonicMS();
147 test_os_sleep_ms(test_params->delay);
149 Tend = GetClock_MonotonicMS();
150 Tdelta = Tend - Tstart;
152 ChipLogProgress(DeviceLayer, "Start=%" PRIu64 " End=%" PRIu64 " Delta=%" PRIu64 " Expected=%" PRIu64, Tstart, Tend, Tdelta,
154 // verify that timers don't fire early
155 NL_TEST_ASSERT(inSuite, Tdelta > (Tdelay - margin));
156 // verify they're not too late
157 // NL_TEST_ASSERT(inSuite, Tdelta < (Tdelay + margin));
160 NL_TEST_ASSERT(inSuite, numOfTestsRan > 0);
163 static void TestDevice_GetClock_MonotonicHiRes(nlTestSuite * inSuite, void * inContext)
165 int numOfTestVectors = ArraySize(test_vector_system_time_us);
166 int numOfTestsRan = 0;
167 const struct time_test_vector * test_params;
169 uint64_t margin = TEST_TIME_MARGIN_US;
170 uint64_t Tstart, Tend, Tdelta, Tdelay;
172 for (int vectorIndex = 0; vectorIndex < numOfTestVectors; vectorIndex++)
174 test_params = &test_vector_system_time_us[vectorIndex];
175 Tdelay = test_params->delay;
176 Tstart = GetClock_MonotonicHiRes();
178 test_os_sleep_us(test_params->delay);
180 Tend = GetClock_MonotonicHiRes();
181 Tdelta = Tend - Tstart;
183 ChipLogProgress(DeviceLayer, "Start=%" PRIu64 " End=%" PRIu64 " Delta=%" PRIu64 " Expected=%" PRIu64, Tstart, Tend, Tdelta,
185 NL_TEST_ASSERT(inSuite, Tdelta > (Tdelay - margin));
188 NL_TEST_ASSERT(inSuite, numOfTestsRan > 0);
192 * Test Suite. It lists all the test functions.
194 static const nlTest sTests[] = {
196 NL_TEST_DEF("Test DeviceLayer::GetClock_Monotonic", TestDevice_GetClock_Monotonic),
197 NL_TEST_DEF("Test DeviceLayer::GetClock_MonotonicMS", TestDevice_GetClock_MonotonicMS),
198 NL_TEST_DEF("Test DeviceLayer::GetClock_MonotonicHiRes", TestDevice_GetClock_MonotonicHiRes),
203 int TestPlatformTime()
205 nlTestSuite theSuite = { "PlatformTime tests", &sTests[0], nullptr, nullptr };
207 // Run test suit againt one context.
208 nlTestRunner(&theSuite, nullptr);
209 return nlTestRunnerStats(&theSuite);
212 CHIP_REGISTER_TEST_SUITE(TestPlatformTime)