s3:rpc_server: Fix code spelling
[Samba.git] / source3 / torture / test_rpc_scale.c
blob6ef26f37a9971dbf30f775b99a09fc5be97a4356
1 /*
2 * Unix SMB/CIFS implementation.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "source3/include/includes.h"
19 #include "source3/torture/proto.h"
20 #include "source3/libsmb/libsmb.h"
21 #include "librpc/gen_ndr/ndr_spoolss_c.h"
22 #include "lib/util/tevent_ntstatus.h"
23 #include "source3/rpc_client/rpc_client.h"
24 #include "source3/rpc_client/cli_pipe.h"
25 #include "libcli/smb/smbXcli_base.h"
27 extern int torture_nprocs;
28 extern int torture_numops;
30 struct rpc_scale_one_state {
31 struct tevent_context *ev;
32 struct cli_state *cli;
33 size_t num_iterations;
34 struct rpc_pipe_client *rpccli;
35 DATA_BLOB buffer;
36 uint32_t needed;
37 uint32_t num_printers;
38 union spoolss_PrinterInfo *printers;
41 static void rpc_scale_one_opened(struct tevent_req *subreq);
42 static void rpc_scale_one_bound(struct tevent_req *subreq);
43 static void rpc_scale_one_listed(struct tevent_req *subreq);
45 static struct tevent_req *rpc_scale_one_send(
46 TALLOC_CTX *mem_ctx,
47 struct tevent_context *ev,
48 struct cli_state *cli,
49 size_t num_iterations)
51 struct tevent_req *req = NULL, *subreq = NULL;
52 struct rpc_scale_one_state *state = NULL;
54 req = tevent_req_create(mem_ctx, &state, struct rpc_scale_one_state);
55 if (req == NULL) {
56 return NULL;
58 state->ev = ev;
59 state->cli = cli;
60 state->num_iterations = num_iterations;
62 subreq = rpc_pipe_open_np_send(
63 state, ev, cli, &ndr_table_spoolss);
64 if (tevent_req_nomem(subreq, req)) {
65 return tevent_req_post(req, ev);
67 tevent_req_set_callback(subreq, rpc_scale_one_opened, req);
68 return req;
71 static void rpc_scale_one_opened(struct tevent_req *subreq)
73 struct tevent_req *req = tevent_req_callback_data(
74 subreq, struct tevent_req);
75 struct rpc_scale_one_state *state = tevent_req_data(
76 req, struct rpc_scale_one_state);
77 struct pipe_auth_data *auth = NULL;
78 NTSTATUS status;
80 status = rpc_pipe_open_np_recv(subreq, state, &state->rpccli);
81 TALLOC_FREE(subreq);
82 if (tevent_req_nterror(req, status)) {
83 return;
86 status = rpccli_anon_bind_data(state, &auth);
87 if (tevent_req_nterror(req, status)) {
88 return;
91 subreq = rpc_pipe_bind_send(state, state->ev, state->rpccli, auth);
92 if (tevent_req_nomem(subreq, req)) {
93 return;
95 tevent_req_set_callback(subreq, rpc_scale_one_bound, req);
98 static void rpc_scale_one_bound(struct tevent_req *subreq)
100 struct tevent_req *req = tevent_req_callback_data(
101 subreq, struct tevent_req);
102 struct rpc_scale_one_state *state = tevent_req_data(
103 req, struct rpc_scale_one_state);
104 char *server = NULL;
105 NTSTATUS status;
107 status = rpc_pipe_bind_recv(subreq);
108 if (tevent_req_nterror(req, status)) {
109 return;
112 server = talloc_asprintf(
113 state,
114 "\\%s\n",
115 smbXcli_conn_remote_name(state->cli->conn));
116 if (tevent_req_nomem(server, req)) {
117 return;
119 state->buffer = data_blob_talloc(state, NULL, 4096);
120 if (tevent_req_nomem(state->buffer.data, req)) {
121 return;
124 subreq = dcerpc_spoolss_EnumPrinters_send(
125 state,
126 state->ev,
127 state->rpccli->binding_handle,
128 PRINTER_ENUM_LOCAL,
129 server,
130 1, /* level */
131 &state->buffer,
132 state->buffer.length,
133 &state->num_printers,
134 &state->printers,
135 &state->needed);
136 if (tevent_req_nomem(subreq, req)) {
137 return;
139 tevent_req_set_callback(subreq, rpc_scale_one_listed, req);
142 static void rpc_scale_one_listed(struct tevent_req *subreq)
144 struct tevent_req *req = tevent_req_callback_data(
145 subreq, struct tevent_req);
146 struct rpc_scale_one_state *state = tevent_req_data(
147 req, struct rpc_scale_one_state);
148 NTSTATUS status;
149 WERROR result;
151 status = dcerpc_spoolss_EnumPrinters_recv(subreq, state, &result);
152 if (tevent_req_nterror(req, status)) {
153 return;
156 if (!W_ERROR_IS_OK(result)) {
157 status = werror_to_ntstatus(result);
158 tevent_req_nterror(req, status);
159 return;
163 * This will trigger a sync close. Making that async will be a
164 * lot of effort, and even with this being sync this test is
165 * nasty enough.
167 TALLOC_FREE(state->rpccli);
169 state->num_iterations -= 1;
171 if (state->num_iterations == 0) {
172 tevent_req_done(req);
173 return;
176 subreq = rpc_pipe_open_np_send(
177 state, state->ev, state->cli, &ndr_table_spoolss);
178 if (tevent_req_nomem(subreq, req)) {
179 return;
181 tevent_req_set_callback(subreq, rpc_scale_one_opened, req);
184 static NTSTATUS rpc_scale_one_recv(struct tevent_req *req)
186 return tevent_req_simple_recv_ntstatus(req);
189 struct rpc_scale_state {
190 size_t num_reqs;
191 size_t done;
194 static void rpc_scale_done(struct tevent_req *subreq);
196 static struct tevent_req *rpc_scale_send(
197 TALLOC_CTX *mem_ctx,
198 struct tevent_context *ev,
199 struct cli_state **clis)
201 struct tevent_req *req = NULL;
202 struct rpc_scale_state *state = NULL;
203 size_t i, num_clis = talloc_array_length(clis);
205 req = tevent_req_create(mem_ctx, &state, struct rpc_scale_state);
206 if (req == NULL) {
207 return NULL;
209 state->num_reqs = num_clis;
211 for (i=0; i<num_clis; i++) {
212 struct tevent_req *subreq = rpc_scale_one_send(
213 state, ev, clis[i], torture_numops);
214 if (tevent_req_nomem(subreq, req)) {
215 return tevent_req_post(req, ev);
217 tevent_req_set_callback(subreq, rpc_scale_done, req);
219 return req;
222 static void rpc_scale_done(struct tevent_req *subreq)
224 struct tevent_req *req = tevent_req_callback_data(
225 subreq, struct tevent_req);
226 struct rpc_scale_state *state = tevent_req_data(
227 req, struct rpc_scale_state);
228 NTSTATUS status;
230 status = rpc_scale_one_recv(subreq);
231 TALLOC_FREE(subreq);
232 if (tevent_req_nterror(req, status)) {
233 return;
236 state->done += 1;
238 if (state->done == state->num_reqs) {
239 tevent_req_done(req);
243 static NTSTATUS rpc_scale_recv(struct tevent_req *req)
245 return tevent_req_simple_recv_ntstatus(req);
248 bool run_rpc_scale(int dummy)
250 TALLOC_CTX *frame = talloc_stackframe();
251 struct cli_state **clis = NULL;
252 struct tevent_req *req = NULL;
253 struct tevent_context *ev = NULL;
254 bool ok, result = false;
255 NTSTATUS status;
256 int i;
258 clis = talloc_zero_array(
259 talloc_tos(), struct cli_state *, torture_nprocs);
260 if (clis == NULL) {
261 fprintf(stderr, "talloc failed\n");
262 goto fail;
265 for (i=0; i<torture_nprocs; i++) {
266 ok = torture_open_connection_flags(&clis[i], i, 0);
267 if (!ok) {
268 fprintf(stderr, "could not open connection %d\n", i);
269 goto fail;
273 ev = samba_tevent_context_init(talloc_tos());
274 if (ev == NULL) {
275 goto fail;
278 req = rpc_scale_send(talloc_tos(), ev, clis);
279 if (req == NULL) {
280 goto fail;
283 ok = tevent_req_poll_ntstatus(req, ev, &status);
284 if (!ok) {
285 fprintf(stderr,
286 "rpc_scale_send failed: %s\n",
287 nt_errstr(status));
288 goto fail;
291 status = rpc_scale_recv(req);
292 if (!NT_STATUS_IS_OK(status)) {
293 fprintf(stderr, "rpc_scale failed: %s\n", nt_errstr(status));
294 goto fail;
297 result = true;
298 fail:
299 TALLOC_FREE(frame);
300 return result;