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