r16907: Add an index parameter to torture_open_connection. Next step is to enable the
[samba.git] / source / torture / nbench / nbench.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester - NBENCH test
4    Copyright (C) Andrew Tridgell 1997-2004
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "libcli/libcli.h"
23 #include "torture/util.h"
24 #include "torture/torture.h"
25 #include "system/filesys.h"
26 #include "pstring.h"
27
28 #include "torture/nbench/proto.h"
29
30 int nbench_line_count = 0;
31 static int timelimit = 600;
32 static int warmup;
33 static const char *loadfile;
34
35 #define ival(s) strtol(s, NULL, 0)
36
37 /* run a test that simulates an approximate netbench client load */
38 static BOOL run_netbench(struct smbcli_state *cli, int client)
39 {
40         extern int torture_nprocs;
41         int i;
42         pstring line;
43         char *cname;
44         FILE *f;
45         const char **params;
46         BOOL correct = True;
47
48         if (torture_nprocs == 1) {
49                 if (!torture_setup_dir(cli, "\\clients")) {
50                         return False;
51                 }
52         }
53
54         nb_setup(cli, client);
55
56         asprintf(&cname, "client%d", client+1);
57
58         f = fopen(loadfile, "r");
59
60         if (!f) {
61                 perror(loadfile);
62                 return False;
63         }
64
65 again:
66         while (fgets(line, sizeof(line)-1, f)) {
67                 NTSTATUS status;
68
69                 nbench_line_count++;
70
71                 line[strlen(line)-1] = 0;
72
73                 all_string_sub(line,"client1", cname, sizeof(line));
74                 
75                 params = str_list_make_shell(NULL, line, " ");
76                 i = str_list_length(params);
77
78                 if (i < 2 || params[0][0] == '#') continue;
79
80                 if (!strncmp(params[0],"SMB", 3)) {
81                         printf("ERROR: You are using a dbench 1 load file\n");
82                         exit(1);
83                 }
84
85                 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0) {
86                         printf("Badly formed status at line %d\n", nbench_line_count);
87                         talloc_free(params);
88                         continue;
89                 }
90
91                 status = nt_status_string_to_code(params[i-1]);
92
93                 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
94
95                 if (!strcmp(params[0],"NTCreateX")) {
96                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
97                                    ival(params[4]), status);
98                 } else if (!strcmp(params[0],"Close")) {
99                         nb_close(ival(params[1]), status);
100                 } else if (!strcmp(params[0],"Rename")) {
101                         nb_rename(params[1], params[2], status);
102                 } else if (!strcmp(params[0],"Unlink")) {
103                         nb_unlink(params[1], ival(params[2]), status);
104                 } else if (!strcmp(params[0],"Deltree")) {
105                         nb_deltree(params[1]);
106                 } else if (!strcmp(params[0],"Rmdir")) {
107                         nb_rmdir(params[1], status);
108                 } else if (!strcmp(params[0],"Mkdir")) {
109                         nb_mkdir(params[1], status);
110                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
111                         nb_qpathinfo(params[1], ival(params[2]), status);
112                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
113                         nb_qfileinfo(ival(params[1]), ival(params[2]), status);
114                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
115                         nb_qfsinfo(ival(params[1]), status);
116                 } else if (!strcmp(params[0],"SET_FILE_INFORMATION")) {
117                         nb_sfileinfo(ival(params[1]), ival(params[2]), status);
118                 } else if (!strcmp(params[0],"FIND_FIRST")) {
119                         nb_findfirst(params[1], ival(params[2]), 
120                                      ival(params[3]), ival(params[4]), status);
121                 } else if (!strcmp(params[0],"WriteX")) {
122                         nb_writex(ival(params[1]), 
123                                   ival(params[2]), ival(params[3]), ival(params[4]),
124                                   status);
125                 } else if (!strcmp(params[0],"Write")) {
126                         nb_write(ival(params[1]), 
127                                  ival(params[2]), ival(params[3]), ival(params[4]),
128                                  status);
129                 } else if (!strcmp(params[0],"LockX")) {
130                         nb_lockx(ival(params[1]), 
131                                  ival(params[2]), ival(params[3]), status);
132                 } else if (!strcmp(params[0],"UnlockX")) {
133                         nb_unlockx(ival(params[1]), 
134                                  ival(params[2]), ival(params[3]), status);
135                 } else if (!strcmp(params[0],"ReadX")) {
136                         nb_readx(ival(params[1]), 
137                                  ival(params[2]), ival(params[3]), ival(params[4]),
138                                  status);
139                 } else if (!strcmp(params[0],"Flush")) {
140                         nb_flush(ival(params[1]), status);
141                 } else if (!strcmp(params[0],"Sleep")) {
142                         nb_sleep(ival(params[1]), status);
143                 } else {
144                         printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
145                 }
146
147                 talloc_free(params);
148                 
149                 if (nb_tick()) goto done;
150         }
151
152         rewind(f);
153         goto again;
154
155 done:
156         fclose(f);
157
158         if (torture_nprocs == 1) {
159                 smbcli_deltree(cli->tree, "\\clients");
160         }
161         if (!torture_close_connection(cli)) {
162                 correct = False;
163         }
164         
165         return correct;
166 }
167
168
169 /* run a test that simulates an approximate netbench client load */
170 BOOL torture_nbench(struct torture_context *torture)
171 {
172         BOOL correct = True;
173         extern int torture_nprocs;
174         struct smbcli_state *cli;
175         const char *p;
176
177         p = lp_parm_string(-1, "torture", "timelimit");
178         if (p && *p) {
179                 timelimit = atoi(p);
180         }
181
182         warmup = timelimit / 20;
183
184         loadfile =  lp_parm_string(-1, "torture", "loadfile");
185         if (!loadfile || !*loadfile) {
186                 loadfile = "client.txt";
187         }
188
189         if (torture_nprocs > 1) {
190                 if (!torture_open_connection(&cli, 0)) {
191                         return False;
192                 }
193
194                 if (!torture_setup_dir(cli, "\\clients")) {
195                         return False;
196                 }
197         }
198
199         nbio_shmem(torture_nprocs, timelimit, warmup);
200
201         printf("Running for %d seconds with load '%s' and warmup %d secs\n", 
202                timelimit, loadfile, warmup);
203
204         /* we need to reset SIGCHLD here as the name resolution
205            library may have changed it. We rely on correct signals
206            from childs in the main torture code which reaps
207            children. This is why smbtorture BENCH-NBENCH was sometimes
208            failing */
209         signal(SIGCHLD, SIG_DFL);
210
211
212         signal(SIGALRM, nb_alarm);
213         alarm(1);
214         torture_create_procs(run_netbench, &correct);
215         alarm(0);
216
217         if (torture_nprocs > 1) {
218                 smbcli_deltree(cli->tree, "\\clients");
219         }
220
221         printf("\nThroughput %g MB/sec\n", nbio_result());
222         return correct;
223 }
224
225 NTSTATUS torture_nbench_init(void)
226 {
227         register_torture_op("BENCH-NBENCH",  torture_nbench);
228         return NT_STATUS_OK;
229 }