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