/* * Copyright (c) 2023 Prevas A/S * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include /** * @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);