handle incomplete load files
[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
23 int nbench_line_count = 0;
24 static int timelimit = 600;
25 static char *loadfile;
26
27 #define ival(s) strtol(s, NULL, 0)
28
29 /* run a test that simulates an approximate netbench client load */
30 static BOOL run_netbench(struct cli_state *cli, int client)
31 {
32         int i;
33         pstring line;
34         char *cname;
35         FILE *f;
36         fstring params[20];
37         const char *p;
38         BOOL correct = True;
39
40         nb_setup(cli, client);
41
42         asprintf(&cname, "client%d", client);
43
44         f = fopen(loadfile, "r");
45
46         if (!f) {
47                 perror(loadfile);
48                 return False;
49         }
50
51 again:
52         while (fgets(line, sizeof(line)-1, f)) {
53                 NTSTATUS status;
54
55                 if (end_timer() >= timelimit) {
56                         goto done;
57                 }
58
59                 nbench_line_count++;
60
61                 line[strlen(line)-1] = 0;
62
63                 all_string_sub(line,"client1", cname, sizeof(line));
64                 
65                 p = line;
66                 for (i=0; 
67                      i<19 && next_token(&p, params[i], " ", sizeof(fstring));
68                      i++) ;
69
70                 params[i][0] = 0;
71
72                 if (i < 2 || params[0][0] == '#') continue;
73
74                 if (!strncmp(params[0],"SMB", 3)) {
75                         printf("ERROR: You are using a dbench 1 load file\n");
76                         exit(1);
77                 }
78
79                 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0) {
80                         printf("Badly formed status at line %d\n", nbench_line_count);
81                         continue;
82                 }
83
84                 status = nt_status_string_to_code(params[i-1]);
85
86                 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
87
88                 if (!strcmp(params[0],"NTCreateX")) {
89                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
90                                    ival(params[4]), status);
91                 } else if (!strcmp(params[0],"Close")) {
92                         nb_close(ival(params[1]), status);
93                 } else if (!strcmp(params[0],"Rename")) {
94                         nb_rename(params[1], params[2], status);
95                 } else if (!strcmp(params[0],"Unlink")) {
96                         nb_unlink(params[1], ival(params[2]), status);
97                 } else if (!strcmp(params[0],"Deltree")) {
98                         nb_deltree(params[1]);
99                 } else if (!strcmp(params[0],"Rmdir")) {
100                         nb_rmdir(params[1], status);
101                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
102                         nb_qpathinfo(params[1], ival(params[2]), status);
103                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
104                         nb_qfileinfo(ival(params[1]), ival(params[2]), status);
105                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
106                         nb_qfsinfo(ival(params[1]), status);
107                 } else if (!strcmp(params[0],"SET_FILE_INFORMATION")) {
108                         nb_sfileinfo(ival(params[1]), ival(params[2]), status);
109                 } else if (!strcmp(params[0],"FIND_FIRST")) {
110                         nb_findfirst(params[1], ival(params[2]), 
111                                      ival(params[3]), ival(params[4]), status);
112                 } else if (!strcmp(params[0],"WriteX")) {
113                         nb_writex(ival(params[1]), 
114                                   ival(params[2]), ival(params[3]), ival(params[4]),
115                                   status);
116                 } else if (!strcmp(params[0],"Write")) {
117                         nb_write(ival(params[1]), 
118                                  ival(params[2]), ival(params[3]), ival(params[4]),
119                                  status);
120                 } else if (!strcmp(params[0],"LockX")) {
121                         nb_lockx(ival(params[1]), 
122                                  ival(params[2]), ival(params[3]), status);
123                 } else if (!strcmp(params[0],"UnlockX")) {
124                         nb_unlockx(ival(params[1]), 
125                                  ival(params[2]), ival(params[3]), status);
126                 } else if (!strcmp(params[0],"ReadX")) {
127                         nb_readx(ival(params[1]), 
128                                  ival(params[2]), ival(params[3]), ival(params[4]),
129                                  status);
130                 } else if (!strcmp(params[0],"Flush")) {
131                         nb_flush(ival(params[1]), status);
132                 } else {
133                         printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
134                 }
135         }
136
137         rewind(f);
138         goto again;
139
140 done:
141         fclose(f);
142         nb_cleanup(cname);
143
144         if (!torture_close_connection(cli)) {
145                 correct = False;
146         }
147         
148         return correct;
149 }
150
151
152 /* run a test that simulates an approximate netbench client load */
153 BOOL torture_nbench(int dummy)
154 {
155         double t;
156         BOOL correct = True;
157         extern int torture_nprocs;
158         struct cli_state *cli;
159         char *p;
160
161         p = lp_parm_string(-1, "torture", "timelimit");
162         if (p && *p) {
163                 timelimit = atoi(p);
164         }
165
166         loadfile =  lp_parm_string(-1, "torture", "loadfile");
167         if (!loadfile || !*loadfile) {
168                 loadfile = "client.txt";
169         }
170
171         if (!torture_open_connection(&cli)) {
172                 return False;
173         }
174
175         nb_setup(cli, -1);
176         nb_deltree("\\clients");
177
178         nbio_shmem(torture_nprocs);
179
180         printf("Running for %d seconds with load '%s'\n", timelimit, loadfile);
181
182         signal(SIGALRM, SIGNAL_CAST nb_alarm);
183         alarm(1);
184         t = torture_create_procs(run_netbench, &correct);
185         alarm(0);
186
187         printf("\nThroughput %g MB/sec\n", 
188                1.0e-6 * nbio_total() / t);
189         return correct;
190 }