init

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "utest/utest.h"
00018 #include "unity/unity.h"
00019 #include "greentea-client/test_env.h"
00020 
00021 #include "mbed.h"
00022 #include "mbed_mktime.h"
00023 
00024 #define LAST_VALID_YEAR 206
00025 
00026 using namespace utest::v1;
00027 
00028 static rtc_leap_year_support_t rtc_leap_year_support;
00029 
00030 /*  Regular is_leap_year, see platform/mbed_mktime.c for the optimised version. */
00031 bool is_leap_year(int year)
00032 {
00033     year = 1900 + year;
00034     if (year % 4) {
00035         return false;
00036     } else if (year % 100) {
00037         return true;
00038     } else if (year % 400) {
00039         return false;
00040     }
00041     return true;
00042 }
00043 
00044 /* Test the optimised version of _rtc_is_leap_year() against the generic version.
00045  *
00046  * Note: This test case is designed for both types of RTC devices:
00047  *       - RTC devices which handle correctly leap years in whole range (1970 - 2106).
00048  *       - RTC devices which does not handle correctly leap years in whole range (1970 - 2106).
00049  *         This RTC devices uses simpler leap year detection and incorrectly treat 2100 as a leap year.
00050  *       rtc_leap_year_support variable specifies which device is tested.
00051  *
00052  * Given is year in valid range.
00053  * When _rtc_is_leap_year() function is called.
00054  * Then _rtc_is_leap_year() returns true if given year is a leap year; false otherwise.
00055  */
00056 void test_is_leap_year()
00057 {
00058     for (int i = 70; i <= LAST_VALID_YEAR; ++i) {
00059         bool expected = is_leap_year(i);
00060 
00061         /* Add exception for year 2100. */
00062         if (rtc_leap_year_support == RTC_4_YEAR_LEAP_YEAR_SUPPORT && i == 200) {
00063             expected = true;
00064         }
00065 
00066         bool actual_value = _rtc_is_leap_year(i, rtc_leap_year_support);
00067 
00068         if (expected != actual_value) {
00069             printf("Leap year failed with i = %d\r\n", i);
00070         }
00071         TEST_ASSERT_EQUAL(expected, actual_value);
00072     }
00073 }
00074 
00075 /* Structure to test border values for _rtc_maketime(). */
00076 typedef struct
00077 {
00078     struct tm timeinfo;
00079     time_t exp_seconds;  // if result is false then exp_seconds is irrelevant
00080     bool result;
00081 } test_mk_time_struct;
00082 
00083 /* Array which contains data to test boundary values for the RTC devices which handles correctly leap years in
00084  * whole range (1970 - 2106).
00085  * Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 7th of February 2106 at 06:28:15 (seconds: UINT_MAX).
00086  */
00087 test_mk_time_struct test_mk_time_arr_full[] = {
00088     {{ 0, 0, 0, 1, 0, 70, 0, 0, 0 },      (time_t) 0, true},          // valid lower bound - the 1st of January 1970 at 00:00:00
00089     {{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false },        // invalid lower bound - the 31st of December 1969 at 23:59:59
00090 
00091     {{ 15, 28, 6, 7, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true },   // valid upper bound - the 7th of February 2106 at 06:28:15
00092     {{ 16, 28, 6, 7, 1, 206, 0, 0, 0 }, (time_t) 0, false },          // invalid upper bound - the 7th of February 2106 at 06:28:16
00093 };
00094 
00095 /* Array which contains data to test boundary values for the RTC devices which does not handle correctly leap years in
00096  * whole range (1970 - 2106). On this platforms we will be one day off after 28.02.2100 since 2100 year will be
00097  * incorrectly treated as a leap year.
00098  * Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 6th of February 2106 at 06:28:15 (seconds: UINT_MAX).
00099  */
00100 test_mk_time_struct test_mk_time_arr_partial[] = {
00101     {{ 0, 0, 0, 1, 0, 70, 0, 0, 0 },      (time_t) 0, true},          // valid lower bound - the 1st of January 1970 at 00:00:00
00102     {{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false },        // invalid lower bound - the 31st of December 1969 at 23:59:59
00103 
00104     {{ 15, 28, 6, 6, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true },   // valid upper bound - the 6th of February 2106 at 06:28:15
00105     {{ 16, 28, 6, 6, 1, 206, 0, 0, 0 }, (time_t) 0, false },          // invalid upper bound - the 6th of February 2106 at 06:28:16
00106 };
00107 
00108 /* Test boundary values for _rtc_maketime().
00109  *
00110  * Note: This test case is designed for both types of RTC devices:
00111  *       - RTC devices which handle correctly leap years in whole range (1970 - 2106).
00112  *       - RTC devices which does not handle correctly leap years in whole range (1970 - 2106).
00113  *         This RTC devices uses simpler leap year detection and incorrectly treat 2100 as a leap year.
00114  *       rtc_leap_year_support variable specifies which device is tested.
00115  *
00116  * Given is boundary calendar time.
00117  * When _rtc_maketime() function is called to convert the calendar time into timestamp.
00118  * Then if given calendar time is valid function returns true and conversion result, otherwise returns false.
00119  */
00120 void test_mk_time_boundary()
00121 {
00122     test_mk_time_struct *pTestCases;
00123 
00124     /* Select array with test cases. */
00125     if (rtc_leap_year_support == RTC_FULL_LEAP_YEAR_SUPPORT) {
00126         pTestCases = test_mk_time_arr_full;
00127     } else {
00128         pTestCases = test_mk_time_arr_partial;
00129     }
00130 
00131     for (int i = 0; i < (sizeof(test_mk_time_arr_full) / (sizeof(test_mk_time_struct))); i++) {
00132         time_t seconds;
00133         bool result = _rtc_maketime(&pTestCases[i].timeinfo, &seconds, rtc_leap_year_support);
00134 
00135         TEST_ASSERT_EQUAL(pTestCases[i].result, result);
00136 
00137         /* If the result is false, then we have conversion error - skip checking seconds. */
00138         if (pTestCases[i].result) {
00139             TEST_ASSERT_EQUAL_UINT32(pTestCases[i].exp_seconds, seconds);
00140         }
00141     }
00142 }
00143 
00144 /* Test _rtc_maketime() function - call with invalid parameters.
00145  *
00146  * Given is _rtc_maketime() function.
00147  * When _rtc_maketime() function is called with invalid parameter.
00148  * Then _rtc_maketime() function returns false.
00149  */
00150 void test_mk_time_invalid_param()
00151 {
00152     time_t seconds;
00153     struct tm timeinfo;
00154 
00155     TEST_ASSERT_EQUAL(false, _rtc_maketime(NULL, &seconds, RTC_FULL_LEAP_YEAR_SUPPORT ));
00156     TEST_ASSERT_EQUAL(false, _rtc_maketime(NULL, &seconds, RTC_4_YEAR_LEAP_YEAR_SUPPORT ));
00157     TEST_ASSERT_EQUAL(false, _rtc_maketime(&timeinfo, NULL, RTC_FULL_LEAP_YEAR_SUPPORT ));
00158     TEST_ASSERT_EQUAL(false, _rtc_maketime(&timeinfo, NULL, RTC_4_YEAR_LEAP_YEAR_SUPPORT ));
00159 }
00160 
00161 /* Test _rtc_localtime() function - call with invalid parameters.
00162  *
00163  * Given is _rtc_localtime() function.
00164  * When _rtc_localtime() function is called with invalid parameter.
00165  * Then _rtc_localtime() function returns false.
00166  */
00167 void test_local_time_invalid_param()
00168 {
00169     TEST_ASSERT_EQUAL(false, _rtc_localtime(1, NULL, RTC_FULL_LEAP_YEAR_SUPPORT ));
00170     TEST_ASSERT_EQUAL(false, _rtc_localtime(1, NULL, RTC_4_YEAR_LEAP_YEAR_SUPPORT ));
00171 }
00172 
00173 utest::v1::status_t teardown_handler_t(const Case * const source, const size_t passed, const size_t failed,
00174         const failure_t reason)
00175 {
00176     return greentea_case_teardown_handler(source, passed, failed, reason);
00177 }
00178 
00179 utest::v1::status_t full_leap_year_case_setup_handler_t(const Case * const source, const size_t index_of_case)
00180 {
00181     rtc_leap_year_support = RTC_FULL_LEAP_YEAR_SUPPORT;
00182 
00183     return greentea_case_setup_handler(source, index_of_case);
00184 }
00185 
00186 utest::v1::status_t partial_leap_year_case_setup_handler_t(const Case * const source, const size_t index_of_case)
00187 {
00188     rtc_leap_year_support = RTC_4_YEAR_LEAP_YEAR_SUPPORT;
00189 
00190     return greentea_case_setup_handler(source, index_of_case);
00191 }
00192 
00193 Case cases[] = {
00194   Case("test is leap year - RTC leap years full support", full_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t),
00195   Case("test is leap year - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t),
00196   Case("test make time boundary values - RTC leap years full support", full_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t),
00197   Case("test make time boundary values - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t),
00198   Case("test make time - invalid param", test_mk_time_invalid_param, teardown_handler_t),
00199   Case("test local time - invalid param", test_local_time_invalid_param, teardown_handler_t),
00200 };
00201 
00202 utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
00203 {
00204     GREENTEA_SETUP(20, "default_auto");
00205     return greentea_test_setup_handler(number_of_cases);
00206 }
00207 
00208 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
00209 
00210 int main()
00211 {
00212     return Harness::run(specification);
00213 }