2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/cldap/cldap.h"
24 #include "libcli/resolve/resolve.h"
25 #include "torture/torture.h"
26 #include "param/param.h"
27 #include "../lib/tsocket/tsocket.h"
29 #define CHECK_VAL(v, correct) torture_assert_int_equal(tctx, (v), (correct), "incorrect value");
32 struct torture_context
*tctx
;
33 int pass_count
, fail_count
;
36 static void request_netlogon_handler(struct tevent_req
*req
)
38 struct cldap_netlogon io
;
39 struct bench_state
*state
= tevent_req_callback_data(req
, struct bench_state
);
41 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
43 status
= cldap_netlogon_recv(req
,
44 lp_iconv_convenience(state
->tctx
->lp_ctx
),
47 if (NT_STATUS_IS_OK(status
)) {
56 benchmark cldap netlogon calls
58 static bool bench_cldap_netlogon(struct torture_context
*tctx
, const char *address
)
60 struct cldap_socket
*cldap
;
62 struct timeval tv
= timeval_current();
63 int timelimit
= torture_setting_int(tctx
, "timelimit", 10);
64 struct cldap_netlogon search
;
65 struct bench_state
*state
;
67 struct tsocket_address
*dest_addr
;
70 ret
= tsocket_address_inet_from_strings(tctx
, "ip",
72 lp_cldap_port(tctx
->lp_ctx
),
76 status
= cldap_socket_init(tctx
, tctx
->ev
, NULL
, dest_addr
, &cldap
);
77 torture_assert_ntstatus_ok(tctx
, status
, "cldap_socket_init");
79 state
= talloc_zero(tctx
, struct bench_state
);
83 search
.in
.dest_address
= NULL
;
84 search
.in
.dest_port
= 0;
85 search
.in
.acct_control
= -1;
86 search
.in
.version
= 6;
88 printf("Running CLDAP/netlogon for %d seconds\n", timelimit
);
89 while (timeval_elapsed(&tv
) < timelimit
) {
90 while (num_sent
- (state
->pass_count
+state
->fail_count
) < 10) {
91 struct tevent_req
*req
;
92 req
= cldap_netlogon_send(state
, cldap
, &search
);
94 tevent_req_set_callback(req
, request_netlogon_handler
, state
);
97 if (num_sent
% 50 == 0) {
98 if (torture_setting_bool(tctx
, "progress", true)) {
99 printf("%.1f queries per second (%d failures) \r",
100 state
->pass_count
/ timeval_elapsed(&tv
),
107 tevent_loop_once(tctx
->ev
);
110 while (num_sent
!= (state
->pass_count
+ state
->fail_count
)) {
111 tevent_loop_once(tctx
->ev
);
114 printf("%.1f queries per second (%d failures) \n",
115 state
->pass_count
/ timeval_elapsed(&tv
),
122 static void request_rootdse_handler(struct tevent_req
*req
)
124 struct cldap_search io
;
125 struct bench_state
*state
= tevent_req_callback_data(req
, struct bench_state
);
127 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
128 status
= cldap_search_recv(req
, tmp_ctx
, &io
);
130 if (NT_STATUS_IS_OK(status
)) {
135 talloc_free(tmp_ctx
);
139 benchmark cldap netlogon calls
141 static bool bench_cldap_rootdse(struct torture_context
*tctx
, const char *address
)
143 struct cldap_socket
*cldap
;
145 struct timeval tv
= timeval_current();
146 int timelimit
= torture_setting_int(tctx
, "timelimit", 10);
147 struct cldap_search search
;
148 struct bench_state
*state
;
150 struct tsocket_address
*dest_addr
;
153 ret
= tsocket_address_inet_from_strings(tctx
, "ip",
155 lp_cldap_port(tctx
->lp_ctx
),
159 /* cldap_socket_init should now know about the dest. address */
160 status
= cldap_socket_init(tctx
, tctx
->ev
, NULL
, dest_addr
, &cldap
);
161 torture_assert_ntstatus_ok(tctx
, status
, "cldap_socket_init");
163 state
= talloc_zero(tctx
, struct bench_state
);
166 search
.in
.dest_address
= NULL
;
167 search
.in
.dest_port
= 0;
168 search
.in
.filter
= "(objectClass=*)";
169 search
.in
.timeout
= 2;
170 search
.in
.retries
= 1;
172 printf("Running CLDAP/rootdse for %d seconds\n", timelimit
);
173 while (timeval_elapsed(&tv
) < timelimit
) {
174 while (num_sent
- (state
->pass_count
+state
->fail_count
) < 10) {
175 struct tevent_req
*req
;
176 req
= cldap_search_send(state
, cldap
, &search
);
178 tevent_req_set_callback(req
, request_rootdse_handler
, state
);
181 if (num_sent
% 50 == 0) {
182 if (torture_setting_bool(tctx
, "progress", true)) {
183 printf("%.1f queries per second (%d failures) \r",
184 state
->pass_count
/ timeval_elapsed(&tv
),
191 tevent_loop_once(tctx
->ev
);
194 while (num_sent
!= (state
->pass_count
+ state
->fail_count
)) {
195 tevent_loop_once(tctx
->ev
);
198 printf("%.1f queries per second (%d failures) \n",
199 state
->pass_count
/ timeval_elapsed(&tv
),
207 benchmark how fast a CLDAP server can respond to a series of parallel
210 bool torture_bench_cldap(struct torture_context
*torture
)
213 struct nbt_name name
;
217 make_nbt_name_server(&name
, torture_setting_string(torture
, "host", NULL
));
219 /* do an initial name resolution to find its IP */
220 status
= resolve_name(lp_resolve_context(torture
->lp_ctx
), &name
, torture
, &address
, torture
->ev
);
221 if (!NT_STATUS_IS_OK(status
)) {
222 printf("Failed to resolve %s - %s\n",
223 name
.name
, nt_errstr(status
));
227 ret
&= bench_cldap_netlogon(torture
, address
);
228 ret
&= bench_cldap_rootdse(torture
, address
);