2017-06-08 02:59:17 +00:00
/* mbed Microcontroller Library
* Copyright ( c ) 2017 ARM Limited
*
* 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 "utest/utest.h"
# include "unity/unity.h"
# include "greentea-client/test_env.h"
# include "mbed.h"
# include "mbed_mktime.h"
2017-11-06 14:07:19 +00:00
# define LAST_VALID_YEAR 206
2017-06-09 21:23:40 +00:00
2017-06-08 02:59:17 +00:00
using namespace utest : : v1 ;
2017-11-06 14:07:19 +00:00
static rtc_leap_year_support_t rtc_leap_year_support ;
/* Regular is_leap_year, see platform/mbed_mktime.c for the optimised version. */
bool is_leap_year ( int year )
{
2017-06-08 02:59:17 +00:00
year = 1900 + year ;
if ( year % 4 ) {
return false ;
} else if ( year % 100 ) {
return true ;
} else if ( year % 400 ) {
return false ;
}
return true ;
}
2017-11-06 14:07:19 +00:00
/* Test the optimised version of _rtc_is_leap_year() against the generic version.
*
* Note : This test case is designed for both types of RTC devices :
* - RTC devices which handle correctly leap years in whole range ( 1970 - 2106 ) .
* - RTC devices which does not handle correctly leap years in whole range ( 1970 - 2106 ) .
* This RTC devices uses simpler leap year detection and incorrectly treat 2100 as a leap year .
* rtc_leap_year_support variable specifies which device is tested .
*
* Given is year in valid range .
* When _rtc_is_leap_year ( ) function is called .
* Then _rtc_is_leap_year ( ) returns true if given year is a leap year ; false otherwise .
2017-06-08 02:59:17 +00:00
*/
2017-11-06 14:07:19 +00:00
void test_is_leap_year ( )
{
for ( int i = 70 ; i < = LAST_VALID_YEAR ; + + i ) {
2017-06-08 02:59:17 +00:00
bool expected = is_leap_year ( i ) ;
2017-11-06 14:07:19 +00:00
/* Add exception for year 2100. */
if ( rtc_leap_year_support = = RTC_4_YEAR_LEAP_YEAR_SUPPORT & & i = = 200 ) {
expected = true ;
}
bool actual_value = _rtc_is_leap_year ( i , rtc_leap_year_support ) ;
if ( expected ! = actual_value ) {
printf ( " Leap year failed with i = %d \r \n " , i ) ;
2017-06-08 02:59:17 +00:00
}
TEST_ASSERT_EQUAL ( expected , actual_value ) ;
}
}
2017-11-06 14:07:19 +00:00
/* Structure to test border values for _rtc_maketime(). */
typedef struct
{
struct tm timeinfo ;
time_t exp_seconds ; // if result is false then exp_seconds is irrelevant
bool result ;
} test_mk_time_struct ;
/* Array which contains data to test boundary values for the RTC devices which handles correctly leap years in
* whole range ( 1970 - 2106 ) .
* Expected range : the 1 st of January 1970 at 00 : 00 : 00 ( seconds : 0 ) to the 7 th of February 2106 at 06 : 28 : 15 ( seconds : UINT_MAX ) .
*/
test_mk_time_struct test_mk_time_arr_full [ ] = {
{ { 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
{ { 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
{ { 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
{ { 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
} ;
2017-06-08 02:59:17 +00:00
2017-11-06 14:07:19 +00:00
/* Array which contains data to test boundary values for the RTC devices which does not handle correctly leap years in
* whole range ( 1970 - 2106 ) . On this platforms we will be one day off after 28.02 .2100 since 2100 year will be
* incorrectly treated as a leap year .
* Expected range : the 1 st of January 1970 at 00 : 00 : 00 ( seconds : 0 ) to the 6 th of February 2106 at 06 : 28 : 15 ( seconds : UINT_MAX ) .
2017-06-08 02:59:17 +00:00
*/
2017-11-06 14:07:19 +00:00
test_mk_time_struct test_mk_time_arr_partial [ ] = {
{ { 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
{ { 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
2017-06-08 02:59:17 +00:00
2017-11-06 14:07:19 +00:00
{ { 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
{ { 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
} ;
/* Test boundary values for _rtc_maketime().
*
* Note : This test case is designed for both types of RTC devices :
* - RTC devices which handle correctly leap years in whole range ( 1970 - 2106 ) .
* - RTC devices which does not handle correctly leap years in whole range ( 1970 - 2106 ) .
* This RTC devices uses simpler leap year detection and incorrectly treat 2100 as a leap year .
* rtc_leap_year_support variable specifies which device is tested .
*
* Given is boundary calendar time .
* When _rtc_maketime ( ) function is called to convert the calendar time into timestamp .
* Then if given calendar time is valid function returns true and conversion result , otherwise returns false .
2017-06-08 02:59:17 +00:00
*/
2017-11-06 14:07:19 +00:00
void test_mk_time_boundary ( )
{
test_mk_time_struct * pTestCases ;
/* Select array with test cases. */
if ( rtc_leap_year_support = = RTC_FULL_LEAP_YEAR_SUPPORT ) {
pTestCases = test_mk_time_arr_full ;
} else {
pTestCases = test_mk_time_arr_partial ;
}
for ( int i = 0 ; i < ( sizeof ( test_mk_time_arr_full ) / ( sizeof ( test_mk_time_struct ) ) ) ; i + + ) {
time_t seconds ;
bool result = _rtc_maketime ( & pTestCases [ i ] . timeinfo , & seconds , rtc_leap_year_support ) ;
TEST_ASSERT_EQUAL ( pTestCases [ i ] . result , result ) ;
/* If the result is false, then we have conversion error - skip checking seconds. */
if ( pTestCases [ i ] . result ) {
TEST_ASSERT_EQUAL_UINT32 ( pTestCases [ i ] . exp_seconds , seconds ) ;
2017-06-08 02:59:17 +00:00
}
}
}
2017-11-06 14:07:19 +00:00
/* Test _rtc_maketime() function - call with invalid parameters.
*
* Given is _rtc_maketime ( ) function .
* When _rtc_maketime ( ) function is called with invalid parameter .
* Then _rtc_maketime ( ) function returns false .
2017-06-08 02:59:17 +00:00
*/
2017-11-06 14:07:19 +00:00
void test_mk_time_invalid_param ( )
{
time_t seconds ;
struct tm timeinfo ;
TEST_ASSERT_EQUAL ( false , _rtc_maketime ( NULL , & seconds , RTC_FULL_LEAP_YEAR_SUPPORT ) ) ;
TEST_ASSERT_EQUAL ( false , _rtc_maketime ( NULL , & seconds , RTC_4_YEAR_LEAP_YEAR_SUPPORT ) ) ;
TEST_ASSERT_EQUAL ( false , _rtc_maketime ( & timeinfo , NULL , RTC_FULL_LEAP_YEAR_SUPPORT ) ) ;
TEST_ASSERT_EQUAL ( false , _rtc_maketime ( & timeinfo , NULL , RTC_4_YEAR_LEAP_YEAR_SUPPORT ) ) ;
2017-06-08 02:59:17 +00:00
}
2017-11-06 14:07:19 +00:00
/* Test _rtc_localtime() function - call with invalid parameters.
*
* Given is _rtc_localtime ( ) function .
* When _rtc_localtime ( ) function is called with invalid parameter .
* Then _rtc_localtime ( ) function returns false .
2017-06-08 02:59:17 +00:00
*/
2017-11-06 14:07:19 +00:00
void test_local_time_invalid_param ( )
{
TEST_ASSERT_EQUAL ( false , _rtc_localtime ( 1 , NULL , RTC_FULL_LEAP_YEAR_SUPPORT ) ) ;
TEST_ASSERT_EQUAL ( false , _rtc_localtime ( 1 , NULL , RTC_4_YEAR_LEAP_YEAR_SUPPORT ) ) ;
}
2017-06-08 02:59:17 +00:00
2017-11-06 14:07:19 +00:00
utest : : v1 : : status_t teardown_handler_t ( const Case * const source , const size_t passed , const size_t failed ,
const failure_t reason )
{
return greentea_case_teardown_handler ( source , passed , failed , reason ) ;
2017-06-08 02:59:17 +00:00
}
2017-11-06 14:07:19 +00:00
utest : : v1 : : status_t full_leap_year_case_setup_handler_t ( const Case * const source , const size_t index_of_case )
{
rtc_leap_year_support = RTC_FULL_LEAP_YEAR_SUPPORT ;
return greentea_case_setup_handler ( source , index_of_case ) ;
}
utest : : v1 : : status_t partial_leap_year_case_setup_handler_t ( const Case * const source , const size_t index_of_case )
{
rtc_leap_year_support = RTC_4_YEAR_LEAP_YEAR_SUPPORT ;
return greentea_case_setup_handler ( source , index_of_case ) ;
2017-06-08 02:59:17 +00:00
}
Case cases [ ] = {
2017-11-06 14:07:19 +00:00
Case ( " test is leap year - RTC leap years full support " , full_leap_year_case_setup_handler_t , test_is_leap_year , teardown_handler_t ) ,
Case ( " test is leap year - RTC leap years partial support " , partial_leap_year_case_setup_handler_t , test_is_leap_year , teardown_handler_t ) ,
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 ) ,
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 ) ,
Case ( " test make time - invalid param " , test_mk_time_invalid_param , teardown_handler_t ) ,
Case ( " test local time - invalid param " , test_local_time_invalid_param , teardown_handler_t ) ,
2017-06-08 02:59:17 +00:00
} ;
2017-11-06 14:07:19 +00:00
utest : : v1 : : status_t greentea_test_setup ( const size_t number_of_cases )
{
GREENTEA_SETUP ( 20 , " default_auto " ) ;
2017-06-08 02:59:17 +00:00
return greentea_test_setup_handler ( number_of_cases ) ;
}
Specification specification ( greentea_test_setup , cases , greentea_test_teardown_handler ) ;
2017-11-06 14:07:19 +00:00
int main ( )
{
2017-06-08 02:59:17 +00:00
return Harness : : run ( specification ) ;
}