2017-11-06 14:07:19 +00:00
/*
* Copyright ( c ) 2013 - 2016 , ARM Limited , All Rights Reserved
* SPDX - License - Identifier : Apache - 2.0
*
* 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 .
*/
/*
* This is the mbed device part of the test to verify if :
* - _rtc_maketime ( ) function converts a calendar time into time since UNIX epoch as a time_t ,
* - _rtc_localtime ( ) function converts a given time in seconds since epoch into calendar time .
*/
# include "mbed.h"
# include "greentea-client/test_env.h"
# include "utest/utest.h"
# include "unity/unity.h"
# include "mbed_mktime.h"
# define LAST_VALID_YEAR 206
using namespace utest : : v1 ;
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 )
{
year = 1900 + year ;
if ( year % 4 ) {
return false ;
} else if ( year % 100 ) {
return true ;
} else if ( year % 400 ) {
return false ;
}
return true ;
}
struct tm make_time_info ( int year , int month , int day , int hours , int minutes , int seconds )
{
2018-07-27 09:17:07 +00:00
struct tm timeinfo = {
seconds , // tm_sec
2017-11-06 14:07:19 +00:00
minutes , // tm_min
hours , // tm_hour
day , // tm_mday
month , // tm_mon
year , // tm_year
0 , // tm_wday
0 , // tm_yday
0 , // tm_isdst
2018-07-27 09:17:07 +00:00
} ;
2017-11-06 14:07:19 +00:00
return timeinfo ;
}
/* Test _rtc_maketime() and _rtc_localtime() across wide range
*
* Note : This test functions handles both types of RTC devices :
* - devices which supports full leap years support in range 1970 - 2106.
* - devices which supports parial leap years support and incorrectly treats 2100 year as a leap year .
*
* Given is valid calendar time .
* When _rtc_maketime ( ) is used to generate timestamp from calendar time and _rtc_localtime ( ) is used to convert
* timestamp to calendar time .
* Then both operations gives valid results .
*/
void test_case_mktime_localtime ( )
{
char _key [ 11 ] =
2018-07-27 09:17:07 +00:00
{ } ;
2017-11-06 14:07:19 +00:00
char _value [ 128 ] =
2018-07-27 09:17:07 +00:00
{ } ;
2017-11-06 14:07:19 +00:00
2018-01-08 09:14:54 +00:00
size_t years [ ] = { 70 , 71 , 100 , 196 , 200 , 205 } ;
2017-11-06 14:07:19 +00:00
/* Inform host part of the test about tested RTC type. */
greentea_send_kv ( " leap_year_setup " , rtc_leap_year_support ) ;
/* Check the first and last last day of each month. */
2018-07-27 09:17:07 +00:00
for ( size_t year_id = 0 ; year_id < ( sizeof ( years ) / sizeof ( size_t ) ) ; + + year_id ) {
2017-11-06 14:07:19 +00:00
for ( size_t month = 0 ; month < 12 ; + + month ) {
for ( size_t dayid = 0 ; dayid < 2 ; + + dayid ) {
size_t year = years [ year_id ] ;
size_t day = 0 ;
/* Test the first and the last day of each month:
* day 0 - first ,
* day 1 - last
* */
2018-07-27 09:17:07 +00:00
switch ( dayid ) {
2017-11-06 14:07:19 +00:00
case 0 :
day = 1 ;
break ;
case 1 :
day = 31 ;
if ( month = = 3 | | month = = 5 | | month = = 8 | | month = = 10 ) {
day = 30 ;
}
if ( month = = 1 ) {
day = 28 ;
}
if ( month = = 1 & & is_leap_year ( year ) ) {
day = 29 ;
}
/* Additional conditions for RTCs with partial leap year support. */
2018-07-27 09:17:07 +00:00
if ( month = = 1 & & year = = 200 & & rtc_leap_year_support = = RTC_4_YEAR_LEAP_YEAR_SUPPORT ) {
2017-11-06 14:07:19 +00:00
day = 29 ;
}
break ;
default :
break ;
}
tm time_info = make_time_info ( year , month , day , 23 , dayid ? 59 : 0 , dayid ? 59 : 0 ) ;
time_t actual_timestamp ;
TEST_ASSERT_TRUE ( _rtc_maketime ( & time_info , & actual_timestamp , rtc_leap_year_support ) ) ;
greentea_send_kv ( " timestamp " , ( int ) actual_timestamp ) ;
greentea_parse_kv ( _key , _value , sizeof ( _key ) , sizeof ( _value ) ) ;
TEST_ASSERT_EQUAL_STRING ( " passed " , _key ) ;
/* Response which indicates success contains encoded week day
* and year day needed to verify _rtc_localtime ( ) .
* Use validated timestamp to generate and validate calendar time .
*/
unsigned int buf = ( unsigned int ) strtol ( _value , NULL , 10 ) ;
time_info . tm_wday = ( ( buf > > 16 ) & 0x0000FFFF ) ;
time_info . tm_yday = ( buf & 0x0000FFFF ) ;
tm actual_time_info ;
bool result = _rtc_localtime ( ( time_t ) actual_timestamp , & actual_time_info , rtc_leap_year_support ) ;
TEST_ASSERT_TRUE ( result ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_sec , actual_time_info . tm_sec , " invalid seconds " ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_min , actual_time_info . tm_min , " invalid minutes " ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_hour , actual_time_info . tm_hour , " invalid hours " ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_mday , actual_time_info . tm_mday , " invalid day " ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_mon , actual_time_info . tm_mon , " invalid month " ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_year , actual_time_info . tm_year , " invalid year " ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_wday , actual_time_info . tm_wday , " invalid weekday " ) ;
TEST_ASSERT_EQUAL_UINT32_MESSAGE ( time_info . tm_yday , actual_time_info . tm_yday , " invalid year day " ) ;
}
}
}
}
2018-07-27 09:17:07 +00:00
utest : : v1 : : status_t full_leap_year_case_setup_handler_t ( const Case * const source , const size_t index_of_case )
2017-11-06 14:07:19 +00:00
{
rtc_leap_year_support = RTC_FULL_LEAP_YEAR_SUPPORT ;
return greentea_case_setup_handler ( source , index_of_case ) ;
}
2018-07-27 09:17:07 +00:00
utest : : v1 : : status_t partial_leap_year_case_setup_handler_t ( const Case * const source , const size_t index_of_case )
2017-11-06 14:07:19 +00:00
{
rtc_leap_year_support = RTC_4_YEAR_LEAP_YEAR_SUPPORT ;
return greentea_case_setup_handler ( source , index_of_case ) ;
}
2018-07-27 09:17:07 +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 )
2017-11-06 14:07:19 +00:00
{
return greentea_case_teardown_handler ( source , passed , failed , reason ) ;
}
// Test cases
2018-07-27 09:17:07 +00:00
Case cases [ ] = {
Case ( " test make time and local time - RTC leap years full support " , full_leap_year_case_setup_handler_t , test_case_mktime_localtime , teardown_handler_t ) ,
Case ( " test make time and local time - RTC leap years partial support " , partial_leap_year_case_setup_handler_t , test_case_mktime_localtime , teardown_handler_t ) ,
2017-11-06 14:07:19 +00:00
} ;
utest : : v1 : : status_t greentea_test_setup ( const size_t number_of_cases )
{
GREENTEA_SETUP ( 300 , " rtc_calc_auto " ) ;
return greentea_test_setup_handler ( number_of_cases ) ;
}
Specification specification ( greentea_test_setup , cases , greentea_test_teardown_handler ) ;
int main ( )
{
Harness : : run ( specification ) ;
}