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
, tmp_ctx
, &io
);
45 if (NT_STATUS_IS_OK(status
)) {
54 benchmark cldap netlogon calls
56 static bool bench_cldap_netlogon(struct torture_context
*tctx
, const char *address
)
58 struct cldap_socket
*cldap
;
60 struct timeval tv
= timeval_current();
61 int timelimit
= torture_setting_int(tctx
, "timelimit", 10);
62 struct cldap_netlogon search
;
63 struct bench_state
*state
;
65 struct tsocket_address
*dest_addr
;
68 ret
= tsocket_address_inet_from_strings(tctx
, "ip",
70 lpcfg_cldap_port(tctx
->lp_ctx
),
74 status
= cldap_socket_init(tctx
, NULL
, dest_addr
, &cldap
);
75 torture_assert_ntstatus_ok(tctx
, status
, "cldap_socket_init");
77 state
= talloc_zero(tctx
, struct bench_state
);
81 search
.in
.dest_address
= NULL
;
82 search
.in
.dest_port
= 0;
83 search
.in
.acct_control
= -1;
84 search
.in
.version
= 6;
86 printf("Running CLDAP/netlogon for %d seconds\n", timelimit
);
87 while (timeval_elapsed(&tv
) < timelimit
) {
88 while (num_sent
- (state
->pass_count
+state
->fail_count
) < 10) {
89 struct tevent_req
*req
;
90 req
= cldap_netlogon_send(state
, tctx
->ev
,
93 tevent_req_set_callback(req
, request_netlogon_handler
, state
);
96 if (num_sent
% 50 == 0) {
97 if (torture_setting_bool(tctx
, "progress", true)) {
98 printf("%.1f queries per second (%d failures) \r",
99 state
->pass_count
/ timeval_elapsed(&tv
),
106 tevent_loop_once(tctx
->ev
);
109 while (num_sent
!= (state
->pass_count
+ state
->fail_count
)) {
110 tevent_loop_once(tctx
->ev
);
113 printf("%.1f queries per second (%d failures) \n",
114 state
->pass_count
/ timeval_elapsed(&tv
),
121 static void request_rootdse_handler(struct tevent_req
*req
)
123 struct cldap_search io
;
124 struct bench_state
*state
= tevent_req_callback_data(req
, struct bench_state
);
126 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
127 status
= cldap_search_recv(req
, tmp_ctx
, &io
);
129 if (NT_STATUS_IS_OK(status
)) {
134 talloc_free(tmp_ctx
);
138 benchmark cldap netlogon calls
140 static bool bench_cldap_rootdse(struct torture_context
*tctx
, const char *address
)
142 struct cldap_socket
*cldap
;
144 struct timeval tv
= timeval_current();
145 int timelimit
= torture_setting_int(tctx
, "timelimit", 10);
146 struct cldap_search search
;
147 struct bench_state
*state
;
149 struct tsocket_address
*dest_addr
;
152 ret
= tsocket_address_inet_from_strings(tctx
, "ip",
154 lpcfg_cldap_port(tctx
->lp_ctx
),
158 /* cldap_socket_init should now know about the dest. address */
159 status
= cldap_socket_init(tctx
, NULL
, dest_addr
, &cldap
);
160 torture_assert_ntstatus_ok(tctx
, status
, "cldap_socket_init");
162 state
= talloc_zero(tctx
, struct bench_state
);
165 search
.in
.dest_address
= NULL
;
166 search
.in
.dest_port
= 0;
167 search
.in
.filter
= "(objectClass=*)";
168 search
.in
.timeout
= 2;
169 search
.in
.retries
= 1;
171 printf("Running CLDAP/rootdse for %d seconds\n", timelimit
);
172 while (timeval_elapsed(&tv
) < timelimit
) {
173 while (num_sent
- (state
->pass_count
+state
->fail_count
) < 10) {
174 struct tevent_req
*req
;
175 req
= cldap_search_send(state
, tctx
->ev
, cldap
, &search
);
177 tevent_req_set_callback(req
, request_rootdse_handler
, state
);
180 if (num_sent
% 50 == 0) {
181 if (torture_setting_bool(tctx
, "progress", true)) {
182 printf("%.1f queries per second (%d failures) \r",
183 state
->pass_count
/ timeval_elapsed(&tv
),
190 tevent_loop_once(tctx
->ev
);
193 while (num_sent
!= (state
->pass_count
+ state
->fail_count
)) {
194 tevent_loop_once(tctx
->ev
);
197 printf("%.1f queries per second (%d failures) \n",
198 state
->pass_count
/ timeval_elapsed(&tv
),
206 benchmark how fast a CLDAP server can respond to a series of parallel
209 bool torture_bench_cldap(struct torture_context
*torture
)
212 struct nbt_name name
;
216 make_nbt_name_server(&name
, torture_setting_string(torture
, "host", NULL
));
218 /* do an initial name resolution to find its IP */
219 status
= resolve_name_ex(lpcfg_resolve_context(torture
->lp_ctx
),
220 0, 0, &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
);