r4549: got rid of a lot more uses of plain talloc(), instead using
[metze/samba/wip.git] / source4 / torture / rpc / echo.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for echo rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/ndr_echo.h"
24
25
26 /*
27   test the AddOne interface
28 */
29 static BOOL test_addone(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
30 {
31         int i;
32         NTSTATUS status;
33
34         printf("\nTesting AddOne\n");
35
36         for (i=0;i<10;i++) {
37                 uint32_t n = i;
38                 struct echo_AddOne r;
39                 r.in.v = &n;
40                 r.out.v = &n;
41                 status = dcerpc_echo_AddOne(p, mem_ctx, &r);
42                 if (!NT_STATUS_IS_OK(status)) {
43                         printf("AddOne(%d) failed - %s\n", i, nt_errstr(status));
44                         return False;
45                 }
46                 printf("%d + 1 = %u\n", i, n);
47         }
48
49         return True;
50 }
51
52 /*
53   test the EchoData interface
54 */
55 static BOOL test_echodata(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
56 {
57         int i;
58         NTSTATUS status;
59         uint8_t *data_in, *data_out;
60         int len = 1 + (random() % 5000);
61         struct echo_EchoData r;
62
63         printf("\nTesting EchoData\n");
64
65         data_in = talloc_size(mem_ctx, len);
66         data_out = talloc_size(mem_ctx, len);
67         for (i=0;i<len;i++) {
68                 data_in[i] = i;
69         }
70         
71         r.in.len = len;
72         r.in.in_data = data_in;
73
74         status = dcerpc_echo_EchoData(p, mem_ctx, &r);
75         if (!NT_STATUS_IS_OK(status)) {
76                 printf("EchoData(%d) failed - %s\n", len, nt_errstr(status));
77                 return False;
78         }
79
80         data_out = r.out.out_data;
81
82         for (i=0;i<len;i++) {
83                 if (data_in[i] != data_out[i]) {
84                         printf("Bad data returned for len %d at offset %d\n", 
85                                len, i);
86                         printf("in:\n");
87                         dump_data(0, data_in+i, MIN(len-i, 16));
88                         printf("out:\n");
89                         dump_data(0, data_out+i, MIN(len-1, 16));
90                         return False;
91                 }
92         }
93
94
95         return True;
96 }
97
98
99 /*
100   test the SourceData interface
101 */
102 static BOOL test_sourcedata(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
103 {
104         int i;
105         NTSTATUS status;
106         int len = 200000 + (random() % 5000);
107         uint8_t *data_out;
108         struct echo_SourceData r;
109
110         printf("\nTesting SourceData\n");
111
112         data_out = talloc_size(mem_ctx, len);
113
114         r.in.len = len;
115         r.out.data = data_out;
116
117         status = dcerpc_echo_SourceData(p, mem_ctx, &r);
118         if (!NT_STATUS_IS_OK(status)) {
119                 printf("SourceData(%d) failed - %s\n", len, nt_errstr(status));
120                 return False;
121         }
122
123         for (i=0;i<len;i++) {
124                 uint8_t *v = (uint8_t *)data_out;
125                 if (v[i] != (i & 0xFF)) {
126                         printf("bad data 0x%x at %d\n", (uint8_t)data_out[i], i);
127                         return False;
128                 }
129         }
130
131         return True;
132 }
133
134 /*
135   test the SinkData interface
136 */
137 static BOOL test_sinkdata(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
138 {
139         int i;
140         NTSTATUS status;
141         uint8_t *data_in;
142         int len = 200000 + (random() % 5000);
143         struct echo_SinkData r;
144
145         printf("\nTesting SinkData\n");
146
147         data_in = talloc_size(mem_ctx, len);
148         for (i=0;i<len;i++) {
149                 data_in[i] = i+1;
150         }
151
152         r.in.len = len;
153         r.in.data = data_in;
154
155         status = dcerpc_echo_SinkData(p, mem_ctx, &r);
156         if (!NT_STATUS_IS_OK(status)) {
157                 printf("SinkData(%d) failed - %s\n", len, nt_errstr(status));
158                 return False;
159         }
160
161         printf("sunk %d bytes\n", len);
162
163         return True;
164 }
165
166
167 /*
168   test the testcall interface
169 */
170 static BOOL test_testcall(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
171 {
172         NTSTATUS status;
173         struct echo_TestCall r;
174
175         r.in.s1 = "input string";
176
177         printf("\nTesting TestCall\n");
178         status = dcerpc_echo_TestCall(p, mem_ctx, &r);
179         if (!NT_STATUS_IS_OK(status)) {
180                 printf("TestCall failed - %s\n", nt_errstr(status));
181                 return False;
182         }
183
184         return True;
185 }
186
187 /*
188   test the testcall interface
189 */
190 static BOOL test_testcall2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
191 {
192         NTSTATUS status;
193         struct echo_TestCall2 r;
194         int i;
195         BOOL ret = True;
196
197         for (i=1;i<=7;i++) {
198                 r.in.level = i;
199
200                 printf("\nTesting TestCall2 level %d\n", i);
201                 status = dcerpc_echo_TestCall2(p, mem_ctx, &r);
202                 if (!NT_STATUS_IS_OK(status)) {
203                         printf("TestCall2 failed - %s\n", nt_errstr(status));
204                         ret = False;
205                 }
206         }
207
208         return ret;
209 }
210
211 #if 0
212 /*
213   test the TestSleep interface
214 */
215 static BOOL test_sleep(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
216 {
217         int i;
218         NTSTATUS status;
219 #define ASYNC_COUNT 5
220         struct rpc_request *req[ASYNC_COUNT];
221         struct echo_TestSleep r[ASYNC_COUNT];
222         int done[ASYNC_COUNT];
223         struct event_context *ctx;
224         int total_done = 0;
225         BOOL ret = True;
226
227         printf("\nTesting TestSleep\n");
228
229         for (i=0;i<ASYNC_COUNT;i++) {
230                 done[i] = 0;
231                 r[i].in.seconds = ASYNC_COUNT-i;
232                 req[i] = dcerpc_echo_TestSleep_send(p, mem_ctx, &r[i]);
233                 if (!req[i]) {
234                         printf("Failed to send async sleep request\n");
235                         return False;
236                 }
237         }
238
239         ctx = dcerpc_event_context(p);
240         while (total_done < ASYNC_COUNT) {
241                 if (event_loop_once(ctx) != 0) {
242                         return False;
243                 }
244                 for (i=0;i<ASYNC_COUNT;i++) {
245                         if (done[i] == 0 && req[i]->state == RPC_REQUEST_DONE) {
246                                 total_done++;
247                                 done[i] = 1;
248                                 status = dcerpc_ndr_request_recv(req[i]);
249                                 if (!NT_STATUS_IS_OK(status)) {
250                                         printf("TestSleep(%d) failed - %s\n",
251                                                i, nt_errstr(status));
252                                         ret = False;
253                                 } else {
254                                         printf("Sleep for %d seconds\n", 
255                                                r[i].out.result);
256                                 }
257                         }
258                 }
259         }
260
261         return ret;
262 }
263 #endif
264
265
266 /*
267   test enum handling
268 */
269 static BOOL test_enum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
270 {
271         NTSTATUS status;
272         struct echo_TestEnum r;
273         BOOL ret = True;
274         enum echo_Enum1 v = ECHO_ENUM1;
275         struct echo_Enum2 e2;
276         union echo_Enum3 e3;
277
278         r.in.foo1 = &v;
279         r.in.foo2 = &e2;
280         r.in.foo3 = &e3;
281         r.out.foo1 = &v;
282         r.out.foo2 = &e2;
283         r.out.foo3 = &e3;
284
285         e2.e1 = 76;
286         e2.e2 = ECHO_ENUM1_32;
287         e3.e1 = ECHO_ENUM2;
288
289         printf("\nTesting TestEnum\n");
290         status = dcerpc_echo_TestEnum(p, mem_ctx, &r);
291         if (!NT_STATUS_IS_OK(status)) {
292                 printf("TestEnum failed - %s\n", nt_errstr(status));
293                 ret = False;
294         }
295
296         return ret;
297 }
298
299
300 BOOL torture_rpc_echo(void)
301 {
302         NTSTATUS status;
303         struct dcerpc_pipe *p;
304         TALLOC_CTX *mem_ctx;
305         BOOL ret = True;
306
307         mem_ctx = talloc_init("torture_rpc_echo");
308
309         status = torture_rpc_connection(&p, 
310                                         DCERPC_RPCECHO_NAME,
311                                         DCERPC_RPCECHO_UUID,
312                                         DCERPC_RPCECHO_VERSION);
313         if (!NT_STATUS_IS_OK(status)) {
314                 return False;
315         }
316
317         if (!test_addone(p, mem_ctx)) {
318                 ret = False;
319         }
320
321         if (!test_sinkdata(p, mem_ctx)) {
322                 ret = False;
323         }
324
325         if (!test_echodata(p, mem_ctx)) {
326                 ret = False;
327         }
328
329         if (!test_sourcedata(p, mem_ctx)) {
330                 ret = False;
331         }
332
333         if (!test_testcall(p, mem_ctx)) {
334                 ret = False;
335         }
336
337         if (!test_testcall2(p, mem_ctx)) {
338                 ret = False;
339         }
340
341         if (!test_enum(p, mem_ctx)) {
342                 ret = False;
343         }
344
345 /*
346         if (!test_sleep(p, mem_ctx)) {
347                 ret = False;
348         }
349 */
350         printf("\n");
351         
352         talloc_free(mem_ctx);
353
354         torture_rpc_close(p);
355         return ret;
356 }