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