1 /*
2 * Copyright (c) 2019 Peter Bigot Consulting, LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/sys/notify.h>
9
get_extflags(const struct sys_notify * anp)10 static uint32_t get_extflags(const struct sys_notify *anp)
11 {
12 uint32_t flags = anp->flags & SYS_NOTIFY_EXTENSION_MASK;
13
14 return flags >> SYS_NOTIFY_EXTENSION_POS;
15 }
16
set_extflags(struct sys_notify * anp,uint32_t flags)17 static void set_extflags(struct sys_notify *anp,
18 uint32_t flags)
19 {
20 anp->flags = (anp->flags & ~SYS_NOTIFY_EXTENSION_MASK)
21 | (flags << SYS_NOTIFY_EXTENSION_POS);
22 }
23
callback(struct sys_notify * anp,int * resp)24 static void callback(struct sys_notify *anp,
25 int *resp)
26 {
27 zassert_equal(sys_notify_fetch_result(anp, resp), 0,
28 "failed callback fetch");
29 }
30
ZTEST(sys_notify_api,test_validate)31 ZTEST(sys_notify_api, test_validate)
32 {
33 struct sys_notify notify = {
34 .flags = 0,
35 };
36
37 zassert_equal(sys_notify_validate(NULL), -EINVAL,
38 "accepted null pointer");
39 zassert_equal(sys_notify_validate(¬ify), -EINVAL,
40 "accepted bad method");
41 }
42
43
ZTEST(sys_notify_api,test_spinwait)44 ZTEST(sys_notify_api, test_spinwait)
45 {
46 int rc;
47 int set_res = 423;
48 int res = 0;
49 sys_notify_generic_callback cb;
50 struct sys_notify notify;
51 uint32_t xflags = 0x1234;
52
53 memset(¬ify, 0xac, sizeof(notify));
54 rc = sys_notify_validate(¬ify);
55 zassert_equal(rc, -EINVAL,
56 "invalid not diagnosed");
57
58 sys_notify_init_spinwait(¬ify);
59 rc = sys_notify_validate(¬ify);
60 zassert_equal(rc, 0,
61 "init_spinwait invalid");
62
63 zassert_false(sys_notify_uses_callback(¬ify),
64 "uses callback");
65
66 zassert_equal(notify.flags, SYS_NOTIFY_METHOD_SPINWAIT,
67 "flags mismatch");
68
69 set_extflags(¬ify, xflags);
70 zassert_equal(sys_notify_get_method(¬ify),
71 SYS_NOTIFY_METHOD_SPINWAIT,
72 "method corrupted");
73 zassert_equal(get_extflags(¬ify), xflags,
74 "xflags extract failed");
75
76 rc = sys_notify_fetch_result(¬ify, &res);
77 zassert_equal(rc, -EAGAIN,
78 "spinwait ready too soon");
79
80 zassert_not_equal(notify.flags, 0,
81 "flags cleared");
82
83 cb = sys_notify_finalize(¬ify, set_res);
84 zassert_equal(cb, (sys_notify_generic_callback)NULL,
85 "callback not null");
86 zassert_equal(notify.flags, 0,
87 "flags not cleared");
88
89 rc = sys_notify_fetch_result(¬ify, &res);
90 zassert_equal(rc, 0,
91 "spinwait not ready");
92 zassert_equal(res, set_res,
93 "result not set");
94 }
95
ZTEST(sys_notify_api,test_signal)96 ZTEST(sys_notify_api, test_signal)
97 {
98 #ifdef CONFIG_POLL
99 int rc;
100 int set_res = 423;
101 int res;
102 struct k_poll_signal sig;
103 sys_notify_generic_callback cb;
104 struct sys_notify notify;
105 uint32_t xflags = 0x1234;
106
107 memset(¬ify, 0xac, sizeof(notify));
108 rc = sys_notify_validate(¬ify);
109 zassert_equal(rc, -EINVAL,
110 "invalid not diagnosed");
111
112 k_poll_signal_init(&sig);
113 k_poll_signal_check(&sig, &rc, &res);
114 zassert_equal(rc, 0,
115 "signal set");
116
117 sys_notify_init_signal(¬ify, &sig);
118 notify.method.signal = NULL;
119 rc = sys_notify_validate(¬ify);
120 zassert_equal(rc, -EINVAL,
121 "null signal not invalid");
122
123 memset(¬ify, 0xac, sizeof(notify));
124 sys_notify_init_signal(¬ify, &sig);
125 rc = sys_notify_validate(¬ify);
126 zassert_equal(rc, 0,
127 "init_spinwait invalid");
128
129 zassert_false(sys_notify_uses_callback(¬ify),
130 "uses callback");
131
132 zassert_equal(notify.flags, SYS_NOTIFY_METHOD_SIGNAL,
133 "flags mismatch");
134 zassert_equal(notify.method.signal, &sig,
135 "signal pointer mismatch");
136
137 set_extflags(¬ify, xflags);
138 zassert_equal(sys_notify_get_method(¬ify),
139 SYS_NOTIFY_METHOD_SIGNAL,
140 "method corrupted");
141 zassert_equal(get_extflags(¬ify), xflags,
142 "xflags extract failed");
143
144 rc = sys_notify_fetch_result(¬ify, &res);
145 zassert_equal(rc, -EAGAIN,
146 "spinwait ready too soon");
147
148 zassert_not_equal(notify.flags, 0,
149 "flags cleared");
150
151 cb = sys_notify_finalize(¬ify, set_res);
152 zassert_equal(cb, (sys_notify_generic_callback)NULL,
153 "callback not null");
154 zassert_equal(notify.flags, 0,
155 "flags not cleared");
156 k_poll_signal_check(&sig, &rc, &res);
157 zassert_equal(rc, 1,
158 "signal not set");
159 zassert_equal(res, set_res,
160 "signal result wrong");
161
162 rc = sys_notify_fetch_result(¬ify, &res);
163 zassert_equal(rc, 0,
164 "signal not ready");
165 zassert_equal(res, set_res,
166 "result not set");
167 #endif /* CONFIG_POLL */
168 }
169
ZTEST(sys_notify_api,test_callback)170 ZTEST(sys_notify_api, test_callback)
171 {
172 int rc;
173 int set_res = 423;
174 int res;
175 sys_notify_generic_callback cb;
176 struct sys_notify notify;
177 uint32_t xflags = 0x8765432;
178
179 memset(¬ify, 0xac, sizeof(notify));
180 rc = sys_notify_validate(¬ify);
181 zassert_equal(rc, -EINVAL,
182 "invalid not diagnosed");
183
184 sys_notify_init_callback(¬ify, callback);
185 notify.method.callback = NULL;
186 rc = sys_notify_validate(¬ify);
187 zassert_equal(rc, -EINVAL,
188 "null callback not invalid");
189
190 memset(¬ify, 0xac, sizeof(notify));
191 sys_notify_init_callback(¬ify, callback);
192 rc = sys_notify_validate(¬ify);
193 zassert_equal(rc, 0,
194 "init_spinwait invalid");
195
196 zassert_true(sys_notify_uses_callback(¬ify),
197 "not using callback");
198
199 zassert_equal(notify.flags, SYS_NOTIFY_METHOD_CALLBACK,
200 "flags mismatch");
201 zassert_equal(notify.method.callback,
202 (sys_notify_generic_callback)callback,
203 "callback mismatch");
204
205 set_extflags(¬ify, xflags);
206 zassert_equal(sys_notify_get_method(¬ify),
207 SYS_NOTIFY_METHOD_CALLBACK,
208 "method corrupted");
209 zassert_equal(get_extflags(¬ify), xflags,
210 "xflags extract failed");
211
212 rc = sys_notify_fetch_result(¬ify, &res);
213 zassert_equal(rc, -EAGAIN,
214 "callback ready too soon");
215
216 zassert_not_equal(notify.flags, 0,
217 "flags cleared");
218
219 cb = sys_notify_finalize(¬ify, set_res);
220 zassert_equal(cb, (sys_notify_generic_callback)callback,
221 "callback wrong");
222 zassert_equal(notify.flags, 0,
223 "flags not cleared");
224
225 res = ~set_res;
226 ((sys_notify_generic_callback)cb)(¬ify, &res);
227 zassert_equal(res, set_res,
228 "result not set");
229 }
230
231 ZTEST_SUITE(sys_notify_api, NULL, NULL, NULL, NULL, NULL);
232