summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2016-01-14 07:28:21 -0800
committerMark Salyzyn <salyzyn@google.com>2016-01-14 07:30:22 -0800
commitf1ec6990593a8db655746f415619e1da7093a168 (patch)
tree3dca774b7b33745ae0636357ba925e69705f8715 /tests
parent59c72161d70447232ee646d2cb9b756d76db91f3 (diff)
downloadextras-f1ec6990593a8db655746f415619e1da7093a168.tar.gz
Add time rtc ioctl tests
- test read validity - test year setting from 1970 to 2037 (2015+ critical) - test year rollover operation (68 seconds to run test) Bug: 26346842 Change-Id: I225ca2a25c291b9d05d75f5f39de2c6c753fcba1
Diffstat (limited to 'tests')
-rw-r--r--tests/timetest/Android.mk23
-rw-r--r--tests/timetest/rtc_test.cpp149
2 files changed, 172 insertions, 0 deletions
diff --git a/tests/timetest/Android.mk b/tests/timetest/Android.mk
index 05e21fbe..b2a1aa5b 100644
--- a/tests/timetest/Android.mk
+++ b/tests/timetest/Android.mk
@@ -1,6 +1,7 @@
# Copyright 2006 The Android Open Source Project
LOCAL_PATH:= $(call my-dir)
+
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= timetest.c
@@ -17,3 +18,25 @@ LOCAL_STATIC_LIBRARIES := libc
include $(BUILD_EXECUTABLE)
+# -----------------------------------------------------------------------------
+# Unit tests.
+# -----------------------------------------------------------------------------
+
+test_c_flags := \
+ -fstack-protector-all \
+ -g \
+ -Wall -Wextra \
+ -Werror \
+ -fno-builtin \
+ -std=gnu++11
+
+test_src_files := \
+ rtc_test.cpp
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := time-unit-tests
+LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS += $(test_c_flags)
+LOCAL_SRC_FILES := $(test_src_files)
+include $(BUILD_NATIVE_TEST)
+
diff --git a/tests/timetest/rtc_test.cpp b/tests/timetest/rtc_test.cpp
new file mode 100644
index 00000000..9dd6fd89
--- /dev/null
+++ b/tests/timetest/rtc_test.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/rtc.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+
+static int hwtime(int flag, int request, struct rtc_time *tm) {
+ int ret;
+ do {
+ ret = TEMP_FAILURE_RETRY(open("/dev/rtc0", flag));
+ if (ret < 0) {
+ ret = -errno;
+ }
+ } while (ret == -EBUSY);
+ if (ret < 0) {
+ return ret;
+ }
+
+ int fd = ret;
+ do {
+ ret = TEMP_FAILURE_RETRY(ioctl(fd, request, tm));
+ if (ret < 0) {
+ ret = -errno;
+ }
+ } while (ret == -EBUSY);
+ close(fd);
+ return ret;
+}
+
+static int rd_hwtime(struct rtc_time *tm) {
+ return hwtime(O_RDONLY, RTC_RD_TIME, tm);
+}
+
+static int set_hwtime(struct rtc_time *tm) {
+ return hwtime(O_WRONLY, RTC_SET_TIME, tm);
+}
+
+TEST(time, rtc_rollover) {
+ struct rtc_time roll;
+ memset(&roll, 0, sizeof(roll));
+ ASSERT_LE(0, rd_hwtime(&roll));
+ int mday[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ mday[1] = (roll.tm_year % 4) ? 28 : 29;
+ ASSERT_LE(0, roll.tm_sec);
+ ASSERT_GT(60, roll.tm_sec);
+ ASSERT_LE(0, roll.tm_min);
+ ASSERT_GT(60, roll.tm_min);
+ ASSERT_LE(0, roll.tm_hour);
+ ASSERT_GT(24, roll.tm_hour);
+ ASSERT_LE(0, roll.tm_mday);
+ ASSERT_GE(mday[roll.tm_mon], roll.tm_mday);
+ ASSERT_LE(0, roll.tm_mon);
+ ASSERT_GT(12, roll.tm_mon);
+ ASSERT_LE(0, roll.tm_year);
+ ASSERT_GT(138, roll.tm_year);
+
+ // Wait for granular clock
+ struct rtc_time save = roll;
+ static const useconds_t timeout_sleep = 10000;
+ static const int timeout_num = 2000000 / timeout_sleep;
+ int timeout;
+ for (timeout = timeout_num; timeout && (roll.tm_year == save.tm_year); --timeout) {
+ ASSERT_LE(0, rd_hwtime(&save));
+ usleep(timeout_sleep);
+ }
+
+ memset(&roll, 0, sizeof(roll));
+ roll.tm_sec = 59;
+ roll.tm_min = 59;
+ roll.tm_hour = 23;
+ roll.tm_mday = 31;
+ roll.tm_mon = 11;
+ roll.tm_year = 70;
+ roll.tm_wday = 0;
+ roll.tm_yday = 0;
+ roll.tm_isdst = 0;
+
+ for (roll.tm_year = 70; roll.tm_year < 137; ++roll.tm_year) {
+ struct rtc_time tm = roll;
+ int __set_hwtime = set_hwtime(&tm);
+ // below 2015, permitted to error out.
+ if ((__set_hwtime == -EINVAL) && (roll.tm_year < 115)) {
+ continue;
+ }
+ ASSERT_LE(0, __set_hwtime);
+ ASSERT_LE(0, rd_hwtime(&tm));
+ ASSERT_EQ(roll.tm_sec, tm.tm_sec);
+ ASSERT_EQ(roll.tm_min, tm.tm_min);
+ ASSERT_EQ(roll.tm_hour, tm.tm_hour);
+ ASSERT_EQ(roll.tm_mday, tm.tm_mday);
+ ASSERT_EQ(roll.tm_mon, tm.tm_mon);
+ ASSERT_EQ(roll.tm_year, tm.tm_year);
+ for (timeout = timeout_num; timeout && (roll.tm_year == tm.tm_year); --timeout) {
+ ASSERT_LE(0, rd_hwtime(&tm));
+ usleep(timeout_sleep);
+ }
+ ASSERT_EQ(roll.tm_year + 1, tm.tm_year);
+ EXPECT_LT(timeout_num * 5 / 100, timeout);
+ EXPECT_GT(timeout_num * 95 / 100, timeout);
+
+ // correct saved time to compensate for rollover check
+ if (++save.tm_sec >= 60) {
+ save.tm_sec = 0;
+ if (++save.tm_min >= 60) {
+ save.tm_min = 0;
+ if (++save.tm_hour >= 24) {
+ save.tm_hour = 0;
+ mday[1] = (save.tm_year % 4) ? 28 : 29;
+ if (++save.tm_mday >= mday[save.tm_mon]) {
+ save.tm_mday = 1;
+ if (++save.tm_mon >= 12) {
+ save.tm_mon = 0;
+ ++save.tm_year;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ASSERT_LE(0, set_hwtime(&save));
+ ASSERT_LE(0, rd_hwtime(&roll));
+
+ ASSERT_EQ(save.tm_sec, roll.tm_sec);
+ ASSERT_EQ(save.tm_min, roll.tm_min);
+ ASSERT_EQ(save.tm_hour, roll.tm_hour);
+ ASSERT_EQ(save.tm_mday, roll.tm_mday);
+ ASSERT_EQ(save.tm_mon, roll.tm_mon);
+ ASSERT_EQ(save.tm_year, roll.tm_year);
+}