s3:tests: Fix spelling error
[Samba.git] / source4 / torture / smbtorture.c
blob7c5a6f78dbbcd28c64d9ae8c63c6047266d6a822
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/util/util_file.h"
23 #include "lib/cmdline/cmdline.h"
24 #include "system/time.h"
25 #include "system/wait.h"
26 #include "system/filesys.h"
27 #include "system/readline.h"
28 #include "../libcli/smbreadline/smbreadline.h"
29 #include "libcli/libcli.h"
30 #include "lib/events/events.h"
32 #include "torture/smbtorture.h"
33 #include "librpc/rpc/dcerpc.h"
34 #include "auth/gensec/gensec.h"
35 #include "param/param.h"
36 #include "lib/util/samba_modules.h"
38 #ifdef HAVE_READLINE_HISTORY_H
39 #include <readline/history.h>
40 #endif
42 static int use_fullname;
44 static char *prefix_name(TALLOC_CTX *mem_ctx, const char *prefix, const char *name)
46 if (prefix == NULL)
47 return talloc_strdup(mem_ctx, name);
48 else
49 return talloc_asprintf(mem_ctx, "%s.%s", prefix, name);
52 static void print_test_list(const struct torture_suite *suite, const char *prefix, const char *expr)
54 struct torture_suite *o;
55 struct torture_tcase *t;
56 struct torture_test *p;
58 for (o = suite->children; o; o = o->next) {
59 char *name = prefix_name(NULL, prefix, o->name);
60 print_test_list(o, name, expr);
61 talloc_free(name);
64 for (t = suite->testcases; t; t = t->next) {
65 for (p = t->tests; p; p = p->next) {
66 char *name = talloc_asprintf(NULL, "%s.%s.%s", prefix, t->name, p->name);
67 if (strncmp(name, expr, strlen(expr)) == 0) {
68 printf("%s\n", name);
70 talloc_free(name);
75 static bool run_matching(struct torture_context *torture,
76 const char *prefix,
77 const char *expr,
78 const char **restricted,
79 struct torture_suite *suite,
80 bool *matched)
82 bool ret = true;
83 struct torture_suite *o;
84 struct torture_tcase *t;
85 struct torture_test *p;
87 for (o = suite->children; o; o = o->next) {
88 char *name = NULL;
89 name = prefix_name(torture, prefix, o->name);
90 if (gen_fnmatch(expr, name) == 0) {
91 *matched = true;
92 reload_charcnv(torture->lp_ctx);
93 if (use_fullname == 1) {
94 torture_subunit_prefix_reset(torture, prefix);
96 ret &= torture_run_suite_restricted(torture, o, restricted);
97 if (use_fullname == 1) {
98 torture_subunit_prefix_reset(torture, NULL);
101 * torture_run_suite_restricted() already implements
102 * recursion, so we're done with this child suite.
104 continue;
106 ret &= run_matching(torture, name, expr, restricted, o, matched);
109 for (t = suite->testcases; t; t = t->next) {
110 char *tname = prefix_name(torture, prefix, t->name);
111 if (gen_fnmatch(expr, tname) == 0) {
112 *matched = true;
113 reload_charcnv(torture->lp_ctx);
114 if (use_fullname == 1) {
115 torture_subunit_prefix_reset(torture, prefix);
117 ret &= torture_run_tcase_restricted(torture, t, restricted);
118 if (use_fullname == 1) {
119 torture_subunit_prefix_reset(torture, NULL);
122 * torture_run_tcase_restricted() already implements
123 * recursion, so we're done for this tcase.
125 continue;
127 for (p = t->tests; p; p = p->next) {
128 char *pname = prefix_name(torture, tname, p->name);
129 if (gen_fnmatch(expr, pname) == 0) {
130 *matched = true;
131 reload_charcnv(torture->lp_ctx);
132 if (use_fullname == 1) {
133 torture_subunit_prefix_reset(torture,
134 tname);
136 ret &= torture_run_test_restricted(torture, t, p, restricted);
137 if (use_fullname == 1) {
138 torture_subunit_prefix_reset(torture,
139 NULL);
145 return ret;
148 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
150 /****************************************************************************
151 run a specified test or "ALL"
152 ****************************************************************************/
153 bool torture_run_named_tests(struct torture_context *torture, const char *name,
154 const char **restricted)
156 bool ret = true;
157 bool matched = false;
158 struct torture_suite *o;
160 torture_ui_report_time(torture);
162 if (strequal(name, "ALL")) {
163 if (restricted != NULL) {
164 printf("--load-list and ALL are incompatible\n");
165 return false;
167 for (o = torture_root->children; o; o = o->next) {
168 ret &= torture_run_suite(torture, o);
170 return ret;
173 ret = run_matching(torture, NULL, name, restricted, torture_root, &matched);
175 if (!matched) {
176 printf("Unknown torture operation '%s'\n", name);
177 return false;
180 return ret;
183 bool torture_parse_target(TALLOC_CTX *ctx,
184 struct loadparm_context *lp_ctx,
185 const char *target)
187 char *host = NULL, *share = NULL;
188 struct dcerpc_binding *binding_struct;
189 NTSTATUS status;
191 /* see if its a RPC transport specifier */
192 if (!smbcli_parse_unc(target, ctx, &host, &share)) {
193 const char *h;
195 status = dcerpc_parse_binding(ctx, target, &binding_struct);
196 if (NT_STATUS_IS_ERR(status)) {
197 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
198 return false;
201 h = dcerpc_binding_get_string_option(binding_struct, "host");
202 host = discard_const_p(char, h);
203 if (host != NULL) {
204 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
207 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
208 lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
209 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
210 } else {
211 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
212 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
213 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
215 TALLOC_FREE(host);
216 TALLOC_FREE(share);
219 return true;
222 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
224 char *userdn, *basedn, *secret;
225 char *p, *d;
227 /* retrieve the userdn */
228 p = strchr_m(dns, '#');
229 if (!p) {
230 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
231 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
232 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
233 return;
235 userdn = strndup(dns, p - dns);
236 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
238 /* retrieve the basedn */
239 d = p + 1;
240 p = strchr_m(d, '#');
241 if (!p) {
242 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
243 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
244 return;
246 basedn = strndup(d, p - d);
247 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
249 /* retrieve the secret */
250 p = p + 1;
251 if (!p) {
252 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
253 return;
255 secret = strdup(p);
256 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
258 printf ("%s - %s - %s\n", userdn, basedn, secret);
262 /* Print the full test list, formatted into separate labelled test
263 * groups.
265 static void print_structured_testsuite_list(void)
267 struct torture_suite *o;
268 struct torture_suite *s;
269 struct torture_tcase *t;
270 int i;
272 if (torture_root == NULL) {
273 printf("NO TESTS LOADED\n");
274 return;
277 for (o = torture_root->children; o; o = o->next) {
278 printf("\n%s (%s):\n ", o->description, o->name);
280 i = 0;
281 for (s = o->children; s; s = s->next) {
282 if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
283 printf("\n ");
284 i = 0;
286 i+=printf("%s.%s ", o->name, s->name);
289 for (t = o->testcases; t; t = t->next) {
290 if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
291 printf("\n ");
292 i = 0;
294 i+=printf("%s.%s ", o->name, t->name);
297 if (i) printf("\n");
300 printf("\nThe default test is ALL.\n");
303 static void print_testsuite_list(void)
305 struct torture_suite *o;
306 struct torture_suite *s;
307 struct torture_tcase *t;
309 if (torture_root == NULL)
310 return;
312 for (o = torture_root->children; o; o = o->next) {
313 for (s = o->children; s; s = s->next) {
314 printf("%s.%s\n", o->name, s->name);
317 for (t = o->testcases; t; t = t->next) {
318 printf("%s.%s\n", o->name, t->name);
323 void torture_print_testsuites(bool structured)
325 if (structured) {
326 print_structured_testsuite_list();
327 } else {
328 print_testsuite_list();
332 static void usage(poptContext pc)
334 poptPrintUsage(pc, stdout, 0);
335 printf("\n");
337 printf("The binding format is:\n\n");
339 printf(" TRANSPORT:host[flags]\n\n");
341 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
342 printf(" or ncalrpc for local connections.\n\n");
344 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
345 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
346 printf(" string.\n\n");
348 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
349 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
350 printf(" will be auto-determined.\n\n");
352 printf(" other recognised flags are:\n\n");
354 printf(" sign : enable ntlmssp signing\n");
355 printf(" seal : enable ntlmssp sealing\n");
356 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
357 printf(" validate: enable the NDR validator\n");
358 printf(" print: enable debugging of the packets\n");
359 printf(" bigendian: use bigendian RPC\n");
360 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
362 printf(" For example, these all connect to the samr pipe:\n\n");
364 printf(" ncacn_np:myserver\n");
365 printf(" ncacn_np:myserver[samr]\n");
366 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
367 printf(" ncacn_np:myserver[/pipe/samr]\n");
368 printf(" ncacn_np:myserver[samr,sign,print]\n");
369 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
370 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
371 printf(" ncacn_np:\n");
372 printf(" ncacn_np:[/pipe/samr]\n\n");
374 printf(" ncacn_ip_tcp:myserver\n");
375 printf(" ncacn_ip_tcp:myserver[1024]\n");
376 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
378 printf(" ncalrpc:\n\n");
380 printf("The UNC format is:\n\n");
382 printf(" //server/share\n\n");
384 printf("Tests are:");
386 print_structured_testsuite_list();
390 _NORETURN_ static void max_runtime_handler(int sig)
392 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
393 exit(1);
396 /****************************************************************************
397 main program
398 ****************************************************************************/
399 int main(int argc, const char *argv[])
401 int opt, i;
402 bool correct = true;
403 int max_runtime=0;
404 int argc_new;
405 struct torture_context *torture;
406 struct torture_results *results;
407 const struct torture_ui_ops *ui_ops;
408 char **argv_new;
409 poptContext pc;
410 static const char *target = "other";
411 NTSTATUS status;
412 int shell = false;
413 static const char *ui_ops_name = "subunit";
414 const char *basedir = NULL;
415 char *outputdir;
416 const char *extra_module = NULL;
417 static int list_tests = 0, list_testsuites = 0;
418 int num_extra_users = 0;
419 const char **restricted = NULL;
420 int num_restricted = -1;
421 const char *load_list = NULL;
422 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
423 OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,
424 OPT_EXTRA_USER,};
425 TALLOC_CTX *mem_ctx = NULL;
426 struct loadparm_context *lp_ctx = NULL;
427 bool ok;
429 struct poptOption long_options[] = {
430 POPT_AUTOHELP
431 {"fullname", 0, POPT_ARG_NONE, &use_fullname, 0,
432 "use full name for the test", NULL },
433 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
434 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
435 {"basedir", 0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
436 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "Seed to use for randomizer", NULL},
437 {"num-progs", 0, POPT_ARG_INT, NULL, OPT_NUMPROGS, "num progs", NULL},
438 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
439 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
440 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "NBench load file to use", NULL},
441 {"list-suites", 0, POPT_ARG_NONE, &list_testsuites, 0, "List available testsuites and exit", NULL },
442 {"list", 0, POPT_ARG_NONE, &list_tests, 0, "List available tests in specified suites and exit", NULL },
443 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
444 {"timelimit", 't', POPT_ARG_INT, NULL, OPT_TIMELIMIT, "Set time limit (in seconds)", NULL},
445 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
446 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
447 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS,
448 "run dangerous tests (eg. wiping out password database)", NULL},
449 {"load-module", 0, POPT_ARG_STRING, &extra_module, 0, "load tests from DSO file", "SOFILE"},
450 {"shell", 0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
451 {"target", 'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
452 {"async", 'a', POPT_ARG_NONE, NULL, OPT_ASYNC,
453 "run async tests", NULL},
454 {"num-async", 0, POPT_ARG_INT, &torture_numasync, 0,
455 "number of simultaneous async requests", NULL},
456 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
457 "set maximum time for smbtorture to live", "seconds"},
458 {"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
459 "extra user credentials", NULL},
460 {"load-list", 0, POPT_ARG_STRING, &load_list, 0,
461 "load a test id list from a text file", NULL},
462 POPT_COMMON_SAMBA
463 POPT_COMMON_CONNECTION
464 POPT_COMMON_CREDENTIALS
465 POPT_COMMON_VERSION
466 POPT_LEGACY_S4
467 POPT_TABLEEND
470 setlinebuf(stdout);
472 mem_ctx = talloc_named_const(NULL, 0, "torture_ctx");
473 if (mem_ctx == NULL) {
474 printf("Unable to allocate torture_ctx\n");
475 exit(1);
478 printf("smbtorture %s\n", samba_version_string());
480 /* we are never interested in SIGPIPE */
481 BlockSignals(true, SIGPIPE);
483 ok = samba_cmdline_init(mem_ctx,
484 SAMBA_CMDLINE_CONFIG_CLIENT,
485 false /* require_smbconf */);
486 if (!ok) {
487 DBG_ERR("Unable to init cmdline parser\n");
488 TALLOC_FREE(mem_ctx);
489 exit(1);
492 pc = samba_popt_get_context(getprogname(),
493 argc,
494 argv,
495 long_options,
496 POPT_CONTEXT_KEEP_FIRST);
497 if (pc == NULL) {
498 DBG_ERR("Failed cmdline parser\n");
499 TALLOC_FREE(mem_ctx);
500 exit(1);
503 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
505 lp_ctx = samba_cmdline_get_lp_ctx();
507 while((opt = poptGetNextOpt(pc)) != -1) {
508 switch (opt) {
509 case OPT_LOADFILE:
510 lpcfg_set_cmdline(lp_ctx, "torture:loadfile", poptGetOptArg(pc));
511 break;
512 case OPT_UNCLIST:
513 lpcfg_set_cmdline(lp_ctx, "torture:unclist", poptGetOptArg(pc));
514 break;
515 case OPT_TIMELIMIT:
516 lpcfg_set_cmdline(lp_ctx, "torture:timelimit", poptGetOptArg(pc));
517 break;
518 case OPT_NUMPROGS:
519 lpcfg_set_cmdline(lp_ctx, "torture:nprocs", poptGetOptArg(pc));
520 break;
521 case OPT_DNS:
522 parse_dns(lp_ctx, poptGetOptArg(pc));
523 break;
524 case OPT_DANGEROUS:
525 lpcfg_set_cmdline(lp_ctx, "torture:dangerous", "Yes");
526 break;
527 case OPT_ASYNC:
528 lpcfg_set_cmdline(lp_ctx, "torture:async", "Yes");
529 break;
530 case OPT_SMB_PORTS:
531 lpcfg_set_cmdline(lp_ctx, "smb ports", poptGetOptArg(pc));
532 break;
533 case OPT_EXTRA_USER:
535 char *option = talloc_asprintf(mem_ctx,
536 "torture:extra_user%u",
537 ++num_extra_users);
538 const char *value = poptGetOptArg(pc);
539 if (option == NULL) {
540 printf("talloc fail\n");
541 talloc_free(mem_ctx);
542 exit(1);
544 lpcfg_set_cmdline(lp_ctx, option, value);
545 talloc_free(option);
547 break;
548 default:
549 if (opt < 0) {
550 printf("Invalid command line option %s (%d)\n",
551 poptBadOption(pc, 0),
552 opt);
553 talloc_free(mem_ctx);
554 exit(1);
559 if (load_list != NULL) {
560 char **r;
561 r = file_lines_load(load_list, &num_restricted, 0, mem_ctx);
562 restricted = discard_const_p(const char *, r);
563 if (restricted == NULL) {
564 printf("Unable to read load list file '%s'\n", load_list);
565 talloc_free(mem_ctx);
566 exit(1);
570 if (strcmp(target, "samba3") == 0) {
571 lpcfg_set_cmdline(lp_ctx, "torture:samba3", "true");
572 lpcfg_set_cmdline(lp_ctx, "torture:resume_key_support", "false");
573 } else if (strcmp(target, "samba4") == 0) {
574 lpcfg_set_cmdline(lp_ctx, "torture:samba4", "true");
575 } else if (strcmp(target, "samba4-ntvfs") == 0) {
576 lpcfg_set_cmdline(lp_ctx, "torture:samba4", "true");
577 lpcfg_set_cmdline(lp_ctx, "torture:samba4-ntvfs", "true");
578 } else if (strcmp(target, "winxp") == 0) {
579 lpcfg_set_cmdline(lp_ctx, "torture:winxp", "true");
580 } else if (strcmp(target, "w2k3") == 0) {
581 lpcfg_set_cmdline(lp_ctx, "torture:w2k3", "true");
582 } else if (strcmp(target, "w2k8") == 0) {
583 lpcfg_set_cmdline(lp_ctx, "torture:w2k8", "true");
584 lpcfg_set_cmdline(lp_ctx,
585 "torture:invalid_lock_range_support", "false");
586 } else if (strcmp(target, "w2k12") == 0) {
587 lpcfg_set_cmdline(lp_ctx, "torture:w2k12", "true");
588 } else if (strcmp(target, "win7") == 0) {
589 lpcfg_set_cmdline(lp_ctx, "torture:win7", "true");
590 lpcfg_set_cmdline(lp_ctx, "torture:resume_key_support", "false");
591 lpcfg_set_cmdline(lp_ctx, "torture:rewind_support", "false");
593 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
594 lpcfg_set_cmdline(lp_ctx, "torture:search_ea_support", "false");
596 lpcfg_set_cmdline(lp_ctx, "torture:hide_on_access_denied",
597 "true");
598 } else if (strcmp(target, "onefs") == 0) {
599 lpcfg_set_cmdline(lp_ctx, "torture:onefs", "true");
600 lpcfg_set_cmdline(lp_ctx, "torture:openx_deny_dos_support",
601 "false");
602 lpcfg_set_cmdline(lp_ctx, "torture:range_not_locked_on_file_close", "false");
603 lpcfg_set_cmdline(lp_ctx, "torture:sacl_support", "false");
604 lpcfg_set_cmdline(lp_ctx, "torture:ea_support", "false");
605 lpcfg_set_cmdline(lp_ctx, "torture:smbexit_pdu_support",
606 "false");
607 lpcfg_set_cmdline(lp_ctx, "torture:smblock_pdu_support",
608 "false");
609 lpcfg_set_cmdline(lp_ctx, "torture:2_step_break_to_none",
610 "true");
611 lpcfg_set_cmdline(lp_ctx, "torture:deny_dos_support", "false");
612 lpcfg_set_cmdline(lp_ctx, "torture:deny_fcb_support", "false");
613 lpcfg_set_cmdline(lp_ctx, "torture:read_support", "false");
614 lpcfg_set_cmdline(lp_ctx, "torture:writeclose_support", "false");
615 lpcfg_set_cmdline(lp_ctx, "torture:resume_key_support", "false");
616 lpcfg_set_cmdline(lp_ctx, "torture:rewind_support", "false");
617 lpcfg_set_cmdline(lp_ctx, "torture:raw_search_search", "false");
618 lpcfg_set_cmdline(lp_ctx, "torture:search_ea_size", "false");
621 if (max_runtime) {
622 /* this will only work if nobody else uses alarm(),
623 which means it won't work for some tests, but we
624 can't use the event context method we use for smbd
625 as so many tests create their own event
626 context. This will at least catch most cases. */
627 signal(SIGALRM, max_runtime_handler);
628 alarm(max_runtime);
631 if (extra_module != NULL) {
632 init_module_fn fn = load_module(poptGetOptArg(pc), false, NULL);
634 if (fn == NULL)
635 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
636 else {
637 status = fn(mem_ctx);
638 if (NT_STATUS_IS_ERR(status)) {
639 d_printf("Error initializing module %s: %s\n",
640 poptGetOptArg(pc), nt_errstr(status));
643 } else {
644 torture_init(mem_ctx);
647 if (list_testsuites) {
648 print_testsuite_list();
649 poptFreeContext(pc);
650 talloc_free(mem_ctx);
651 return 0;
654 argv_new = discard_const_p(char *, poptGetArgs(pc));
656 argc_new = argc;
657 for (i=0; i<argc; i++) {
658 if (argv_new[i] == NULL) {
659 argc_new = i;
660 break;
664 if (list_tests) {
665 if (argc_new == 1) {
666 print_test_list(torture_root, NULL, "");
667 } else {
668 for (i=1;i<argc_new;i++) {
669 print_test_list(torture_root, NULL, argv_new[i]);
672 poptFreeContext(pc);
673 talloc_free(mem_ctx);
674 return 0;
677 if (torture_seed == 0) {
678 torture_seed = time(NULL);
680 printf("Using seed %d\n", torture_seed);
681 srandom(torture_seed);
683 if (!strcmp(ui_ops_name, "simple")) {
684 ui_ops = &torture_simple_ui_ops;
685 } else if (!strcmp(ui_ops_name, "subunit")) {
686 ui_ops = &torture_subunit_ui_ops;
687 } else {
688 printf("Unknown output format '%s'\n", ui_ops_name);
689 talloc_free(mem_ctx);
690 exit(1);
693 results = torture_results_init(mem_ctx, ui_ops);
695 torture = torture_context_init(s4_event_context_init(mem_ctx),
696 results);
697 if (basedir != NULL) {
698 if (basedir[0] != '/') {
699 fprintf(stderr, "Please specify an absolute path to --basedir\n");
700 poptFreeContext(pc);
701 talloc_free(mem_ctx);
702 return 1;
704 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
705 } else {
706 char *pwd = talloc_size(torture, PATH_MAX);
707 if (!getcwd(pwd, PATH_MAX)) {
708 fprintf(stderr, "Unable to determine current working directory\n");
709 poptFreeContext(pc);
710 talloc_free(mem_ctx);
711 return 1;
713 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
715 if (!outputdir) {
716 fprintf(stderr, "Could not allocate per-run output dir\n");
717 poptFreeContext(pc);
718 talloc_free(mem_ctx);
719 return 1;
721 torture->outputdir = mkdtemp(outputdir);
722 if (!torture->outputdir) {
723 perror("Failed to make temp output dir");
724 poptFreeContext(pc);
725 talloc_free(mem_ctx);
726 return 1;
729 torture->lp_ctx = lp_ctx;
731 gensec_init();
733 if (shell) {
734 /* In shell mode, just ignore any remaining test names. */
735 torture_shell(torture);
736 } else {
738 /* At this point, we should just have a target string,
739 * followed by a series of test names. Unless we are in
740 * shell mode, in which case we don't need anything more.
743 if (argc_new < 3) {
744 printf("You must specify a test to run, or 'ALL'\n");
745 usage(pc);
746 torture->results->returncode = 1;
747 } else if (!torture_parse_target(torture,
748 lp_ctx, argv_new[1])) {
749 /* Take the target name or binding. */
750 usage(pc);
751 torture->results->returncode = 1;
752 } else {
753 for (i=2;i<argc_new;i++) {
754 if (!torture_run_named_tests(torture, argv_new[i],
755 (const char **)restricted)) {
756 correct = false;
762 /* Now delete the temp dir we created */
763 torture_deltree_outputdir(torture);
765 if (torture->results->returncode && correct) {
766 poptFreeContext(pc);
767 talloc_free(mem_ctx);
768 return(0);
769 } else {
770 poptFreeContext(pc);
771 talloc_free(mem_ctx);
772 return(1);