r19392: Use torture_setting_* rather than lp_parm_* where possible.
[sfrench/samba-autobuild/.git] / source4 / 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/ui.h"
24 #include "torture/util.h"
25 #include "torture/torture.h"
26 #include "system/filesys.h"
27 #include "pstring.h"
28
29 #include "torture/nbench/proto.h"
30
31 int nbench_line_count = 0;
32 static int timelimit = 600;
33 static int warmup;
34 static const char *loadfile;
35
36 #define ival(s) strtol(s, NULL, 0)
37
38 /* run a test that simulates an approximate netbench client load */
39 static BOOL run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
40 {
41         extern int torture_nprocs;
42         int i;
43         pstring line;
44         char *cname;
45         FILE *f;
46         const char **params;
47         BOOL correct = True;
48
49         if (torture_nprocs == 1) {
50                 if (!torture_setup_dir(cli, "\\clients")) {
51                         return False;
52                 }
53         }
54
55         nb_setup(cli, client);
56
57         asprintf(&cname, "client%d", client+1);
58
59         f = fopen(loadfile, "r");
60
61         if (!f) {
62                 perror(loadfile);
63                 return False;
64         }
65
66 again:
67         while (fgets(line, sizeof(line)-1, f)) {
68                 NTSTATUS status;
69
70                 nbench_line_count++;
71
72                 line[strlen(line)-1] = 0;
73
74                 all_string_sub(line,"client1", cname, sizeof(line));
75                 
76                 params = str_list_make_shell(NULL, line, " ");
77                 i = str_list_length(params);
78
79                 if (i < 2 || params[0][0] == '#') continue;
80
81                 if (!strncmp(params[0],"SMB", 3)) {
82                         printf("ERROR: You are using a dbench 1 load file\n");
83                         exit(1);
84                 }
85
86                 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0) {
87                         printf("Badly formed status at line %d\n", nbench_line_count);
88                         talloc_free(params);
89                         continue;
90                 }
91
92                 status = nt_status_string_to_code(params[i-1]);
93
94                 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
95
96                 if (!strcmp(params[0],"NTCreateX")) {
97                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
98                                    ival(params[4]), status);
99                 } else if (!strcmp(params[0],"Close")) {
100                         nb_close(ival(params[1]), status);
101                 } else if (!strcmp(params[0],"Rename")) {
102                         nb_rename(params[1], params[2], status);
103                 } else if (!strcmp(params[0],"Unlink")) {
104                         nb_unlink(params[1], ival(params[2]), status);
105                 } else if (!strcmp(params[0],"Deltree")) {
106                         nb_deltree(params[1]);
107                 } else if (!strcmp(params[0],"Rmdir")) {
108                         nb_rmdir(params[1], status);
109                 } else if (!strcmp(params[0],"Mkdir")) {
110                         nb_mkdir(params[1], status);
111                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
112                         nb_qpathinfo(params[1], ival(params[2]), status);
113                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
114                         nb_qfileinfo(ival(params[1]), ival(params[2]), status);
115                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
116                         nb_qfsinfo(ival(params[1]), status);
117                 } else if (!strcmp(params[0],"SET_FILE_INFORMATION")) {
118                         nb_sfileinfo(ival(params[1]), ival(params[2]), status);
119                 } else if (!strcmp(params[0],"FIND_FIRST")) {
120                         nb_findfirst(params[1], ival(params[2]), 
121                                      ival(params[3]), ival(params[4]), status);
122                 } else if (!strcmp(params[0],"WriteX")) {
123                         nb_writex(ival(params[1]), 
124                                   ival(params[2]), ival(params[3]), ival(params[4]),
125                                   status);
126                 } else if (!strcmp(params[0],"Write")) {
127                         nb_write(ival(params[1]), 
128                                  ival(params[2]), ival(params[3]), ival(params[4]),
129                                  status);
130                 } else if (!strcmp(params[0],"LockX")) {
131                         nb_lockx(ival(params[1]), 
132                                  ival(params[2]), ival(params[3]), status);
133                 } else if (!strcmp(params[0],"UnlockX")) {
134                         nb_unlockx(ival(params[1]), 
135                                  ival(params[2]), ival(params[3]), status);
136                 } else if (!strcmp(params[0],"ReadX")) {
137                         nb_readx(ival(params[1]), 
138                                  ival(params[2]), ival(params[3]), ival(params[4]),
139                                  status);
140                 } else if (!strcmp(params[0],"Flush")) {
141                         nb_flush(ival(params[1]), status);
142                 } else if (!strcmp(params[0],"Sleep")) {
143                         nb_sleep(ival(params[1]), status);
144                 } else {
145                         printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
146                 }
147
148                 talloc_free(params);
149                 
150                 if (nb_tick()) goto done;
151         }
152
153         rewind(f);
154         goto again;
155
156 done:
157         fclose(f);
158
159         if (torture_nprocs == 1) {
160                 smbcli_deltree(cli->tree, "\\clients");
161         }
162         if (!torture_close_connection(cli)) {
163                 correct = False;
164         }
165         
166         return correct;
167 }
168
169
170 /* run a test that simulates an approximate netbench client load */
171 BOOL torture_nbench(struct torture_context *torture)
172 {
173         BOOL correct = True;
174         extern int torture_nprocs;
175         struct smbcli_state *cli;
176         const char *p;
177
178         p = torture_setting_string(torture, "timelimit", NULL);
179         if (p && *p) {
180                 timelimit = atoi(p);
181         }
182
183         warmup = timelimit / 20;
184
185         loadfile = torture_setting_string(torture, "loadfile", NULL);
186         if (!loadfile || !*loadfile) {
187                 loadfile = "client.txt";
188         }
189
190         if (torture_nprocs > 1) {
191                 if (!torture_open_connection(&cli, 0)) {
192                         return False;
193                 }
194
195                 if (!torture_setup_dir(cli, "\\clients")) {
196                         return False;
197                 }
198         }
199
200         nbio_shmem(torture_nprocs, timelimit, warmup);
201
202         printf("Running for %d seconds with load '%s' and warmup %d secs\n", 
203                timelimit, loadfile, warmup);
204
205         /* we need to reset SIGCHLD here as the name resolution
206            library may have changed it. We rely on correct signals
207            from childs in the main torture code which reaps
208            children. This is why smbtorture BENCH-NBENCH was sometimes
209            failing */
210         signal(SIGCHLD, SIG_DFL);
211
212
213         signal(SIGALRM, nb_alarm);
214         alarm(1);
215         torture_create_procs(torture, run_netbench, &correct);
216         alarm(0);
217
218         if (torture_nprocs > 1) {
219                 smbcli_deltree(cli->tree, "\\clients");
220         }
221
222         printf("\nThroughput %g MB/sec\n", nbio_result());
223         return correct;
224 }
225
226 NTSTATUS torture_nbench_init(void)
227 {
228         struct torture_suite *suite = torture_suite_create(
229                                                                                 talloc_autofree_context(),
230                                                                                 "BENCH");
231
232         torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
233
234         suite->description = talloc_strdup(suite, 
235                                                                 "Benchmarks");
236
237         torture_register_suite(suite);
238         return NT_STATUS_OK;
239 }