LCOV - code coverage report
Current view: top level - source4/torture/ldap - cldapbench.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 118 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    CLDAP benchmark test
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    
       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.
      12             :    
      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.
      17             :    
      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/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/cldap/cldap.h"
      24             : #include "libcli/resolve/resolve.h"
      25             : #include "libcli/ldap/ldap_client.h"
      26             : #include "torture/torture.h"
      27             : #include "torture/ldap/proto.h"
      28             : #include "param/param.h"
      29             : #include "../lib/tsocket/tsocket.h"
      30             : 
      31             : #define CHECK_VAL(v, correct) torture_assert_int_equal(tctx, (v), (correct), "incorrect value");
      32             : 
      33             : struct bench_state {
      34             :         struct torture_context *tctx;
      35             :         int pass_count, fail_count;
      36             : };
      37             : 
      38           0 : static void request_netlogon_handler(struct tevent_req *req)
      39             : {
      40           0 :         struct cldap_netlogon io;
      41           0 :         struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
      42           0 :         NTSTATUS status;
      43           0 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
      44           0 :         io.in.version = 6;
      45           0 :         status = cldap_netlogon_recv(req, tmp_ctx, &io);
      46           0 :         talloc_free(req);
      47           0 :         if (NT_STATUS_IS_OK(status)) {
      48           0 :                 state->pass_count++;
      49             :         } else {
      50           0 :                 state->fail_count++;
      51             :         }
      52           0 :         talloc_free(tmp_ctx);
      53           0 : }
      54             : 
      55             : /*
      56             :   benchmark cldap netlogon calls
      57             : */
      58           0 : static bool bench_cldap_netlogon(struct torture_context *tctx, const char *address)
      59             : {
      60           0 :         struct cldap_socket *cldap;
      61           0 :         int num_sent=0;
      62           0 :         struct timeval tv = timeval_current();
      63           0 :         int timelimit = torture_setting_int(tctx, "timelimit", 10);
      64           0 :         struct cldap_netlogon search;
      65           0 :         struct bench_state *state;
      66           0 :         NTSTATUS status;
      67           0 :         struct tsocket_address *dest_addr;
      68           0 :         int ret;
      69             : 
      70           0 :         ret = tsocket_address_inet_from_strings(tctx, "ip",
      71             :                                                 address,
      72             :                                                 lpcfg_cldap_port(tctx->lp_ctx),
      73             :                                                 &dest_addr);
      74           0 :         CHECK_VAL(ret, 0);
      75             : 
      76           0 :         status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
      77           0 :         torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
      78             : 
      79           0 :         state = talloc_zero(tctx, struct bench_state);
      80           0 :         state->tctx = tctx;
      81             : 
      82           0 :         ZERO_STRUCT(search);
      83           0 :         search.in.dest_address = NULL;
      84           0 :         search.in.dest_port = 0;
      85           0 :         search.in.acct_control = -1;
      86           0 :         search.in.version = 6;
      87             : 
      88           0 :         printf("Running CLDAP/netlogon for %d seconds\n", timelimit);
      89           0 :         while (timeval_elapsed(&tv) < timelimit) {
      90           0 :                 while (num_sent - (state->pass_count+state->fail_count) < 10) {
      91           0 :                         struct tevent_req *req;
      92           0 :                         req = cldap_netlogon_send(state, tctx->ev,
      93             :                                                   cldap, &search);
      94             : 
      95           0 :                         tevent_req_set_callback(req, request_netlogon_handler, state);
      96             : 
      97           0 :                         num_sent++;
      98           0 :                         if (num_sent % 50 == 0) {
      99           0 :                                 if (torture_setting_bool(tctx, "progress", true)) {
     100           0 :                                         printf("%.1f queries per second (%d failures)  \r", 
     101           0 :                                                state->pass_count / timeval_elapsed(&tv),
     102             :                                                state->fail_count);
     103           0 :                                         fflush(stdout);
     104             :                                 }
     105             :                         }
     106             :                 }
     107             : 
     108           0 :                 tevent_loop_once(tctx->ev);
     109             :         }
     110             : 
     111           0 :         while (num_sent != (state->pass_count + state->fail_count)) {
     112           0 :                 tevent_loop_once(tctx->ev);
     113             :         }
     114             : 
     115           0 :         printf("%.1f queries per second (%d failures)  \n", 
     116           0 :                state->pass_count / timeval_elapsed(&tv),
     117             :                state->fail_count);
     118             : 
     119           0 :         talloc_free(cldap);
     120           0 :         return true;
     121             : }
     122             : 
     123           0 : static void request_rootdse_handler(struct tevent_req *req)
     124             : {
     125           0 :         struct cldap_search io;
     126           0 :         struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
     127           0 :         NTSTATUS status;
     128           0 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     129           0 :         status = cldap_search_recv(req, tmp_ctx, &io);
     130           0 :         talloc_free(req);
     131           0 :         if (NT_STATUS_IS_OK(status)) {
     132           0 :                 state->pass_count++;
     133             :         } else {
     134           0 :                 state->fail_count++;
     135             :         }
     136           0 :         talloc_free(tmp_ctx);
     137           0 : }
     138             : 
     139             : /*
     140             :   benchmark cldap netlogon calls
     141             : */
     142           0 : static bool bench_cldap_rootdse(struct torture_context *tctx, const char *address)
     143             : {
     144           0 :         struct cldap_socket *cldap;
     145           0 :         int num_sent=0;
     146           0 :         struct timeval tv = timeval_current();
     147           0 :         int timelimit = torture_setting_int(tctx, "timelimit", 10);
     148           0 :         struct cldap_search search;
     149           0 :         struct bench_state *state;
     150           0 :         NTSTATUS status;
     151           0 :         struct tsocket_address *dest_addr;
     152           0 :         int ret;
     153             : 
     154           0 :         ret = tsocket_address_inet_from_strings(tctx, "ip",
     155             :                                                 address,
     156             :                                                 lpcfg_cldap_port(tctx->lp_ctx),
     157             :                                                 &dest_addr);
     158           0 :         CHECK_VAL(ret, 0);
     159             : 
     160             :         /* cldap_socket_init should now know about the dest. address */
     161           0 :         status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
     162           0 :         torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
     163             : 
     164           0 :         state = talloc_zero(tctx, struct bench_state);
     165             : 
     166           0 :         ZERO_STRUCT(search);
     167           0 :         search.in.dest_address  = NULL;
     168           0 :         search.in.dest_port     = 0;
     169           0 :         search.in.filter        = "(objectClass=*)";
     170           0 :         search.in.timeout       = 2;
     171           0 :         search.in.retries       = 1;
     172             : 
     173           0 :         printf("Running CLDAP/rootdse for %d seconds\n", timelimit);
     174           0 :         while (timeval_elapsed(&tv) < timelimit) {
     175           0 :                 while (num_sent - (state->pass_count+state->fail_count) < 10) {
     176           0 :                         struct tevent_req *req;
     177           0 :                         req = cldap_search_send(state, tctx->ev, cldap, &search);
     178             : 
     179           0 :                         tevent_req_set_callback(req, request_rootdse_handler, state);
     180             : 
     181           0 :                         num_sent++;
     182           0 :                         if (num_sent % 50 == 0) {
     183           0 :                                 if (torture_setting_bool(tctx, "progress", true)) {
     184           0 :                                         printf("%.1f queries per second (%d failures)  \r",
     185           0 :                                                state->pass_count / timeval_elapsed(&tv),
     186             :                                                state->fail_count);
     187           0 :                                         fflush(stdout);
     188             :                                 }
     189             :                         }
     190             :                 }
     191             : 
     192           0 :                 tevent_loop_once(tctx->ev);
     193             :         }
     194             : 
     195           0 :         while (num_sent != (state->pass_count + state->fail_count)) {
     196           0 :                 tevent_loop_once(tctx->ev);
     197             :         }
     198             : 
     199           0 :         printf("%.1f queries per second (%d failures)  \n",
     200           0 :                state->pass_count / timeval_elapsed(&tv),
     201             :                state->fail_count);
     202             : 
     203           0 :         talloc_free(cldap);
     204           0 :         return true;
     205             : }
     206             : 
     207             : /*
     208             :   benchmark how fast a CLDAP server can respond to a series of parallel
     209             :   requests 
     210             : */
     211           0 : bool torture_bench_cldap(struct torture_context *torture)
     212             : {
     213           0 :         const char *address;
     214           0 :         struct nbt_name name;
     215           0 :         NTSTATUS status;
     216           0 :         bool ret = true;
     217             :         
     218           0 :         make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));
     219             : 
     220             :         /* do an initial name resolution to find its IP */
     221           0 :         status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
     222             :                                  0, 0, &name, torture, &address, torture->ev);
     223           0 :         if (!NT_STATUS_IS_OK(status)) {
     224           0 :                 printf("Failed to resolve %s - %s\n",
     225             :                        name.name, nt_errstr(status));
     226           0 :                 return false;
     227             :         }
     228             : 
     229           0 :         ret &= bench_cldap_netlogon(torture, address);
     230           0 :         ret &= bench_cldap_rootdse(torture, address);
     231             : 
     232           0 :         return ret;
     233             : }

Generated by: LCOV version 1.14