Skip to content

Commit 83ced5b

Browse files
Mark SalyzynGerrit Code Review
Mark Salyzyn
authored and
Gerrit Code Review
committed
Merge "Add time rtc ioctl tests"
2 parents 59c7216 + f1ec699 commit 83ced5b

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

tests/timetest/Android.mk

+23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright 2006 The Android Open Source Project
22

33
LOCAL_PATH:= $(call my-dir)
4+
45
include $(CLEAR_VARS)
56

67
LOCAL_SRC_FILES:= timetest.c
@@ -17,3 +18,25 @@ LOCAL_STATIC_LIBRARIES := libc
1718

1819
include $(BUILD_EXECUTABLE)
1920

21+
# -----------------------------------------------------------------------------
22+
# Unit tests.
23+
# -----------------------------------------------------------------------------
24+
25+
test_c_flags := \
26+
-fstack-protector-all \
27+
-g \
28+
-Wall -Wextra \
29+
-Werror \
30+
-fno-builtin \
31+
-std=gnu++11
32+
33+
test_src_files := \
34+
rtc_test.cpp
35+
36+
include $(CLEAR_VARS)
37+
LOCAL_MODULE := time-unit-tests
38+
LOCAL_MODULE_TAGS := tests
39+
LOCAL_CFLAGS += $(test_c_flags)
40+
LOCAL_SRC_FILES := $(test_src_files)
41+
include $(BUILD_NATIVE_TEST)
42+

tests/timetest/rtc_test.cpp

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Copyright (C) 2016 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <errno.h>
18+
#include <fcntl.h>
19+
#include <linux/rtc.h>
20+
#include <sys/ioctl.h>
21+
#include <sys/types.h>
22+
#include <unistd.h>
23+
24+
#include <gtest/gtest.h>
25+
26+
static int hwtime(int flag, int request, struct rtc_time *tm) {
27+
int ret;
28+
do {
29+
ret = TEMP_FAILURE_RETRY(open("/dev/rtc0", flag));
30+
if (ret < 0) {
31+
ret = -errno;
32+
}
33+
} while (ret == -EBUSY);
34+
if (ret < 0) {
35+
return ret;
36+
}
37+
38+
int fd = ret;
39+
do {
40+
ret = TEMP_FAILURE_RETRY(ioctl(fd, request, tm));
41+
if (ret < 0) {
42+
ret = -errno;
43+
}
44+
} while (ret == -EBUSY);
45+
close(fd);
46+
return ret;
47+
}
48+
49+
static int rd_hwtime(struct rtc_time *tm) {
50+
return hwtime(O_RDONLY, RTC_RD_TIME, tm);
51+
}
52+
53+
static int set_hwtime(struct rtc_time *tm) {
54+
return hwtime(O_WRONLY, RTC_SET_TIME, tm);
55+
}
56+
57+
TEST(time, rtc_rollover) {
58+
struct rtc_time roll;
59+
memset(&roll, 0, sizeof(roll));
60+
ASSERT_LE(0, rd_hwtime(&roll));
61+
int mday[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
62+
mday[1] = (roll.tm_year % 4) ? 28 : 29;
63+
ASSERT_LE(0, roll.tm_sec);
64+
ASSERT_GT(60, roll.tm_sec);
65+
ASSERT_LE(0, roll.tm_min);
66+
ASSERT_GT(60, roll.tm_min);
67+
ASSERT_LE(0, roll.tm_hour);
68+
ASSERT_GT(24, roll.tm_hour);
69+
ASSERT_LE(0, roll.tm_mday);
70+
ASSERT_GE(mday[roll.tm_mon], roll.tm_mday);
71+
ASSERT_LE(0, roll.tm_mon);
72+
ASSERT_GT(12, roll.tm_mon);
73+
ASSERT_LE(0, roll.tm_year);
74+
ASSERT_GT(138, roll.tm_year);
75+
76+
// Wait for granular clock
77+
struct rtc_time save = roll;
78+
static const useconds_t timeout_sleep = 10000;
79+
static const int timeout_num = 2000000 / timeout_sleep;
80+
int timeout;
81+
for (timeout = timeout_num; timeout && (roll.tm_year == save.tm_year); --timeout) {
82+
ASSERT_LE(0, rd_hwtime(&save));
83+
usleep(timeout_sleep);
84+
}
85+
86+
memset(&roll, 0, sizeof(roll));
87+
roll.tm_sec = 59;
88+
roll.tm_min = 59;
89+
roll.tm_hour = 23;
90+
roll.tm_mday = 31;
91+
roll.tm_mon = 11;
92+
roll.tm_year = 70;
93+
roll.tm_wday = 0;
94+
roll.tm_yday = 0;
95+
roll.tm_isdst = 0;
96+
97+
for (roll.tm_year = 70; roll.tm_year < 137; ++roll.tm_year) {
98+
struct rtc_time tm = roll;
99+
int __set_hwtime = set_hwtime(&tm);
100+
// below 2015, permitted to error out.
101+
if ((__set_hwtime == -EINVAL) && (roll.tm_year < 115)) {
102+
continue;
103+
}
104+
ASSERT_LE(0, __set_hwtime);
105+
ASSERT_LE(0, rd_hwtime(&tm));
106+
ASSERT_EQ(roll.tm_sec, tm.tm_sec);
107+
ASSERT_EQ(roll.tm_min, tm.tm_min);
108+
ASSERT_EQ(roll.tm_hour, tm.tm_hour);
109+
ASSERT_EQ(roll.tm_mday, tm.tm_mday);
110+
ASSERT_EQ(roll.tm_mon, tm.tm_mon);
111+
ASSERT_EQ(roll.tm_year, tm.tm_year);
112+
for (timeout = timeout_num; timeout && (roll.tm_year == tm.tm_year); --timeout) {
113+
ASSERT_LE(0, rd_hwtime(&tm));
114+
usleep(timeout_sleep);
115+
}
116+
ASSERT_EQ(roll.tm_year + 1, tm.tm_year);
117+
EXPECT_LT(timeout_num * 5 / 100, timeout);
118+
EXPECT_GT(timeout_num * 95 / 100, timeout);
119+
120+
// correct saved time to compensate for rollover check
121+
if (++save.tm_sec >= 60) {
122+
save.tm_sec = 0;
123+
if (++save.tm_min >= 60) {
124+
save.tm_min = 0;
125+
if (++save.tm_hour >= 24) {
126+
save.tm_hour = 0;
127+
mday[1] = (save.tm_year % 4) ? 28 : 29;
128+
if (++save.tm_mday >= mday[save.tm_mon]) {
129+
save.tm_mday = 1;
130+
if (++save.tm_mon >= 12) {
131+
save.tm_mon = 0;
132+
++save.tm_year;
133+
}
134+
}
135+
}
136+
}
137+
}
138+
}
139+
140+
ASSERT_LE(0, set_hwtime(&save));
141+
ASSERT_LE(0, rd_hwtime(&roll));
142+
143+
ASSERT_EQ(save.tm_sec, roll.tm_sec);
144+
ASSERT_EQ(save.tm_min, roll.tm_min);
145+
ASSERT_EQ(save.tm_hour, roll.tm_hour);
146+
ASSERT_EQ(save.tm_mday, roll.tm_mday);
147+
ASSERT_EQ(save.tm_mon, roll.tm_mon);
148+
ASSERT_EQ(save.tm_year, roll.tm_year);
149+
}

0 commit comments

Comments
 (0)