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