Feature/date time mstimer clock (#861)
* Added daylight savings time calculation module with unit testing. * Added datetime daylight savings time and clock API * Added basic datetime_local() clock using mstimer as basis and time-sync option. Integrated clock with ports/stm32f4xx example.
This commit is contained in:
@@ -171,6 +171,7 @@ list(APPEND testdirs
|
||||
# basic/sys
|
||||
bacnet/basic/sys/color_rgb
|
||||
bacnet/basic/sys/days
|
||||
bacnet/basic/sys/dst
|
||||
bacnet/basic/sys/lighting_command
|
||||
bacnet/basic/sys/fifo
|
||||
bacnet/basic/sys/filename
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
/* @file
|
||||
* @brief test BACnet integer encode/decode APIs
|
||||
* @date June 2022
|
||||
* @brief tests sRGB to and from from CIE xy and brightness API
|
||||
*
|
||||
* @section LICENSE
|
||||
* Copyright (c) 2022 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* @date June 2022
|
||||
* @author Steve Karg <Steve Karg <skarg@users.sourceforge.net>
|
||||
* @copyright SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* @file
|
||||
* @brief test BACnet integer encode/decode APIs
|
||||
* @brief tests day of year calculations API
|
||||
* @date August 2021
|
||||
* @author Steve Karg <Steve Karg <skarg@users.sourceforge.net>
|
||||
* @copyright SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <zephyr/ztest.h>
|
||||
#include <bacnet/basic/sys/days.h>
|
||||
|
||||
/* define our epic beginnings */
|
||||
#define BACNET_EPOCH_YEAR 1900
|
||||
/* 1/1/1900 is a Monday */
|
||||
/* Monday=1..Sunday=7 */
|
||||
#define BACNET_EPOCH_DOW 1
|
||||
|
||||
/**
|
||||
* @addtogroup bacnet_tests
|
||||
* @{
|
||||
@@ -31,9 +33,43 @@ static void test_epoch_conversion_date(
|
||||
days = days_since_epoch(epoch_year, year, month, day);
|
||||
days_since_epoch_to_date(
|
||||
epoch_year, days, &test_year, &test_month, &test_day);
|
||||
zassert_equal(year, test_year, NULL);
|
||||
zassert_equal(month, test_month, NULL);
|
||||
zassert_equal(day, test_day, NULL);
|
||||
zassert_equal(
|
||||
year, test_year, "date=%u/%u/%u year=%u test_year=%u", year, month, day,
|
||||
year, test_year);
|
||||
zassert_equal(
|
||||
month, test_month, "date=%u/%u/%u month=%u test_month=%u", year, month,
|
||||
day, month, test_month);
|
||||
zassert_equal(
|
||||
day, test_day, "date=%u/%u/%u day=%u test_day=%u", year, month, day,
|
||||
day, test_day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit Test for the day of week based on epoch year and epoch day of week
|
||||
* @param epoch_year - years after Christ birth (0..9999 AD)
|
||||
* @param epoch_dow - day of week (1=Monday...7=Sunday)
|
||||
* @param year - years after Christ birth (0..9999 AD)
|
||||
* @param month - months (1=Jan...12=Dec)
|
||||
* @param day - day of month (1-31)
|
||||
* @param dow - day of week (1=Monday...7=Sunday)
|
||||
*/
|
||||
static void test_epoch_conversion_day(
|
||||
uint16_t epoch_year,
|
||||
uint8_t epoch_dow,
|
||||
uint16_t year,
|
||||
uint8_t month,
|
||||
uint8_t day,
|
||||
uint8_t dow)
|
||||
{
|
||||
uint32_t days;
|
||||
uint16_t test_dow;
|
||||
|
||||
/* conversions of day and date */
|
||||
days = days_since_epoch(epoch_year, year, month, day);
|
||||
test_dow = days_of_week(epoch_dow, days);
|
||||
zassert_equal(
|
||||
dow, test_dow, "date=%u/%u/%u dow=%u test_dow=%u", year, month, day,
|
||||
dow, test_dow);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,13 +81,28 @@ ZTEST(days_tests, test_days_epoch_conversion)
|
||||
static void test_days_epoch_conversion(void)
|
||||
#endif
|
||||
{
|
||||
const uint16_t epoch_year = 2000;
|
||||
const uint16_t epoch_year = BACNET_EPOCH_YEAR;
|
||||
const uint8_t epoch_day_of_week = BACNET_EPOCH_DOW;
|
||||
|
||||
test_epoch_conversion_date(epoch_year, 2000, 1, 1);
|
||||
test_epoch_conversion_date(epoch_year, 2048, 2, 28);
|
||||
test_epoch_conversion_date(epoch_year, 2048, 2, 29);
|
||||
test_epoch_conversion_date(epoch_year, 2038, 6, 15);
|
||||
test_epoch_conversion_date(epoch_year, 9999, 12, 31);
|
||||
|
||||
test_epoch_conversion_day(
|
||||
epoch_year, epoch_day_of_week, epoch_year, 1, 1, epoch_day_of_week);
|
||||
/* some known day of week (1=Monday...7=Sunday) */
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 6, 1);
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 7, 2);
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 8, 3);
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 9, 4);
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 10, 5);
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 11, 6);
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 12, 7);
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2003, 1, 13, 1);
|
||||
/* 50th wedding anniversary */
|
||||
test_epoch_conversion_day(epoch_year, epoch_day_of_week, 2043, 6, 26, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,6 +185,42 @@ static void test_days_date_is_valid(void)
|
||||
zassert_equal(days_per_month(0, 0), 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit Test for the days, checking the date to see if it is a valid date
|
||||
*/
|
||||
#if defined(CONFIG_ZTEST_NEW_API)
|
||||
ZTEST(days_tests, test_days_since_epoch)
|
||||
#else
|
||||
static void test_days_since_epoch(void)
|
||||
#endif
|
||||
{
|
||||
uint32_t days = 0;
|
||||
uint16_t year = 0, test_year = 0;
|
||||
uint8_t month = 0, test_month = 0;
|
||||
uint8_t day = 0, test_day = 0;
|
||||
|
||||
days = days_since_epoch(BACNET_EPOCH_YEAR, BACNET_EPOCH_YEAR, 1, 1);
|
||||
zassert_equal(days, 0, "days=%lu", (unsigned long)days);
|
||||
days_since_epoch_to_date(BACNET_EPOCH_YEAR, days, &year, &month, &day);
|
||||
zassert_equal(year, BACNET_EPOCH_YEAR, NULL);
|
||||
zassert_equal(month, 1, NULL);
|
||||
zassert_equal(day, 1, NULL);
|
||||
|
||||
for (year = BACNET_EPOCH_YEAR; year < (BACNET_EPOCH_YEAR + 0xFF); year++) {
|
||||
for (month = 1; month <= 12; month++) {
|
||||
for (day = 1; day <= days_per_month(year, month); day++) {
|
||||
days = days_since_epoch(BACNET_EPOCH_YEAR, year, month, day);
|
||||
days_since_epoch_to_date(
|
||||
BACNET_EPOCH_YEAR, days, &test_year, &test_month,
|
||||
&test_day);
|
||||
zassert_equal(year, test_year, NULL);
|
||||
zassert_equal(month, test_month, NULL);
|
||||
zassert_equal(day, test_day, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit Test for days apart, checking the dates to see how many days apart
|
||||
*/
|
||||
@@ -162,6 +249,7 @@ void test_main(void)
|
||||
{
|
||||
ztest_test_suite(
|
||||
days_tests, ztest_unit_test(test_days_epoch_conversion),
|
||||
ztest_unit_test(test_days_since_epoch),
|
||||
ztest_unit_test(test_days_of_year_to_md),
|
||||
ztest_unit_test(test_days_date_is_valid),
|
||||
ztest_unit_test(test_days_apart));
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
||||
|
||||
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
project(test_${basename}
|
||||
VERSION 1.0.0
|
||||
LANGUAGES C)
|
||||
|
||||
|
||||
string(REGEX REPLACE
|
||||
"/test/bacnet/[a-zA-Z_/-]*$"
|
||||
"/src"
|
||||
SRC_DIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
string(REGEX REPLACE
|
||||
"/test/bacnet/[a-zA-Z_/-]*$"
|
||||
"/test"
|
||||
TST_DIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(ZTST_DIR "${TST_DIR}/ztest/src")
|
||||
|
||||
add_compile_definitions(
|
||||
BIG_ENDIAN=0
|
||||
CONFIG_ZTEST=1
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${SRC_DIR}
|
||||
${TST_DIR}/ztest/include
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
# File(s) under test
|
||||
${SRC_DIR}/bacnet/basic/sys/dst.c
|
||||
# Support files and stubs (pathname alphabetical)
|
||||
${SRC_DIR}/bacnet/basic/sys/days.c
|
||||
# Test and test library files
|
||||
./src/main.c
|
||||
${ZTST_DIR}/ztest_mock.c
|
||||
${ZTST_DIR}/ztest.c
|
||||
)
|
||||
@@ -0,0 +1,137 @@
|
||||
/* @file
|
||||
* @brief tests daylight savings time validity API
|
||||
* @date August 2021
|
||||
* @author Steve Karg <Steve Karg <skarg@users.sourceforge.net>
|
||||
* @copyright SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include <zephyr/ztest.h>
|
||||
#include <bacnet/basic/sys/dst.h>
|
||||
|
||||
/**
|
||||
* @addtogroup bacnet_tests
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unit Test for daylight savings time
|
||||
*/
|
||||
#if defined(CONFIG_ZTEST_NEW_API)
|
||||
ZTEST(dst_tests, dst_test_valid)
|
||||
#else
|
||||
static void dst_test_valid(void)
|
||||
#endif
|
||||
{
|
||||
struct daylight_savings_data data = { 0 };
|
||||
uint8_t epoch_day;
|
||||
uint16_t epoch_year;
|
||||
/* test at 3am */
|
||||
uint8_t hour = 3;
|
||||
uint8_t minute = 0;
|
||||
uint8_t second = 0;
|
||||
bool active;
|
||||
|
||||
unsigned i;
|
||||
struct dst_test_data {
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
bool active;
|
||||
} test_ordinal_data[] = {
|
||||
/* start date boundary checking for several years */
|
||||
{ 2007, 3, 10, false },
|
||||
{ 2007, 3, 11, true },
|
||||
{ 2008, 3, 8, false },
|
||||
{ 2008, 3, 9, true },
|
||||
{ 2009, 3, 7, false },
|
||||
{ 2009, 3, 8, true },
|
||||
{ 2010, 3, 13, false },
|
||||
{ 2010, 3, 14, true },
|
||||
{ 2011, 3, 12, false },
|
||||
{ 2011, 3, 13, true },
|
||||
{ 2012, 3, 10, false },
|
||||
{ 2012, 3, 11, true },
|
||||
{ 2013, 3, 9, false },
|
||||
{ 2013, 3, 10, true },
|
||||
{ 2014, 3, 8, false },
|
||||
{ 2014, 3, 9, true },
|
||||
{ 2015, 3, 7, false },
|
||||
{ 2015, 3, 8, true },
|
||||
/* end date boundary checking for several years */
|
||||
{ 2007, 11, 3, true },
|
||||
{ 2007, 11, 4, false },
|
||||
{ 2008, 11, 1, true },
|
||||
{ 2008, 11, 2, false },
|
||||
{ 2009, 10, 31, true },
|
||||
{ 2009, 11, 1, false },
|
||||
{ 2010, 11, 6, true },
|
||||
{ 2010, 11, 7, false },
|
||||
{ 2011, 11, 5, true },
|
||||
{ 2011, 11, 6, false },
|
||||
{ 2012, 11, 3, true },
|
||||
{ 2012, 11, 4, false },
|
||||
{ 2013, 11, 2, true },
|
||||
{ 2013, 11, 3, false },
|
||||
{ 2014, 11, 1, true },
|
||||
{ 2014, 11, 2, false },
|
||||
{ 2015, 10, 31, true },
|
||||
{ 2015, 11, 1, false },
|
||||
/* year long check boundaries over a year */
|
||||
{ 2013, 1, 1, false },
|
||||
{ 2013, 3, 3, false },
|
||||
{ 2013, 3, 7, false },
|
||||
{ 2013, 3, 8, false },
|
||||
{ 2013, 3, 9, false },
|
||||
{ 2013, 3, 10, true },
|
||||
{ 2013, 3, 11, true },
|
||||
{ 2013, 3, 12, true },
|
||||
{ 2013, 7, 10, true },
|
||||
{ 2013, 11, 2, true },
|
||||
{ 2013, 11, 3, false },
|
||||
{ 2013, 11, 4, false },
|
||||
{ 2013, 11, 7, false },
|
||||
{ 2013, 11, 8, false },
|
||||
{ 2013, 11, 30, false },
|
||||
{ 2013, 12, 31, false },
|
||||
};
|
||||
struct dst_test_data *td;
|
||||
|
||||
dst_init_defaults(&data);
|
||||
for (i = 0; i < ARRAY_SIZE(test_ordinal_data); i++) {
|
||||
td = &test_ordinal_data[i];
|
||||
active = dst_active(
|
||||
&data, td->year, td->month, td->day, hour, minute, second);
|
||||
zassert_true(active == td->active, NULL);
|
||||
}
|
||||
/* test the fixed dates */
|
||||
epoch_day = data.Epoch_Day;
|
||||
epoch_year = data.Epoch_Year;
|
||||
dst_init(&data, false, 4, 1, 0, 9, 30, 0, epoch_day, epoch_year);
|
||||
/* check the boundaries */
|
||||
active = dst_active(&data, 2013, 3, 31, hour, minute, second);
|
||||
zassert_true(active == false, NULL);
|
||||
active = dst_active(&data, 2013, 4, 1, hour, minute, second);
|
||||
zassert_true(active == true, NULL);
|
||||
active = dst_active(&data, 2013, 4, 2, hour, minute, second);
|
||||
zassert_true(active == true, NULL);
|
||||
active = dst_active(&data, 2013, 9, 29, hour, minute, second);
|
||||
zassert_true(active == true, NULL);
|
||||
active = dst_active(&data, 2013, 9, 30, hour, minute, second);
|
||||
zassert_true(active == false, NULL);
|
||||
active = dst_active(&data, 2013, 10, 1, hour, minute, second);
|
||||
zassert_true(active == false, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ZTEST_NEW_API)
|
||||
ZTEST_SUITE(dst_tests, NULL, NULL, NULL, NULL, NULL);
|
||||
#else
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(dst_tests, ztest_unit_test(dst_test_valid));
|
||||
|
||||
ztest_run_test_suite(dst_tests);
|
||||
}
|
||||
#endif
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
/* define our epic beginnings */
|
||||
#define BACNET_EPOCH_YEAR 1900
|
||||
/* 1/1/1900 is a Monday */
|
||||
#define BACNET_EPOCH_DOW BACNET_WEEKDAY_MONDAY
|
||||
|
||||
/**
|
||||
* @addtogroup bacnet_tests
|
||||
@@ -423,35 +421,6 @@ static void testDateEpochConversion(void)
|
||||
BACNET_EPOCH_YEAR + 0xFF - 1, 12, 31, 23, 59, 59, 0);
|
||||
}
|
||||
|
||||
static void testDateEpoch(void)
|
||||
{
|
||||
uint32_t days = 0;
|
||||
uint16_t year = 0, test_year = 0;
|
||||
uint8_t month = 0, test_month = 0;
|
||||
uint8_t day = 0, test_day = 0;
|
||||
|
||||
days = days_since_epoch(BACNET_EPOCH_YEAR, BACNET_EPOCH_YEAR, 1, 1);
|
||||
zassert_equal(days, 1, "days=%lu", (unsigned long)days);
|
||||
days_since_epoch_to_date(BACNET_EPOCH_YEAR, days, &year, &month, &day);
|
||||
zassert_equal(year, BACNET_EPOCH_YEAR, NULL);
|
||||
zassert_equal(month, 1, NULL);
|
||||
zassert_equal(day, 1, NULL);
|
||||
|
||||
for (year = BACNET_EPOCH_YEAR; year < (BACNET_EPOCH_YEAR + 0xFF); year++) {
|
||||
for (month = 1; month <= 12; month++) {
|
||||
for (day = 1; day <= days_per_month(year, month); day++) {
|
||||
days = days_since_epoch(BACNET_EPOCH_YEAR, year, month, day);
|
||||
days_since_epoch_to_date(
|
||||
BACNET_EPOCH_YEAR, days, &test_year, &test_month,
|
||||
&test_day);
|
||||
zassert_equal(year, test_year, NULL);
|
||||
zassert_equal(month, test_month, NULL);
|
||||
zassert_equal(day, test_day, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ZTEST_NEW_API)
|
||||
ZTEST(bacnet_datetime, testBACnetDayOfWeek)
|
||||
#else
|
||||
@@ -641,11 +610,6 @@ ZTEST_SUITE(bacnet_datetime, NULL, NULL, NULL, NULL, NULL);
|
||||
#else
|
||||
void test_main(void)
|
||||
{
|
||||
#if 0
|
||||
ztest_unit_test(testDateEpoch),
|
||||
ztest_unit_test(testBACnetDateTimeSeconds),
|
||||
ztest_unit_test(testDayOfYear),
|
||||
#endif
|
||||
ztest_test_suite(
|
||||
bacnet_datetime, ztest_unit_test(testBACnetDate),
|
||||
ztest_unit_test(testBACnetTime), ztest_unit_test(testBACnetDateTime),
|
||||
@@ -654,7 +618,7 @@ void test_main(void)
|
||||
ztest_unit_test(testBACnetDateTimeAdd),
|
||||
ztest_unit_test(testBACnetDateTimeWildcard),
|
||||
ztest_unit_test(testDatetimeCodec),
|
||||
ztest_unit_test(testWildcardDateTime), ztest_unit_test(testDateEpoch),
|
||||
ztest_unit_test(testWildcardDateTime),
|
||||
ztest_unit_test(testBACnetDateTimeSeconds),
|
||||
ztest_unit_test(testDayOfYear),
|
||||
ztest_unit_test(testDatetimeConvertUTC));
|
||||
|
||||
Reference in New Issue
Block a user