2 Unix SMB/CIFS implementation.
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/>.
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>
40 static char *prefix_name(TALLOC_CTX
*mem_ctx
, const char *prefix
, const char *name
)
43 return talloc_strdup(mem_ctx
, name
);
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
);
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) {
71 static bool run_matching(struct torture_context
*torture
,
74 const char **restricted
,
75 struct torture_suite
*suite
,
79 struct torture_suite
*o
;
80 struct torture_tcase
*t
;
81 struct torture_test
*p
;
83 for (o
= suite
->children
; o
; o
= o
->next
) {
85 name
= prefix_name(torture
, prefix
, o
->name
);
86 if (gen_fnmatch(expr
, name
) == 0) {
88 reload_charcnv(torture
->lp_ctx
);
89 if (restricted
!= NULL
)
90 ret
&= torture_run_suite_restricted(torture
, o
, restricted
);
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) {
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) {
108 reload_charcnv(torture
->lp_ctx
);
109 ret
&= torture_run_test_restricted(torture
, t
, p
, restricted
);
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
)
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");
136 for (o
= torture_root
->children
; o
; o
= o
->next
) {
137 ret
&= torture_run_suite(torture
, o
);
142 ret
= run_matching(torture
, NULL
, name
, restricted
, torture_root
, &matched
);
145 printf("Unknown torture operation '%s'\n", name
);
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
;
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
);
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
);
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
);
178 static void parse_dns(struct loadparm_context
*lp_ctx
, const char *dns
)
180 char *userdn
, *basedn
, *secret
;
183 /* retrievieng the userdn */
184 p
= strchr_m(dns
, '#');
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", "");
191 userdn
= strndup(dns
, p
- dns
);
192 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_userdn", userdn
);
194 /* retrieve the basedn */
196 p
= strchr_m(d
, '#');
198 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", "");
199 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
202 basedn
= strndup(d
, p
- d
);
203 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", basedn
);
205 /* retrieve the secret */
208 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
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
221 static void print_structured_testsuite_list(void)
223 struct torture_suite
*o
;
224 struct torture_suite
*s
;
225 struct torture_tcase
*t
;
228 if (torture_root
== NULL
) {
229 printf("NO TESTS LOADED\n");
233 for (o
= torture_root
->children
; o
; o
= o
->next
) {
234 printf("\n%s (%s):\n ", o
->description
, o
->name
);
237 for (s
= o
->children
; s
; s
= s
->next
) {
238 if (i
+ strlen(o
->name
) + strlen(s
->name
) >= (MAX_COLS
- 3)) {
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)) {
250 i
+=printf("%s.%s ", o
->name
, t
->name
);
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
)
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
)
282 print_structured_testsuite_list();
284 print_testsuite_list();
288 static void usage(poptContext pc
)
290 poptPrintUsage(pc
, stdout
, 0);
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"));
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
)
375 printf("OK: %s\n", reason
);
378 printf("TEST %s FAILED! - %s\n", context
->active_test
->name
, reason
);
381 printf("ERROR IN TEST %s! - %s\n", context
->active_test
->name
, reason
);
384 printf("SKIP: %s - %s\n", context
->active_test
->name
, reason
);
389 static void simple_comment(struct torture_context
*test
,
392 printf("%s", comment
);
395 static void simple_warning(struct torture_context
*test
,
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 /****************************************************************************
417 ****************************************************************************/
418 int main(int argc
,char *argv
[])
424 struct torture_context
*torture
;
425 struct torture_results
*results
;
426 const struct torture_ui_ops
*ui_ops
;
429 static const char *target
= "other";
432 static const char *ui_ops_name
= "subunit";
433 const char *basedir
= NULL
;
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
,
445 struct poptOption long_options
[] = {
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
},
477 POPT_COMMON_CONNECTION
478 POPT_COMMON_CREDENTIALS
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) {
496 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:loadfile", poptGetOptArg(pc
));
499 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:unclist", poptGetOptArg(pc
));
502 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:timelimit", poptGetOptArg(pc
));
505 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:nprocs", poptGetOptArg(pc
));
508 parse_dns(cmdline_lp_ctx
, poptGetOptArg(pc
));
511 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:dangerous", "Yes");
514 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:async", "Yes");
517 lpcfg_set_cmdline(cmdline_lp_ctx
, "smb ports", poptGetOptArg(pc
));
521 char *option
= talloc_asprintf(NULL
, "torture:extra_user%u",
523 const char *value
= poptGetOptArg(pc
);
524 lpcfg_set_cmdline(cmdline_lp_ctx
, option
, value
);
530 printf("bad command line option %d\n", opt
);
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
);
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",
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",
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",
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",
579 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:smblock_pdu_support",
581 lpcfg_set_cmdline(cmdline_lp_ctx
, "torture:2_step_break_to_none",
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");
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
);
603 if (extra_module
!= NULL
) {
604 init_module_fn fn
= load_module(talloc_autofree_context(), poptGetOptArg(pc
));
607 d_printf("Unable to load module from %s\n", poptGetOptArg(pc
));
610 if (NT_STATUS_IS_ERR(status
)) {
611 d_printf("Error initializing module %s: %s\n",
612 poptGetOptArg(pc
), nt_errstr(status
));
619 if (list_testsuites
) {
620 print_testsuite_list();
624 argv_new
= discard_const_p(char *, poptGetArgs(pc
));
627 for (i
=0; i
<argc
; i
++) {
628 if (argv_new
[i
] == NULL
) {
636 print_test_list(torture_root
, NULL
, "");
638 for (i
=1;i
<argc_new
;i
++) {
639 print_test_list(torture_root
, NULL
, argv_new
[i
]);
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
;
656 printf("Unknown output format '%s'\n", ui_ops_name
);
660 results
= torture_results_init(talloc_autofree_context(), ui_ops
);
662 torture
= torture_context_init(s4_event_context_init(talloc_autofree_context()),
664 if (basedir
!= NULL
) {
665 if (basedir
[0] != '/') {
666 fprintf(stderr
, "Please specify an absolute path to --basedir\n");
669 outputdir
= talloc_asprintf(torture
, "%s/smbtortureXXXXXX", basedir
);
671 char *pwd
= talloc_size(torture
, PATH_MAX
);
672 if (!getcwd(pwd
, PATH_MAX
)) {
673 fprintf(stderr
, "Unable to determine current working directory\n");
676 outputdir
= talloc_asprintf(torture
, "%s/smbtortureXXXXXX", pwd
);
679 fprintf(stderr
, "Could not allocate per-run output dir\n");
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
);
692 /* In shell mode, just ignore any remaining test names. */
693 torture_shell(torture
);
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.
702 printf("You must specify a test to run, or 'ALL'\n");
704 torture
->results
->returncode
= 1;
705 } else if (!torture_parse_target(cmdline_lp_ctx
, argv_new
[1])) {
706 /* Take the target name or binding. */
708 torture
->results
->returncode
= 1;
710 for (i
=2;i
<argc_new
;i
++) {
711 if (!torture_run_named_tests(torture
, argv_new
[i
],
712 (const char **)restricted
)) {
719 /* Now delete the temp dir we created */
720 torture_deltree_outputdir(torture
);
722 if (torture
->results
->returncode
&& correct
) {