blob: 6b2c4f62d9703041ad11e155de1979dda1f49c7a [file] [log] [blame]
/*
* Copyright (c) 2023 Prevas A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr/drivers/rtc.h>
#include <zephyr/drivers/rtc/rtc_fake.h>
#include <zephyr/fff.h>
#include <zephyr/shell/shell.h>
#include <zephyr/shell/shell_dummy.h>
#include <zephyr/ztest.h>
/**
* @addtogroup t_rtc_driver
* @{
* @defgroup t_rtc_api test_rtc_shell
* @}
*/
DEFINE_FFF_GLOBALS;
#define FAKE_RTC_NAME DEVICE_DT_NAME(DT_NODELABEL(fake_rtc))
/* Helper to mock time */
struct time_mock_val {
int ret_val;
struct rtc_time rtc;
};
static struct time_mock_val get_time_mock;
static struct time_mock_val set_time_mock;
static int rtc_fake_get_time_mock(const struct device *dev, struct rtc_time *rtc)
{
ARG_UNUSED(dev);
*rtc = get_time_mock.rtc;
return get_time_mock.ret_val;
}
static int rtc_fake_set_time_mock(const struct device *dev, const struct rtc_time *rtc)
{
ARG_UNUSED(dev);
set_time_mock.rtc = *rtc;
return set_time_mock.ret_val;
}
static void configure_set_time_mock(int ret_val)
{
set_time_mock.ret_val = ret_val;
rtc_fake_set_time_fake.custom_fake = rtc_fake_set_time_mock;
}
static void configure_get_time_mock(int ret_val)
{
get_time_mock.ret_val = ret_val;
get_time_mock.rtc.tm_year = 2023 - 1900; /* rtc_time year offset */
get_time_mock.rtc.tm_mon = 12 - 1; /* rtc_time month offset */
get_time_mock.rtc.tm_mday = 24;
get_time_mock.rtc.tm_hour = 12;
get_time_mock.rtc.tm_min = 34;
get_time_mock.rtc.tm_sec = 56;
rtc_fake_get_time_fake.custom_fake = rtc_fake_get_time_mock;
}
static void assert_set_time(int year, int mon, int mday, int hour, int min, int sec)
{
const struct rtc_time *rtctime;
zassert_equal(rtc_fake_set_time_fake.call_count, 1, "set_time not called");
rtctime = &set_time_mock.rtc;
zassert_equal(year, rtctime->tm_year + 1900, "Year mismatch");
zassert_equal(mon, rtctime->tm_mon + 1, "Month mismatch");
zassert_equal(mday, rtctime->tm_mday, "Day mismatch");
zassert_equal(hour, rtctime->tm_hour, "Hour mismatch");
zassert_equal(min, rtctime->tm_min, "Minute mismatch");
zassert_equal(sec, rtctime->tm_sec, "Second mismatch");
}
ZTEST(rtc_shell, test_rtc_get_ok)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
configure_get_time_mock(0);
err = shell_execute_cmd(sh, "rtc get " FAKE_RTC_NAME);
zassert_ok(err, "failed to execute shell command (err %d)", err);
zassert_equal(rtc_fake_get_time_fake.call_count, 1, "get_time not called");
}
ZTEST(rtc_shell, test_rtc_get_not_initialized)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
configure_get_time_mock(-ENODATA);
err = shell_execute_cmd(sh, "rtc get " FAKE_RTC_NAME);
zassert_ok(err, "shell command (err %d)", err);
zassert_equal(rtc_fake_get_time_fake.call_count, 1, "get_time not called");
}
ZTEST(rtc_shell, test_rtc_get_error)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
configure_get_time_mock(-1);
err = shell_execute_cmd(sh, "rtc get " FAKE_RTC_NAME);
zassert_true(err != 0, "shell command (err %d)", err);
zassert_equal(rtc_fake_get_time_fake.call_count, 1, "get_time not called");
}
ZTEST(rtc_shell, test_rtc_set_date)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
rtc_fake_set_time_fake.return_val = 0;
configure_get_time_mock(0);
configure_set_time_mock(0);
err = shell_execute_cmd(sh, "rtc set " FAKE_RTC_NAME " 2022-05-17");
zassert_ok(err, "failed to execute shell command (err %d)", err);
zassert_equal(rtc_fake_get_time_fake.call_count, 1, "get_time not called");
assert_set_time(2022, 5, 17, get_time_mock.rtc.tm_hour, get_time_mock.rtc.tm_min,
get_time_mock.rtc.tm_sec);
}
ZTEST(rtc_shell, test_rtc_set_time)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
configure_get_time_mock(0);
configure_set_time_mock(0);
err = shell_execute_cmd(sh, "rtc set " FAKE_RTC_NAME " 23:45:16");
zassert_ok(err, "failed to execute shell command (err %d)", err);
zassert_equal(rtc_fake_get_time_fake.call_count, 1, "get_time not called");
assert_set_time(2023, 12, 24, 23, 45, 16);
}
ZTEST(rtc_shell, test_rtc_set_full)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
configure_get_time_mock(0);
configure_set_time_mock(0);
err = shell_execute_cmd(sh, "rtc set " FAKE_RTC_NAME " 2022-05-17T23:45:16");
zassert_ok(err, "failed to execute shell command (err %d)", err);
zassert_equal(rtc_fake_get_time_fake.call_count, 1, "get_time not called");
assert_set_time(2022, 5, 17, 23, 45, 16);
}
ZTEST(rtc_shell, test_rtc_set_error)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
configure_get_time_mock(0);
configure_set_time_mock(-EINVAL);
err = shell_execute_cmd(sh, "rtc set " FAKE_RTC_NAME " 2022:05:17T23:45:16");
zassert_true(err != 0, "failed to execute shell command (err %d)", err);
zassert_equal(rtc_fake_get_time_fake.call_count, 1, "get_time not called");
zassert_equal(rtc_fake_set_time_fake.call_count, 0, "set_time called");
}
static void *rtc_shell_setup(void)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
/* Wait for the initialization of the shell dummy backend. */
WAIT_FOR(shell_ready(sh), 20000, k_msleep(1));
zassert_true(shell_ready(sh), "timed out waiting for dummy shell backend");
return NULL;
}
ZTEST_SUITE(rtc_shell, NULL, rtc_shell_setup, NULL, NULL, NULL);