1 /*
2  * Copyright (c) 2024 Embeint Inc
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <zephyr/zbus/zbus.h>
7 #include <zephyr/ztest.h>
8 #include <zephyr/ztest_assert.h>
9 
10 struct msg {
11 	int x;
12 };
13 
14 ZBUS_CHAN_DEFINE(chan, struct msg, NULL, NULL, ZBUS_OBSERVERS_EMPTY, ZBUS_MSG_INIT(0));
15 
ZTEST(publish_stats,test_channel_metadata)16 ZTEST(publish_stats, test_channel_metadata)
17 {
18 	k_ticks_t clock_window = CONFIG_SYS_CLOCK_TICKS_PER_SEC / 20; /* Accept +- 50ms */
19 	struct msg *cval, val = {0};
20 	k_ticks_t pub_time;
21 
22 	/* Application boot, no publishes */
23 	zassert_equal(0, zbus_chan_pub_stats_count(&chan));
24 	zassert_equal(0, zbus_chan_pub_stats_last_time(&chan));
25 	zassert_equal(0, zbus_chan_pub_stats_avg_period(&chan));
26 
27 	/* Should be no different after a second of runtime */
28 	k_sleep(K_TIMEOUT_ABS_MS(1000));
29 	zassert_equal(0, zbus_chan_pub_stats_count(&chan));
30 	zassert_equal(0, zbus_chan_pub_stats_last_time(&chan));
31 	zassert_equal(0, zbus_chan_pub_stats_avg_period(&chan));
32 
33 	/* Normal publish */
34 	zassert_equal(0, zbus_chan_pub(&chan, &val, K_NO_WAIT));
35 	zassert_equal(1, zbus_chan_pub_stats_count(&chan));
36 	zassert_within(k_uptime_ticks(), zbus_chan_pub_stats_last_time(&chan), clock_window);
37 	zassert_within(1000, zbus_chan_pub_stats_avg_period(&chan), 50);
38 
39 	/* Push 4 times in quick succession, wait for 2 second boundary */
40 	for (int i = 0; i < 4; i++) {
41 		zassert_equal(0, zbus_chan_pub(&chan, &val, K_NO_WAIT));
42 		pub_time = k_uptime_ticks();
43 	}
44 	k_sleep(K_TIMEOUT_ABS_MS(2000));
45 	zassert_equal(5, zbus_chan_pub_stats_count(&chan));
46 	zassert_within(pub_time, zbus_chan_pub_stats_last_time(&chan), clock_window);
47 	zassert_within(400, zbus_chan_pub_stats_avg_period(&chan), 50);
48 
49 	/* Channel claim and finish does not update metadata by default */
50 	zassert_equal(0, zbus_chan_claim(&chan, K_NO_WAIT));
51 	zassert_equal(0, zbus_chan_finish(&chan));
52 
53 	zassert_equal(0, zbus_chan_claim(&chan, K_NO_WAIT));
54 	cval = zbus_chan_msg(&chan);
55 	cval->x = 1000;
56 	zassert_equal(0, zbus_chan_finish(&chan));
57 	zassert_equal(5, zbus_chan_pub_stats_count(&chan));
58 	zassert_within(pub_time, zbus_chan_pub_stats_last_time(&chan), clock_window);
59 
60 	/* Channel notify does not update metadata */
61 	for (int i = 0; i < 10; i++) {
62 		zassert_equal(0, zbus_chan_notify(&chan, K_NO_WAIT));
63 	}
64 	zassert_equal(5, zbus_chan_pub_stats_count(&chan));
65 	zassert_within(pub_time, zbus_chan_pub_stats_last_time(&chan), clock_window);
66 
67 	/* Manually update publish statistics with claim */
68 	zassert_equal(0, zbus_chan_claim(&chan, K_NO_WAIT));
69 	zbus_chan_pub_stats_update(&chan);
70 	pub_time = k_uptime_ticks();
71 	zassert_equal(0, zbus_chan_finish(&chan));
72 
73 	k_sleep(K_TIMEOUT_ABS_MS(3000));
74 	zassert_equal(6, zbus_chan_pub_stats_count(&chan));
75 	zassert_within(pub_time, zbus_chan_pub_stats_last_time(&chan), clock_window);
76 	zassert_within(500, zbus_chan_pub_stats_avg_period(&chan), 50);
77 }
78 
79 ZTEST_SUITE(publish_stats, NULL, NULL, NULL, NULL, NULL);
80