]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-tester.c
d1a44e79b1a036f212243df33daa3b6fec1480cb
[openldap] / tests / progs / slapd-tester.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 #include "portable.h"
7
8 #include <stdio.h>
9
10 #include <ac/stdlib.h>
11
12 #include <ac/ctype.h>
13 #include <ac/dirent.h>
14 #include <ac/socket.h>
15 #include <ac/string.h>
16 #include <ac/unistd.h>
17 #include <ac/wait.h>
18
19 #ifdef HAVE_SYS_PARAM_H
20 #include <sys/param.h>
21 #endif
22
23 #include "ldap_defaults.h"
24
25
26 #define SEARCHCMD               "slapd-search"
27 #define READCMD                 "slapd-read"
28 #define ADDCMD                  "slapd-addel"
29 #define MAXARGS         100
30 #define MAXREQS                 20
31 #define LOOPS                   "100"
32
33 #define TSEARCHFILE             "do_search.0"
34 #define TREADFILE               "do_read.0"
35 #define TADDFILE                "do_add."
36
37 static char *get_file_name( char *dirname, char *filename );
38 static int  get_search_filters( char *filename, char *filters[] );
39 static int  get_read_entries( char *filename, char *entries[] );
40 static void fork_child( char *prog, char *args[] );
41 static void     wait4kids( int nkidval );
42
43 static int      maxkids = 20;
44 static int      nkids;
45
46 static void
47 usage( char *name )
48 {
49         fprintf( stderr, "usage: %s [-h <host>] -p <port> -D <manager> -w <passwd> -d <datadir> -b <baseDN> [-j <maxchild>] [-l <loops>] -P <progdir>\n", name );
50         exit( EXIT_FAILURE );
51 }
52
53 int
54 main( int argc, char **argv )
55 {
56         int             i, j;
57         char            *host = "localhost";
58         char            *port = NULL;
59         char            *manager = NULL;
60         char            *passwd = NULL;
61         char            *dirname = NULL;
62         char        *sbase = NULL;
63         char            *progdir = NULL;
64         char            *loops = LOOPS;
65         DIR                     *datadir;
66         struct dirent   *file;
67         char            *sfile = NULL;
68         char            *sreqs[MAXREQS];
69         int         snum = 0;
70         char            *rfile = NULL;
71         char            *rreqs[MAXREQS];
72         int         rnum = 0;
73         char            *afiles[MAXREQS];
74         int         anum = 0;
75         char            *sargs[MAXARGS];
76         int                     sanum;
77         char            scmd[MAXPATHLEN];
78         char            *rargs[MAXARGS];
79         int                     ranum;
80         char            rcmd[MAXPATHLEN];
81         char            *aargs[MAXARGS];
82         int                     aanum;
83         char            acmd[MAXPATHLEN];
84
85         while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:P:" )) != EOF ) {
86                 switch( i ) {
87                         case 'h':               /* slapd host */
88                                 host = strdup( optarg );
89                         break;
90
91                         case 'p':               /* the servers port number */
92                                 port = strdup( optarg );
93                                 break;
94
95                         case 'D':               /* slapd manager */
96                                 manager = strdup( optarg );
97                         break;
98
99                         case 'w':               /* the managers passwd */
100                                 passwd = strdup( optarg );
101                                 break;
102
103                         case 'b':               /* the base DN */
104                                 sbase = strdup( optarg );
105                                 break;
106
107                         case 'd':               /* data directory */
108                                 dirname = strdup( optarg );
109                         break;
110
111                         case 'P':               /* prog directory */
112                                 progdir = strdup( optarg );
113                         break;
114
115                         case 'j':               /* the number of parallel clients */
116                                 maxkids = atoi( optarg );
117                                 break;
118
119                         case 'l':               /* the number of loops per client */
120                                 loops = strdup( optarg );
121                                 break;
122
123                         default:
124                                 usage( argv[0] );
125                                 break;
126                 }
127         }
128
129         if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
130                         ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
131                 usage( argv[0] );
132
133         /* get the file list */
134         if ( ( datadir = opendir( dirname )) == NULL ) {
135
136                 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
137                                         argv[0], dirname );
138                 exit( EXIT_FAILURE );
139
140         }
141
142         /*  look for search, read, and add/delete files */
143         for ( file = readdir( datadir ); file; file = readdir( datadir )) {
144
145                 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
146                         sfile = get_file_name( dirname, file->d_name );
147                         continue;
148                 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
149                         rfile = get_file_name( dirname, file->d_name );
150                         continue;
151                 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
152                         && ( anum < MAXREQS )) {
153                         afiles[anum++] = get_file_name( dirname, file->d_name );
154                         continue;
155                 }
156         }
157
158         closedir( datadir );
159
160         /* look for search requests */
161         if ( sfile ) {
162                 snum = get_search_filters( sfile, sreqs );
163         }
164
165         /* look for read requests */
166         if ( rfile ) {
167                 rnum = get_read_entries( rfile, rreqs );
168         }
169
170         /*
171          * generate the search clients
172          */
173
174         sanum = 0;
175         sprintf( scmd, "%s%s%s", progdir, LDAP_DIRSEP, SEARCHCMD );
176         sargs[sanum++] = scmd;
177         sargs[sanum++] = "-h";
178         sargs[sanum++] = host;
179         sargs[sanum++] = "-p";
180         sargs[sanum++] = port;
181         sargs[sanum++] = "-b";
182         sargs[sanum++] = sbase;
183         sargs[sanum++] = "-l";
184         sargs[sanum++] = loops;
185         sargs[sanum++] = "-f";
186         sargs[sanum++] = NULL;          /* will hold the search request */
187         sargs[sanum++] = NULL;
188
189         /*
190          * generate the read clients
191          */
192
193         ranum = 0;
194         sprintf( rcmd, "%s%s%s", progdir, LDAP_DIRSEP, READCMD );
195         rargs[ranum++] = rcmd;
196         rargs[ranum++] = "-h";
197         rargs[ranum++] = host;
198         rargs[ranum++] = "-p";
199         rargs[ranum++] = port;
200         rargs[ranum++] = "-l";
201         rargs[ranum++] = loops;
202         rargs[ranum++] = "-e";
203         rargs[ranum++] = NULL;          /* will hold the read entry */
204         rargs[ranum++] = NULL;
205
206         /*
207          * generate the add/delete clients
208          */
209
210         aanum = 0;
211         sprintf( acmd, "%s%s%s", progdir, LDAP_DIRSEP, ADDCMD );
212         aargs[aanum++] = acmd;
213         aargs[aanum++] = "-h";
214         aargs[aanum++] = host;
215         aargs[aanum++] = "-p";
216         aargs[aanum++] = port;
217         aargs[aanum++] = "-D";
218         aargs[aanum++] = manager;
219         aargs[aanum++] = "-w";
220         aargs[aanum++] = passwd;
221         aargs[aanum++] = "-l";
222         aargs[aanum++] = loops;
223         aargs[aanum++] = "-f";
224         aargs[aanum++] = NULL;          /* will hold the add data file */
225         aargs[aanum++] = NULL;
226
227         for ( j = 0; j < MAXREQS; j++ ) {
228
229                 if ( j < snum ) {
230
231                         sargs[sanum - 2] = sreqs[j];
232                         fork_child( scmd, sargs );
233
234                 }
235
236                 if ( j < rnum ) {
237
238                         rargs[ranum - 2] = rreqs[j];
239                         fork_child( rcmd, rargs );
240
241                 }
242
243                 if ( j < anum ) {
244
245                         aargs[aanum - 2] = afiles[j];
246                         fork_child( acmd, aargs );
247
248                 }
249
250         }
251
252         wait4kids( -1 );
253
254         exit( EXIT_SUCCESS );
255 }
256
257 static char *
258 get_file_name( char *dirname, char *filename )
259 {
260         char buf[MAXPATHLEN];
261
262         sprintf( buf, "%s%s%s", dirname, LDAP_DIRSEP, filename );
263         return( strdup( buf ));
264 }
265
266
267 static int
268 get_search_filters( char *filename, char *filters[] )
269 {
270         FILE    *fp;
271         int     filter = 0;
272
273         if ( (fp = fopen( filename, "r" )) != NULL ) {
274                 char  line[BUFSIZ];
275
276                 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
277                         char *nl;
278
279                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
280                                 *nl = '\0';
281                         filters[filter++] = strdup( line );
282
283                 }
284                 fclose( fp );
285         }
286
287         return( filter );
288 }
289
290
291 static int
292 get_read_entries( char *filename, char *entries[] )
293 {
294         FILE    *fp;
295         int     entry = 0;
296
297         if ( (fp = fopen( filename, "r" )) != NULL ) {
298                 char  line[BUFSIZ];
299
300                 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
301                         char *nl;
302
303                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
304                                 *nl = '\0';
305                         entries[entry++] = strdup( line );
306
307                 }
308                 fclose( fp );
309         }
310
311         return( entry );
312 }
313
314
315 static void
316 fork_child( char *prog, char *args[] )
317 {
318         pid_t   pid;
319
320         wait4kids( maxkids );
321
322         switch ( pid = fork() ) {
323         case 0:         /* child */
324                 execvp( prog, args );
325                 fprintf( stderr, "%s: ", prog );
326                 perror( "execv" );
327                 exit( EXIT_FAILURE );
328                 break;
329
330         case -1:        /* trouble */
331                 fprintf( stderr, "Could not fork to run %s\n", prog );
332                 perror( "fork" );
333                 break;
334
335         default:        /* parent */
336                 nkids++;
337                 break;
338         }
339 }
340
341 static void
342 wait4kids( int nkidval )
343 {
344         int             status;
345
346         while ( nkids >= nkidval ) {
347                 wait( &status );
348
349                 if ( WIFSTOPPED(status) ) {
350                         fprintf( stderr,
351                             "stopping: child stopped with signal %d\n",
352                             (int) WSTOPSIG(status) );
353
354                 } else if ( WIFSIGNALED(status) ) {
355                         fprintf( stderr, 
356                             "stopping: child terminated with signal %d%s\n",
357                             (int) WTERMSIG(status),
358 #ifdef WCOREDUMP
359                                 WCOREDUMP(status) ? ", core dumped" : ""
360 #else
361                                 ""
362 #endif
363                                 );
364                         exit( WEXITSTATUS(status)  );
365
366                 } else if ( WEXITSTATUS(status) != 0 ) {
367                         fprintf( stderr, 
368                             "stopping: child exited with status %d\n",
369                             (int) WEXITSTATUS(status) );
370                         exit( WEXITSTATUS(status) );
371
372                 } else {
373                         nkids--;
374                 }
375         }
376 }