1 /*
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2005, 2013 Oracle and/or its affiliates.  All rights reserved.
5  *
6  * $Id$
7  */
8 
9 #include "bench.h"
10 
11 int main __P((int, char *[]));
12 
13 static int  run __P((char *));
14 static int  usage __P((void));
15 
16 char *progname;					/* program name */
17 db_timespec __start_time, __end_time;		/* TIMER_START & TIMER_END */
18 
19 static int test_start = 1;			/* first test to run */
20 static int test_end = 0;			/* last test to run */
21 
22 static struct {
23 	char *name;				/* command name */
24 	int (*f)(int, char *[]);		/* function */
25 } cmdlist[] = {
26 	{ "b_curalloc", b_curalloc },
27 	{ "b_curwalk", b_curwalk },
28 	{ "b_del", b_del },
29 	{ "b_get", b_get },
30 	{ "b_inmem", b_inmem },
31 	{ "b_latch", b_latch },
32 	{ "b_load", b_load },
33 	{ "b_open", b_open },
34 	{ "b_put", b_put },
35 	{ "b_recover", b_recover },
36 	{ "b_txn", b_txn },
37 	{ "b_txn_write", b_txn_write },
38 	{ "b_workload", b_workload },
39 	{ NULL, NULL }
40 };
41 
42 int
main(argc,argv)43 main(argc, argv)
44 	int argc;
45 	char *argv[];
46 {
47 	extern char *optarg;
48 	extern int optind;
49 	int ch, ret;
50 	char *run_directory, *ifile;
51 
52 	if ((progname = __db_rpath(argv[0])) == NULL)
53 		progname = argv[0];
54 	else
55 		++progname;
56 
57 	run_directory = NULL;
58 	ifile = "run.std";
59 	while ((ch = getopt(argc, argv, "d:e:i:s:")) != EOF)
60 		switch (ch) {
61 		case 'd':
62 			run_directory = optarg;
63 			break;
64 		case 'e':
65 			test_end = atoi(optarg);
66 			break;
67 		case 'i':
68 			ifile = optarg;
69 			break;
70 		case 's':
71 			test_start = atoi(optarg);
72 			break;
73 		case '?':
74 		default:
75 			return (usage());
76 		}
77 	argc -= optind;
78 	argv += optind;
79 
80 	/* Run in the target directory. */
81 	if (run_directory != NULL && chdir(run_directory) != 0) {
82 		fprintf(stderr,
83 		    "%s: %s: %s\n", progname, run_directory, strerror(errno));
84 		return (1);
85 	}
86 
87 	/* Clean up any left-over test directory. */
88 	if (b_util_dir_teardown())
89 		return (1);
90 
91 	ret = run(ifile);
92 
93 	return (ret ? EXIT_FAILURE : EXIT_SUCCESS);
94 }
95 
96 /*
97  * run --
98  *	Read a configuration file and run the tests.
99  */
100 static int
run(ifile)101 run(ifile)
102 	char *ifile;
103 {
104 #ifdef HAVE_GETOPT_OPTRESET
105 	extern int optreset;
106 #endif
107 	extern int optind;
108 	static int test_cur = 0;
109 	FILE *ifp;
110 	int argc, cmdindx, lineno, ret;
111 	char *p, cmd[1024], path[1024], **argv;
112 
113 	/* Identify the run. */
114 	if (b_uname() != 0)
115 		return (1);
116 
117 	/* Open the list of tests. */
118 	if ((ifp = fopen(ifile, "r")) == NULL) {
119 		fprintf(stderr,
120 		    "%s: %s: %s\n", progname, ifile, strerror(errno));
121 		return (1);
122 	}
123 
124 	for (lineno = 1; fgets(cmd, sizeof(cmd), ifp) != NULL; ++lineno) {
125 		/*
126 		 * Nul-terminate the command line; check for a trailing \r
127 		 * on Windows.
128 		 */
129 		if ((p = strchr(cmd, '\n')) == NULL) {
130 format_err:		fprintf(stderr, "%s: %s: line %d: illegal input\n",
131 			    progname, ifile, lineno);
132 			return (1);
133 		}
134 		if (p > cmd && p[-1] == '\r')
135 			--p;
136 		*p = '\0';
137 
138 		/* Skip empty lines and comments. */
139 		if (cmd[0] == '\0' || cmd[0] == '#')
140 			continue;
141 
142 		/* Optionally limit the test run to specific tests. */
143 		if (++test_cur < test_start ||
144 		    (test_end != 0 && test_cur > test_end))
145 			continue;
146 
147 		fprintf(stderr, "%d: %s\n", test_cur, cmd);
148 
149 		/* Find the command. */
150 		if ((p = strchr(cmd, ' ')) == NULL)
151 			goto format_err;
152 		*p++ = '\0';
153 		for (cmdindx = 0; cmdlist[cmdindx].name != NULL; ++cmdindx)
154 			if (strcmp(cmd, cmdlist[cmdindx].name) == 0)
155 				break;
156 		if (cmdlist[cmdindx].name == NULL)
157 			goto format_err;
158 
159 		/* Build argc/argv. */
160 		if (__db_util_arg(cmd, p, &argc, &argv) != 0)
161 			return (1);
162 
163 		/* Re-direct output into the test log file.  */
164 		(void)snprintf(path, sizeof(path), "%d", test_cur);
165 		if (freopen(path, "a", stdout) == NULL) {
166 			fprintf(stderr,
167 			    "%s: %s: %s\n", progname, path, strerror(errno));
168 			return (1);
169 		}
170 
171 		/*
172 		 * Each underlying "program" re-parses its arguments --
173 		 * reset getopt.
174 		 */
175 #ifdef HAVE_GETOPT_OPTRESET
176 		optreset = 1;
177 #endif
178 		optind = 1;
179 
180 		/* Prepare the test directory. */
181 		if (b_util_dir_setup())
182 			return (1);
183 
184 		ret = cmdlist[cmdindx].f(argc, argv);
185 
186 		/* Clean up the test directory. */
187 		if (b_util_dir_teardown())
188 			return (1);
189 
190 		(void)fflush(stdout);
191 
192 #if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1
193 		__os_free(NULL, argv, 0);
194 #else
195 		__os_free(NULL, argv);
196 #endif
197 		if (ret != 0)
198 			return (ret);
199 	}
200 
201 	return (0);
202 }
203 
204 static int
usage()205 usage()
206 {
207 	(void)fprintf(stderr,
208 	    "usage: %s [-d directory] [-e end] [-i input] [-s start]\n",
209 	    progname);
210 	return (EXIT_FAILURE);
211 }
212