s3: Do not reference ndr_table_<pipe> in the cli_ routines directly
[ira/wip.git] / pidl / tests / samba3-cli.pl
1 #!/usr/bin/perl
2 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3 # Published under the GNU General Public License
4 use strict;
5 use warnings;
6
7 use Test::More tests => 9;
8 use FindBin qw($RealBin);
9 use lib "$RealBin";
10 use Util;
11 use Parse::Pidl::Util qw(MyDumper);
12 use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction ParseOutputArgument);
13 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
14
15 # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
16 my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] };
17 is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn, "r."));
18 is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionOutEnv($fn, "r."));
19
20 $fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] };
21 is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn, "r."));
22 is_deeply({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv($fn, "r."));
23
24 $fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] };
25 is_deeply({ }, GenerateFunctionInEnv($fn, "r."));
26 is_deeply({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv($fn, "r."));
27
28 my $x = new Parse::Pidl::Samba3::ClientNDR();
29
30 $fn = { NAME => "bar", ELEMENTS => [ ] };
31 $x->ParseFunction("foo", $fn);
32 is($x->{res}, 
33 "struct rpccli_bar_state {
34         struct bar orig;
35         struct bar tmp;
36         TALLOC_CTX *out_mem_ctx;
37         NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
38 };
39
40 static void rpccli_bar_done(struct tevent_req *subreq);
41
42 struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
43                                    struct tevent_context *ev,
44                                    struct rpc_pipe_client *cli)
45 {
46         struct tevent_req *req;
47         struct rpccli_bar_state *state;
48         struct tevent_req *subreq;
49
50         req = tevent_req_create(mem_ctx, &state,
51                                 struct rpccli_bar_state);
52         if (req == NULL) {
53                 return NULL;
54         }
55         state->out_mem_ctx = NULL;
56         state->dispatch_recv = cli->dispatch_recv;
57
58         /* In parameters */
59
60         /* Out parameters */
61
62         if (DEBUGLEVEL >= 10) {
63                 NDR_PRINT_IN_DEBUG(bar, &state->orig);
64         }
65
66         /* make a temporary copy, that we pass to the dispatch function */
67         state->tmp = state->orig;
68
69         subreq = cli->dispatch_send(state, ev, cli,
70                                     &ndr_table_foo,
71                                     NDR_BAR,
72                                     &state->tmp);
73         if (tevent_req_nomem(subreq, req)) {
74                 return tevent_req_post(req, ev);
75         }
76         tevent_req_set_callback(subreq, rpccli_bar_done, req);
77         return req;
78 }
79
80 static void rpccli_bar_done(struct tevent_req *subreq)
81 {
82         struct tevent_req *req = tevent_req_callback_data(
83                 subreq, struct tevent_req);
84         struct rpccli_bar_state *state = tevent_req_data(
85                 req, struct rpccli_bar_state);
86         NTSTATUS status;
87         TALLOC_CTX *mem_ctx;
88
89         if (state->out_mem_ctx) {
90                 mem_ctx = state->out_mem_ctx;
91         } else {
92                 mem_ctx = state;
93         }
94
95         status = state->dispatch_recv(subreq, mem_ctx);
96         TALLOC_FREE(subreq);
97         if (!NT_STATUS_IS_OK(status)) {
98                 tevent_req_nterror(req, status);
99                 return;
100         }
101
102         /* Copy out parameters */
103
104         /* Reset temporary structure */
105         ZERO_STRUCT(state->tmp);
106
107         if (DEBUGLEVEL >= 10) {
108                 NDR_PRINT_OUT_DEBUG(bar, &state->orig);
109         }
110
111         tevent_req_done(req);
112 }
113
114 NTSTATUS rpccli_bar_recv(struct tevent_req *req,
115                          TALLOC_CTX *mem_ctx)
116 {
117         struct rpccli_bar_state *state = tevent_req_data(
118                 req, struct rpccli_bar_state);
119         NTSTATUS status;
120
121         if (tevent_req_is_nterror(req, &status)) {
122                 tevent_req_received(req);
123                 return status;
124         }
125
126         /* Steal possbile out parameters to the callers context */
127         talloc_steal(mem_ctx, state->out_mem_ctx);
128
129         tevent_req_received(req);
130         return NT_STATUS_OK;
131 }
132
133 NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
134                     TALLOC_CTX *mem_ctx)
135 {
136 \tstruct bar r;
137 \tNTSTATUS status;
138
139 \t/* In parameters */
140
141 \tif (DEBUGLEVEL >= 10) {
142 \t\tNDR_PRINT_IN_DEBUG(bar, &r);
143 \t}
144
145         status = cli->dispatch(cli,
146                                 mem_ctx,
147                                 &ndr_table_foo,
148                                 NDR_BAR,
149                                 &r);
150
151 \tif (!NT_STATUS_IS_OK(status)) {
152 \t\treturn status;
153 \t}
154
155 \tif (DEBUGLEVEL >= 10) {
156 \t\tNDR_PRINT_OUT_DEBUG(bar, &r);
157 \t}
158
159 \tif (NT_STATUS_IS_ERR(status)) {
160 \t\treturn status;
161 \t}
162
163 \t/* Return variables */
164
165 \t/* Return result */
166 \treturn NT_STATUS_OK;
167 }
168
169 ");
170
171 $x = new Parse::Pidl::Samba3::ClientNDR();
172
173 $fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" };
174 $x->ParseFunction("foo", $fn);
175 is($x->{res}, 
176 "struct rpccli_bar_state {
177         struct bar orig;
178         struct bar tmp;
179         TALLOC_CTX *out_mem_ctx;
180         NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
181 };
182
183 static void rpccli_bar_done(struct tevent_req *subreq);
184
185 struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
186                                    struct tevent_context *ev,
187                                    struct rpc_pipe_client *cli)
188 {
189         struct tevent_req *req;
190         struct rpccli_bar_state *state;
191         struct tevent_req *subreq;
192
193         req = tevent_req_create(mem_ctx, &state,
194                                 struct rpccli_bar_state);
195         if (req == NULL) {
196                 return NULL;
197         }
198         state->out_mem_ctx = NULL;
199         state->dispatch_recv = cli->dispatch_recv;
200
201         /* In parameters */
202
203         /* Out parameters */
204
205         /* Result */
206         ZERO_STRUCT(state->orig.out.result);
207
208         if (DEBUGLEVEL >= 10) {
209                 NDR_PRINT_IN_DEBUG(bar, &state->orig);
210         }
211
212         /* make a temporary copy, that we pass to the dispatch function */
213         state->tmp = state->orig;
214
215         subreq = cli->dispatch_send(state, ev, cli,
216                                     &ndr_table_foo,
217                                     NDR_BAR,
218                                     &state->tmp);
219         if (tevent_req_nomem(subreq, req)) {
220                 return tevent_req_post(req, ev);
221         }
222         tevent_req_set_callback(subreq, rpccli_bar_done, req);
223         return req;
224 }
225
226 static void rpccli_bar_done(struct tevent_req *subreq)
227 {
228         struct tevent_req *req = tevent_req_callback_data(
229                 subreq, struct tevent_req);
230         struct rpccli_bar_state *state = tevent_req_data(
231                 req, struct rpccli_bar_state);
232         NTSTATUS status;
233         TALLOC_CTX *mem_ctx;
234
235         if (state->out_mem_ctx) {
236                 mem_ctx = state->out_mem_ctx;
237         } else {
238                 mem_ctx = state;
239         }
240
241         status = state->dispatch_recv(subreq, mem_ctx);
242         TALLOC_FREE(subreq);
243         if (!NT_STATUS_IS_OK(status)) {
244                 tevent_req_nterror(req, status);
245                 return;
246         }
247
248         /* Copy out parameters */
249
250         /* Copy result */
251         state->orig.out.result = state->tmp.out.result;
252
253         /* Reset temporary structure */
254         ZERO_STRUCT(state->tmp);
255
256         if (DEBUGLEVEL >= 10) {
257                 NDR_PRINT_OUT_DEBUG(bar, &state->orig);
258         }
259
260         tevent_req_done(req);
261 }
262
263 NTSTATUS rpccli_bar_recv(struct tevent_req *req,
264                          TALLOC_CTX *mem_ctx,
265                          WERROR *result)
266 {
267         struct rpccli_bar_state *state = tevent_req_data(
268                 req, struct rpccli_bar_state);
269         NTSTATUS status;
270
271         if (tevent_req_is_nterror(req, &status)) {
272                 tevent_req_received(req);
273                 return status;
274         }
275
276         /* Steal possbile out parameters to the callers context */
277         talloc_steal(mem_ctx, state->out_mem_ctx);
278
279         /* Return result */
280         *result = state->orig.out.result;
281
282         tevent_req_received(req);
283         return NT_STATUS_OK;
284 }
285
286 NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
287                     TALLOC_CTX *mem_ctx,
288                     WERROR *werror)
289 {
290 \tstruct bar r;
291 \tNTSTATUS status;
292
293 \t/* In parameters */
294
295 \tif (DEBUGLEVEL >= 10) {
296 \t\tNDR_PRINT_IN_DEBUG(bar, &r);
297 \t}
298
299         status = cli->dispatch(cli,
300                                 mem_ctx,
301                                 &ndr_table_foo,
302                                 NDR_BAR,
303                                 &r);
304
305 \tif (!NT_STATUS_IS_OK(status)) {
306 \t\treturn status;
307 \t}
308
309 \tif (DEBUGLEVEL >= 10) {
310 \t\tNDR_PRINT_OUT_DEBUG(bar, &r);
311 \t}
312
313 \tif (NT_STATUS_IS_ERR(status)) {
314 \t\treturn status;
315 \t}
316
317 \t/* Return variables */
318
319 \t/* Return result */
320 \tif (werror) {
321 \t\t*werror = r.out.result;
322 \t}
323
324 \treturn werror_to_ntstatus(r.out.result);
325 }
326
327 ");
328
329 $x = new Parse::Pidl::Samba3::ClientNDR();
330
331 $fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" };
332 my $e = { NAME => "foo", ORIGINAL => { FILE => "f", LINE => -1 },
333           LEVELS => [ { TYPE => "ARRAY", SIZE_IS => "mysize" }, { TYPE => "DATA", DATA_TYPE => "int" } ]};
334
335 $x->ParseOutputArgument($fn, $e);
336 is($x->{res}, "memcpy(foo, r.out.foo, mysize * sizeof(*foo));\n");