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