docs: Fix variable list in man vfs_crossrename.
[Samba.git] / source4 / torture / smbtorture.c
blob62cf0abfb7072786deeccc6e6cac38b51d14d215
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-2003
5 Copyright (C) Jelmer Vernooij 2006-2008
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "lib/cmdline/popt_common.h"
23 #include "system/time.h"
24 #include "system/wait.h"
25 #include "system/filesys.h"
26 #include "system/readline.h"
27 #include "../libcli/smbreadline/smbreadline.h"
28 #include "libcli/libcli.h"
29 #include "lib/events/events.h"
31 #include "torture/smbtorture.h"
32 #include "librpc/rpc/dcerpc.h"
33 #include "auth/gensec/gensec.h"
34 #include "param/param.h"
36 #if HAVE_READLINE_HISTORY_H
37 #include <readline/history.h>
38 #endif
40 static char *prefix_name(TALLOC_CTX *mem_ctx, const char *prefix, const char *name)
42 if (prefix == NULL)
43 return talloc_strdup(mem_ctx, name);
44 else
45 return talloc_asprintf(mem_ctx, "%s.%s", prefix, name);
48 static void print_test_list(const struct torture_suite *suite, const char *prefix, const char *expr)
50 struct torture_suite *o;
51 struct torture_tcase *t;
52 struct torture_test *p;
54 for (o = suite->children; o; o = o->next) {
55 char *name = prefix_name(NULL, prefix, o->name);
56 print_test_list(o, name, expr);
57 talloc_free(name);
60 for (t = suite->testcases; t; t = t->next) {
61 for (p = t->tests; p; p = p->next) {
62 char *name = talloc_asprintf(NULL, "%s.%s.%s", prefix, t->name, p->name);
63 if (strncmp(name, expr, strlen(expr)) == 0) {
64 printf("%s\n", name);
66 talloc_free(name);
71 static bool run_matching(struct torture_context *torture,
72 const char *prefix,
73 const char *expr,
74 const char **restricted,
75 struct torture_suite *suite,
76 bool *matched)
78 bool ret = true;
79 struct torture_suite *o;
80 struct torture_tcase *t;
81 struct torture_test *p;
83 for (o = suite->children; o; o = o->next) {
84 char *name = NULL;
85 name = prefix_name(torture, prefix, o->name);
86 if (gen_fnmatch(expr, name) == 0) {
87 *matched = true;
88 reload_charcnv(torture->lp_ctx);
89 if (restricted != NULL)
90 ret &= torture_run_suite_restricted(torture, o, restricted);
91 else
92 ret &= torture_run_suite(torture, o);
94 ret &= run_matching(torture, name, expr, restricted, o, matched);
97 for (t = suite->testcases; t; t = t->next) {
98 char *name = talloc_asprintf(torture, "%s.%s", prefix, t->name);
99 if (gen_fnmatch(expr, name) == 0) {
100 *matched = true;
101 reload_charcnv(torture->lp_ctx);
102 ret &= torture_run_tcase_restricted(torture, t, restricted);
104 for (p = t->tests; p; p = p->next) {
105 name = talloc_asprintf(torture, "%s.%s.%s", prefix, t->name, p->name);
106 if (gen_fnmatch(expr, name) == 0) {
107 *matched = true;
108 reload_charcnv(torture->lp_ctx);
109 ret &= torture_run_test_restricted(torture, t, p, restricted);
114 return ret;
117 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
119 /****************************************************************************
120 run a specified test or "ALL"
121 ****************************************************************************/
122 bool torture_run_named_tests(struct torture_context *torture, const char *name,
123 const char **restricted)
125 bool ret = true;
126 bool matched = false;
127 struct torture_suite *o;
129 torture_ui_report_time(torture);
131 if (strequal(name, "ALL")) {
132 if (restricted != NULL) {
133 printf("--load-list and ALL are incompatible\n");
134 return false;
136 for (o = torture_root->children; o; o = o->next) {
137 ret &= torture_run_suite(torture, o);
139 return ret;
142 ret = run_matching(torture, NULL, name, restricted, torture_root, &matched);
144 if (!matched) {
145 printf("Unknown torture operation '%s'\n", name);
146 return false;
149 return ret;
152 bool torture_parse_target(struct loadparm_context *lp_ctx, const char *target)
154 char *host = NULL, *share = NULL;
155 struct dcerpc_binding *binding_struct;
156 NTSTATUS status;
158 /* see if its a RPC transport specifier */
159 if (!smbcli_parse_unc(target, NULL, &host, &share)) {
160 status = dcerpc_parse_binding(talloc_autofree_context(), target, &binding_struct);
161 if (NT_STATUS_IS_ERR(status)) {
162 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
163 return false;
165 lpcfg_set_cmdline(lp_ctx, "torture:host", binding_struct->host);
166 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
167 lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
168 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
169 } else {
170 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
171 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
172 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
175 return true;
178 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
180 char *userdn, *basedn, *secret;
181 char *p, *d;
183 /* retrievieng the userdn */
184 p = strchr_m(dns, '#');
185 if (!p) {
186 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
187 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
188 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
189 return;
191 userdn = strndup(dns, p - dns);
192 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
194 /* retrieve the basedn */
195 d = p + 1;
196 p = strchr_m(d, '#');
197 if (!p) {
198 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
199 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
200 return;
202 basedn = strndup(d, p - d);
203 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
205 /* retrieve the secret */
206 p = p + 1;
207 if (!p) {
208 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
209 return;
211 secret = strdup(p);
212 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
214 printf ("%s - %s - %s\n", userdn, basedn, secret);
218 /* Print the full test list, formatted into separate labelled test
219 * groups.
221 static void print_structured_testsuite_list(void)
223 struct torture_suite *o;
224 struct torture_suite *s;
225 struct torture_tcase *t;
226 int i;
228 if (torture_root == NULL) {
229 printf("NO TESTS LOADED\n");
230 return;
233 for (o = torture_root->children; o; o = o->next) {
234 printf("\n%s (%s):\n ", o->description, o->name);
236 i = 0;
237 for (s = o->children; s; s = s->next) {
238 if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
239 printf("\n ");
240 i = 0;
242 i+=printf("%s.%s ", o->name, s->name);
245 for (t = o->testcases; t; t = t->next) {
246 if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
247 printf("\n ");
248 i = 0;
250 i+=printf("%s.%s ", o->name, t->name);
253 if (i) printf("\n");
256 printf("\nThe default test is ALL.\n");
259 static void print_testsuite_list(void)
261 struct torture_suite *o;
262 struct torture_suite *s;
263 struct torture_tcase *t;
265 if (torture_root == NULL)
266 return;
268 for (o = torture_root->children; o; o = o->next) {
269 for (s = o->children; s; s = s->next) {
270 printf("%s.%s\n", o->name, s->name);
273 for (t = o->testcases; t; t = t->next) {
274 printf("%s.%s\n", o->name, t->name);
279 void torture_print_testsuites(bool structured)
281 if (structured) {
282 print_structured_testsuite_list();
283 } else {
284 print_testsuite_list();
288 static void usage(poptContext pc)
290 poptPrintUsage(pc, stdout, 0);
291 printf("\n");
293 printf("The binding format is:\n\n");
295 printf(" TRANSPORT:host[flags]\n\n");
297 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
298 printf(" or ncalrpc for local connections.\n\n");
300 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
301 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
302 printf(" string.\n\n");
304 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
305 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
306 printf(" will be auto-determined.\n\n");
308 printf(" other recognised flags are:\n\n");
310 printf(" sign : enable ntlmssp signing\n");
311 printf(" seal : enable ntlmssp sealing\n");
312 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
313 printf(" validate: enable the NDR validator\n");
314 printf(" print: enable debugging of the packets\n");
315 printf(" bigendian: use bigendian RPC\n");
316 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
318 printf(" For example, these all connect to the samr pipe:\n\n");
320 printf(" ncacn_np:myserver\n");
321 printf(" ncacn_np:myserver[samr]\n");
322 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
323 printf(" ncacn_np:myserver[/pipe/samr]\n");
324 printf(" ncacn_np:myserver[samr,sign,print]\n");
325 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
326 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
327 printf(" ncacn_np:\n");
328 printf(" ncacn_np:[/pipe/samr]\n\n");
330 printf(" ncacn_ip_tcp:myserver\n");
331 printf(" ncacn_ip_tcp:myserver[1024]\n");
332 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
334 printf(" ncalrpc:\n\n");
336 printf("The UNC format is:\n\n");
338 printf(" //server/share\n\n");
340 printf("Tests are:");
342 print_structured_testsuite_list();
346 _NORETURN_ static void max_runtime_handler(int sig)
348 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
349 exit(1);
352 struct timeval last_suite_started;
354 static void simple_suite_start(struct torture_context *ctx,
355 struct torture_suite *suite)
357 last_suite_started = timeval_current();
358 printf("Running %s\n", suite->name);
361 static void simple_suite_finish(struct torture_context *ctx,
362 struct torture_suite *suite)
365 printf("%s took %g secs\n\n", suite->name,
366 timeval_elapsed(&last_suite_started));
369 static void simple_test_result(struct torture_context *context,
370 enum torture_result res, const char *reason)
372 switch (res) {
373 case TORTURE_OK:
374 if (reason)
375 printf("OK: %s\n", reason);
376 break;
377 case TORTURE_FAIL:
378 printf("TEST %s FAILED! - %s\n", context->active_test->name, reason);
379 break;
380 case TORTURE_ERROR:
381 printf("ERROR IN TEST %s! - %s\n", context->active_test->name, reason);
382 break;
383 case TORTURE_SKIP:
384 printf("SKIP: %s - %s\n", context->active_test->name, reason);
385 break;
389 static void simple_comment(struct torture_context *test,
390 const char *comment)
392 printf("%s", comment);
395 static void simple_warning(struct torture_context *test,
396 const char *comment)
398 fprintf(stderr, "WARNING: %s\n", comment);
401 static void simple_progress(struct torture_context *test,
402 int offset, enum torture_progress_whence whence)
406 const static struct torture_ui_ops std_ui_ops = {
407 .comment = simple_comment,
408 .warning = simple_warning,
409 .suite_start = simple_suite_start,
410 .suite_finish = simple_suite_finish,
411 .test_result = simple_test_result,
412 .progress = simple_progress,
415 /****************************************************************************
416 main program
417 ****************************************************************************/
418 int main(int argc,char *argv[])
420 int opt, i;
421 bool correct = true;
422 int max_runtime=0;
423 int argc_new;
424 struct torture_context *torture;
425 struct torture_results *results;
426 const struct torture_ui_ops *ui_ops;
427 char **argv_new;
428 poptContext pc;
429 static const char *target = "other";
430 NTSTATUS status;
431 int shell = false;
432 static const char *ui_ops_name = "subunit";
433 const char *basedir = NULL;
434 char *outputdir;
435 const char *extra_module = NULL;
436 static int list_tests = 0, list_testsuites = 0;
437 int num_extra_users = 0;
438 char **restricted = NULL;
439 int num_restricted = -1;
440 const char *load_list = NULL;
441 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
442 OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,
443 OPT_EXTRA_USER,};
445 struct poptOption long_options[] = {
446 POPT_AUTOHELP
447 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
448 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
449 {"basedir", 0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
450 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "Seed to use for randomizer", NULL},
451 {"num-progs", 0, POPT_ARG_INT, NULL, OPT_NUMPROGS, "num progs", NULL},
452 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
453 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
454 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "NBench load file to use", NULL},
455 {"list-suites", 0, POPT_ARG_NONE, &list_testsuites, 0, "List available testsuites and exit", NULL },
456 {"list", 0, POPT_ARG_NONE, &list_tests, 0, "List available tests in specified suites and exit", NULL },
457 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
458 {"timelimit", 't', POPT_ARG_INT, NULL, OPT_TIMELIMIT, "Set time limit (in seconds)", NULL},
459 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
460 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
461 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS,
462 "run dangerous tests (eg. wiping out password database)", NULL},
463 {"load-module", 0, POPT_ARG_STRING, &extra_module, 0, "load tests from DSO file", "SOFILE"},
464 {"shell", 0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
465 {"target", 'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
466 {"async", 'a', POPT_ARG_NONE, NULL, OPT_ASYNC,
467 "run async tests", NULL},
468 {"num-async", 0, POPT_ARG_INT, &torture_numasync, 0,
469 "number of simultaneous async requests", NULL},
470 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
471 "set maximum time for smbtorture to live", "seconds"},
472 {"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
473 "extra user credentials", NULL},
474 {"load-list", 0, POPT_ARG_STRING, &load_list, 0,
475 "load a test id list from a text file", NULL},
476 POPT_COMMON_SAMBA
477 POPT_COMMON_CONNECTION
478 POPT_COMMON_CREDENTIALS
479 POPT_COMMON_VERSION
480 { NULL }
483 setlinebuf(stdout);
485 /* we are never interested in SIGPIPE */
486 BlockSignals(true, SIGPIPE);
488 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
489 POPT_CONTEXT_KEEP_FIRST);
491 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
493 while((opt = poptGetNextOpt(pc)) != -1) {
494 switch (opt) {
495 case OPT_LOADFILE:
496 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:loadfile", poptGetOptArg(pc));
497 break;
498 case OPT_UNCLIST:
499 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc));
500 break;
501 case OPT_TIMELIMIT:
502 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:timelimit", poptGetOptArg(pc));
503 break;
504 case OPT_NUMPROGS:
505 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:nprocs", poptGetOptArg(pc));
506 break;
507 case OPT_DNS:
508 parse_dns(cmdline_lp_ctx, poptGetOptArg(pc));
509 break;
510 case OPT_DANGEROUS:
511 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:dangerous", "Yes");
512 break;
513 case OPT_ASYNC:
514 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:async", "Yes");
515 break;
516 case OPT_SMB_PORTS:
517 lpcfg_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
518 break;
519 case OPT_EXTRA_USER:
521 char *option = talloc_asprintf(NULL, "torture:extra_user%u",
522 ++num_extra_users);
523 const char *value = poptGetOptArg(pc);
524 lpcfg_set_cmdline(cmdline_lp_ctx, option, value);
525 talloc_free(option);
527 break;
528 default:
529 if (opt < 0) {
530 printf("bad command line option %d\n", opt);
531 exit(1);
536 if (load_list != NULL) {
537 restricted = file_lines_load(load_list, &num_restricted, 0,
538 talloc_autofree_context());
539 if (restricted == NULL) {
540 printf("Unable to read load list file '%s'\n", load_list);
541 exit(1);
545 if (strcmp(target, "samba3") == 0) {
546 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba3", "true");
547 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
548 } else if (strcmp(target, "samba4") == 0) {
549 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
550 } else if (strcmp(target, "winxp") == 0) {
551 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:winxp", "true");
552 } else if (strcmp(target, "w2k3") == 0) {
553 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k3", "true");
554 } else if (strcmp(target, "w2k8") == 0) {
555 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k8", "true");
556 lpcfg_set_cmdline(cmdline_lp_ctx,
557 "torture:invalid_lock_range_support", "false");
558 } else if (strcmp(target, "win7") == 0) {
559 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:win7", "true");
560 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:cn_max_buffer_size",
561 "0x00010000");
562 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
563 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
565 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
566 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_support", "false");
568 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:hide_on_access_denied",
569 "true");
570 } else if (strcmp(target, "onefs") == 0) {
571 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:onefs", "true");
572 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:openx_deny_dos_support",
573 "false");
574 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:range_not_locked_on_file_close", "false");
575 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:sacl_support", "false");
576 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:ea_support", "false");
577 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smbexit_pdu_support",
578 "false");
579 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smblock_pdu_support",
580 "false");
581 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:2_step_break_to_none",
582 "true");
583 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_dos_support", "false");
584 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_fcb_support", "false");
585 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:read_support", "false");
586 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:writeclose_support", "false");
587 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
588 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
589 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:raw_search_search", "false");
590 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_size", "false");
593 if (max_runtime) {
594 /* this will only work if nobody else uses alarm(),
595 which means it won't work for some tests, but we
596 can't use the event context method we use for smbd
597 as so many tests create their own event
598 context. This will at least catch most cases. */
599 signal(SIGALRM, max_runtime_handler);
600 alarm(max_runtime);
603 if (extra_module != NULL) {
604 init_module_fn fn = load_module(talloc_autofree_context(), poptGetOptArg(pc));
606 if (fn == NULL)
607 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
608 else {
609 status = fn();
610 if (NT_STATUS_IS_ERR(status)) {
611 d_printf("Error initializing module %s: %s\n",
612 poptGetOptArg(pc), nt_errstr(status));
615 } else {
616 torture_init();
619 if (list_testsuites) {
620 print_testsuite_list();
621 return 0;
624 argv_new = discard_const_p(char *, poptGetArgs(pc));
626 argc_new = argc;
627 for (i=0; i<argc; i++) {
628 if (argv_new[i] == NULL) {
629 argc_new = i;
630 break;
634 if (list_tests) {
635 if (argc_new == 1) {
636 print_test_list(torture_root, NULL, "");
637 } else {
638 for (i=1;i<argc_new;i++) {
639 print_test_list(torture_root, NULL, argv_new[i]);
642 return 0;
645 if (torture_seed == 0) {
646 torture_seed = time(NULL);
648 printf("Using seed %d\n", torture_seed);
649 srandom(torture_seed);
651 if (!strcmp(ui_ops_name, "simple")) {
652 ui_ops = &std_ui_ops;
653 } else if (!strcmp(ui_ops_name, "subunit")) {
654 ui_ops = &torture_subunit_ui_ops;
655 } else {
656 printf("Unknown output format '%s'\n", ui_ops_name);
657 exit(1);
660 results = torture_results_init(talloc_autofree_context(), ui_ops);
662 torture = torture_context_init(s4_event_context_init(talloc_autofree_context()),
663 results);
664 if (basedir != NULL) {
665 if (basedir[0] != '/') {
666 fprintf(stderr, "Please specify an absolute path to --basedir\n");
667 return 1;
669 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
670 } else {
671 char *pwd = talloc_size(torture, PATH_MAX);
672 if (!getcwd(pwd, PATH_MAX)) {
673 fprintf(stderr, "Unable to determine current working directory\n");
674 return 1;
676 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
678 if (!outputdir) {
679 fprintf(stderr, "Could not allocate per-run output dir\n");
680 return 1;
682 torture->outputdir = mkdtemp(outputdir);
683 if (!torture->outputdir) {
684 perror("Failed to make temp output dir");
687 torture->lp_ctx = cmdline_lp_ctx;
689 gensec_init(cmdline_lp_ctx);
691 if (shell) {
692 /* In shell mode, just ignore any remaining test names. */
693 torture_shell(torture);
694 } else {
696 /* At this point, we should just have a target string,
697 * followed by a series of test names. Unless we are in
698 * shell mode, in which case we don't need anythig more.
701 if (argc_new < 3) {
702 printf("You must specify a test to run, or 'ALL'\n");
703 usage(pc);
704 torture->results->returncode = 1;
705 } else if (!torture_parse_target(cmdline_lp_ctx, argv_new[1])) {
706 /* Take the target name or binding. */
707 usage(pc);
708 torture->results->returncode = 1;
709 } else {
710 for (i=2;i<argc_new;i++) {
711 if (!torture_run_named_tests(torture, argv_new[i],
712 (const char **)restricted)) {
713 correct = false;
719 /* Now delete the temp dir we created */
720 torture_deltree_outputdir(torture);
722 if (torture->results->returncode && correct) {
723 return(0);
724 } else {
725 return(1);