Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * testing of some tevent_req aspects
5 : *
6 : * Copyright (C) Volker Lendecke 2018
7 : *
8 : * ** NOTE! The following LGPL license applies to the tevent
9 : * ** library. This does NOT imply that all of Samba is released
10 : * ** under the LGPL
11 : *
12 : * This library is free software; you can redistribute it and/or
13 : * modify it under the terms of the GNU Lesser General Public
14 : * License as published by the Free Software Foundation; either
15 : * version 3 of the License, or (at your option) any later version.
16 : *
17 : * This library is distributed in the hope that it will be useful,
18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 : * Lesser General Public License for more details.
21 : *
22 : * You should have received a copy of the GNU Lesser General Public
23 : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 : */
25 :
26 : #include "includes.h"
27 : #include "tevent.h"
28 : #include "torture/torture.h"
29 : #include "torture/local/proto.h"
30 : #include "lib/util/tevent_unix.h"
31 : #include "lib/util/tevent_req_profile.h"
32 : #include "lib/util/time_basic.h"
33 :
34 : struct tevent_req_create_state {
35 : uint8_t val;
36 : };
37 :
38 0 : static bool test_tevent_req_create(struct torture_context *tctx,
39 : const void *test_data)
40 : {
41 : struct tevent_req *req;
42 : struct tevent_req_create_state *state;
43 :
44 0 : req = tevent_req_create(tctx, &state,
45 : struct tevent_req_create_state);
46 0 : torture_assert_not_null(tctx, req, "tevent_req_create failed\n");
47 0 : torture_assert_int_equal(tctx, state->val, 0, "state not initialized\n");
48 :
49 0 : TALLOC_FREE(req);
50 :
51 0 : return true;
52 : }
53 :
54 : struct profile1_state {
55 : uint8_t dummy;
56 : };
57 :
58 0 : static bool test_tevent_req_profile1(struct torture_context *tctx,
59 : const void *test_data)
60 : {
61 : struct tevent_req *req;
62 : struct profile1_state *state;
63 : const struct tevent_req_profile *p1;
64 : struct tevent_req_profile *p2;
65 : struct timeval start, stop;
66 : bool ok;
67 : int cmp;
68 :
69 0 : req = tevent_req_create(tctx, &state, struct profile1_state);
70 0 : torture_assert_not_null(tctx, req, "tevent_req_create failed\n");
71 :
72 0 : p1 = tevent_req_get_profile(req);
73 0 : torture_assert(tctx, p1 == NULL, "profile not initialized to NULL\n");
74 :
75 0 : ok = tevent_req_set_profile(req);
76 0 : torture_assert(tctx, ok, "set_profile failed\n");
77 :
78 0 : tevent_req_done(req);
79 :
80 0 : p2 = tevent_req_move_profile(req, tctx);
81 0 : torture_assert_not_null(tctx, p2, "get_profile failed\n");
82 :
83 : /* Demonstrate sure "p2" outlives req */
84 0 : TALLOC_FREE(req);
85 :
86 0 : tevent_req_profile_get_start(p2, NULL, &start);
87 0 : tevent_req_profile_get_stop(p2, NULL, &stop);
88 :
89 0 : cmp = tevent_timeval_compare(&start, &stop);
90 0 : torture_assert(tctx, cmp <= 0, "stop before start\n");
91 :
92 0 : TALLOC_FREE(p2);
93 :
94 0 : return true;
95 : }
96 :
97 : struct profile2_state {
98 : uint8_t dummy;
99 : };
100 :
101 : static void profile2_done(struct tevent_req *subreq);
102 :
103 0 : static struct tevent_req *profile2_send(TALLOC_CTX *mem_ctx,
104 : struct tevent_context *ev)
105 : {
106 : struct tevent_req *req, *subreq;
107 : struct profile2_state *state;
108 : bool ok;
109 :
110 0 : req = tevent_req_create(mem_ctx, &state, struct profile2_state);
111 0 : if (req == NULL) {
112 0 : return NULL;
113 : }
114 :
115 0 : ok = tevent_req_set_profile(req);
116 0 : if (!ok) {
117 0 : return tevent_req_post(req, ev);
118 : }
119 :
120 0 : subreq = tevent_wakeup_send(
121 : state,
122 : ev,
123 : tevent_timeval_current_ofs(0, 1));
124 0 : if (tevent_req_nomem(subreq, req)) {
125 0 : return tevent_req_post(req, ev);
126 : }
127 0 : tevent_req_set_callback(subreq, profile2_done, req);
128 :
129 0 : return req;
130 : }
131 :
132 0 : static void profile2_done(struct tevent_req *subreq)
133 : {
134 0 : struct tevent_req *req = tevent_req_callback_data(
135 : subreq, struct tevent_req);
136 : bool ok;
137 :
138 0 : ok = tevent_wakeup_recv(subreq);
139 0 : if (!ok) {
140 0 : tevent_req_oom(req);
141 0 : return;
142 : }
143 0 : tevent_req_done(req);
144 : }
145 :
146 0 : static int profile2_recv(struct tevent_req *req,
147 : TALLOC_CTX *mem_ctx,
148 : struct tevent_req_profile **profile)
149 : {
150 : int err;
151 :
152 0 : if (tevent_req_is_unix_error(req, &err)) {
153 0 : return err;
154 : }
155 :
156 0 : *profile = tevent_req_move_profile(req, mem_ctx);
157 :
158 0 : return 0;
159 : }
160 :
161 0 : static bool test_tevent_req_profile2(struct torture_context *tctx,
162 : const void *test_data)
163 : {
164 : struct tevent_context *ev;
165 : struct tevent_req *req;
166 0 : struct tevent_req_profile *p1 = NULL;
167 0 : struct tevent_req_profile *p2 = NULL;
168 : const char *str1, *str2;
169 : struct timeval tv1, tv2;
170 : pid_t pid1, pid2;
171 : enum tevent_req_state state1, state2;
172 : uint64_t err1, err2;
173 : char *printstring;
174 : ssize_t pack_len;
175 : int err;
176 : bool ok;
177 :
178 0 : ev = samba_tevent_context_init(tctx);
179 0 : torture_assert_not_null(tctx, ev, "samba_tevent_context_init failed\n");
180 :
181 0 : req = profile2_send(tctx, ev);
182 0 : torture_assert_not_null(tctx, req, "profile2_send failed\n");
183 :
184 0 : ok = tevent_req_poll_unix(req, ev, &err);
185 0 : torture_assert(tctx, ok, "tevent_req_poll_unix failed\n");
186 :
187 0 : err = profile2_recv(req, tctx, &p1);
188 0 : torture_assert_int_equal(tctx, err, 0, "profile2_recv failed\n");
189 :
190 0 : TALLOC_FREE(req);
191 0 : TALLOC_FREE(ev);
192 :
193 0 : printstring = tevent_req_profile_string(tctx, p1, 0, UINT_MAX);
194 0 : torture_assert_not_null(
195 : tctx,
196 : printstring,
197 : "tevent_req_profile_string failed\n");
198 0 : printf("%s\n", printstring);
199 :
200 0 : pack_len = tevent_req_profile_pack(p1, NULL, 0);
201 0 : torture_assert(tctx, pack_len>0, "profile_pack failed\n");
202 :
203 0 : {
204 0 : uint8_t buf[pack_len];
205 : ssize_t unpack_len;
206 :
207 0 : tevent_req_profile_pack(p1, buf, sizeof(buf));
208 0 : dump_data(10, buf, sizeof(buf));
209 :
210 0 : unpack_len = tevent_req_profile_unpack(
211 : buf,
212 : pack_len,
213 : tctx,
214 : &p2);
215 0 : torture_assert_int_equal(tctx,
216 : pack_len,
217 : unpack_len,
218 : "profile_unpack failed\n");
219 : }
220 :
221 0 : printstring = tevent_req_profile_string(tctx, p2, 0, UINT_MAX);
222 0 : torture_assert_not_null(
223 : tctx,
224 : printstring,
225 : "tevent_req_profile_string failed\n");
226 0 : printf("%s\n", printstring);
227 :
228 0 : tevent_req_profile_get_name(p1, &str1);
229 0 : tevent_req_profile_get_name(p2, &str2);
230 0 : torture_assert_str_equal(tctx, str1, str2, "names differ\n");
231 :
232 0 : tevent_req_profile_get_start(p1, &str1, &tv1);
233 0 : tevent_req_profile_get_start(p2, &str2, &tv2);
234 0 : torture_assert_str_equal(tctx, str1, str2, "start strings differ\n");
235 0 : torture_assert(tctx,
236 : tevent_timeval_compare(&tv1, &tv2) == 0,
237 : "start times differ\n");
238 :
239 0 : tevent_req_profile_get_stop(p1, &str1, &tv1);
240 0 : tevent_req_profile_get_stop(p2, &str2, &tv2);
241 0 : torture_assert_str_equal(tctx, str1, str2, "stop strings differ\n");
242 0 : torture_assert(tctx,
243 : tevent_timeval_compare(&tv1, &tv2) == 0,
244 : "stop times differ\n");
245 :
246 0 : tevent_req_profile_get_status(p1, &pid1, &state1, &err1);
247 0 : tevent_req_profile_get_status(p2, &pid2, &state2, &err2);
248 0 : torture_assert_int_equal(tctx, pid1, pid2, "pids differ\n");
249 0 : torture_assert_int_equal(tctx, state1, state2, "states differ\n");
250 0 : torture_assert_int_equal(tctx, err1, err2, "user errors differ\n");
251 :
252 0 : str1 = tevent_req_profile_string(p1, p1, 0, UINT_MAX);
253 0 : torture_assert_not_null(tctx, str1, "profile_string failed\n");
254 0 : str2 = tevent_req_profile_string(p2, p2, 0, UINT_MAX);
255 0 : torture_assert_not_null(tctx, str2, "profile_string failed\n");
256 :
257 0 : torture_assert_str_equal(tctx, str1, str2, "result strings differ\n");
258 :
259 0 : TALLOC_FREE(p1);
260 0 : TALLOC_FREE(p2);
261 :
262 0 : return true;
263 : }
264 :
265 964 : struct torture_suite *torture_local_tevent_req(TALLOC_CTX *mem_ctx)
266 : {
267 : struct torture_suite *suite;
268 :
269 964 : suite = torture_suite_create(mem_ctx, "tevent_req");
270 :
271 964 : torture_suite_add_simple_tcase_const(
272 : suite,
273 : "create",
274 : test_tevent_req_create,
275 : NULL);
276 964 : torture_suite_add_simple_tcase_const(
277 : suite,
278 : "profile1",
279 : test_tevent_req_profile1,
280 : NULL);
281 964 : torture_suite_add_simple_tcase_const(
282 : suite,
283 : "profile2",
284 : test_tevent_req_profile2,
285 : NULL);
286 :
287 964 : return suite;
288 : }
|