1 /*
2  * ProFTPD - FTP server API testsuite
3  * Copyright (c) 2008-2017 The ProFTPD Project team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, The ProFTPD Project team and other respective
20  * copyright holders give permission to link this program with OpenSSL, and
21  * distribute the resulting executable, without including the source code for
22  * OpenSSL in the source distribution.
23  */
24 
25 #include "tests.h"
26 
27 struct testsuite_info {
28   const char *name;
29   Suite *(*get_suite)(void);
30 };
31 
32 static struct testsuite_info suites[] = {
33   { "pool", 		tests_get_pool_suite },
34   { "array", 		tests_get_array_suite },
35   { "str", 		tests_get_str_suite },
36   { "sets", 		tests_get_sets_suite },
37   { "timers", 		tests_get_timers_suite },
38   { "table", 		tests_get_table_suite },
39   { "var", 		tests_get_var_suite },
40   { "event", 		tests_get_event_suite },
41   { "env", 		tests_get_env_suite },
42   { "random", 		tests_get_random_suite },
43   { "version", 		tests_get_version_suite },
44   { "feat", 		tests_get_feat_suite },
45   { "netaddr", 		tests_get_netaddr_suite },
46   { "netacl",		tests_get_netacl_suite },
47   { "class",		tests_get_class_suite },
48   { "regexp",		tests_get_regexp_suite },
49   { "expr",		tests_get_expr_suite },
50   { "scoreboard",	tests_get_scoreboard_suite },
51   { "stash",		tests_get_stash_suite },
52   { "modules",		tests_get_modules_suite },
53   { "cmd",		tests_get_cmd_suite },
54   { "response",		tests_get_response_suite },
55   { "fsio",		tests_get_fsio_suite },
56   { "netio",		tests_get_netio_suite },
57   { "trace",		tests_get_trace_suite },
58   { "parser",		tests_get_parser_suite },
59   { "pidfile",		tests_get_pidfile_suite },
60   { "config",		tests_get_config_suite },
61   { "auth",		tests_get_auth_suite },
62   { "filter",		tests_get_filter_suite },
63   { "inet",		tests_get_inet_suite },
64   { "data",		tests_get_data_suite },
65   { "ascii",		tests_get_ascii_suite },
66   { "help",		tests_get_help_suite },
67   { "rlimit",		tests_get_rlimit_suite },
68   { "encode",		tests_get_encode_suite },
69   { "privs",		tests_get_privs_suite },
70   { "display",		tests_get_display_suite },
71   { "misc",		tests_get_misc_suite },
72   { "json",		tests_get_json_suite },
73   { "jot",		tests_get_jot_suite },
74   { "redis",		tests_get_redis_suite },
75   { "error",		tests_get_error_suite },
76 
77   { NULL, NULL }
78 };
79 
tests_get_suite(const char * suite)80 static Suite *tests_get_suite(const char *suite) {
81   register unsigned int i;
82 
83   for (i = 0; suites[i].name != NULL; i++) {
84     if (strcmp(suite, suites[i].name) == 0) {
85       return (*suites[i].get_suite)();
86     }
87   }
88 
89   return NULL;
90 }
91 
main(int argc,char * argv[])92 int main(int argc, char *argv[]) {
93   const char *log_file = "api-tests.log";
94   const char *xml_file = "api-tests.xml";
95   int nfailed = 0;
96   SRunner *runner = NULL;
97   char *requested = NULL;
98 
99   runner = srunner_create(NULL);
100 
101   /* XXX This log name should be set outside this code, e.g. via environment
102    * variable or command-line option.
103    */
104   srunner_set_log(runner, log_file);
105   if (getenv("PR_XML_TEST_OUTPUT")) {
106     srunner_set_xml(runner, xml_file);
107   }
108 
109   requested = getenv("PR_TEST_SUITE");
110   if (requested) {
111     Suite *suite;
112 
113     suite = tests_get_suite(requested);
114     if (suite) {
115       srunner_add_suite(runner, suite);
116 
117     } else {
118       fprintf(stderr, "No such test suite ('%s') requested via PR_TEST_SUITE\n",
119         requested);
120       return EXIT_FAILURE;
121     }
122 
123   } else {
124     register unsigned int i;
125 
126     for (i = 0; suites[i].name; i++) {
127       Suite *suite;
128 
129       suite = (suites[i].get_suite)();
130       if (suite) {
131         srunner_add_suite(runner, suite);
132       }
133     }
134   }
135 
136   /* Configure the Trace API to write to stderr. */
137   pr_trace_use_stderr(TRUE);
138 
139   requested = getenv("PR_TEST_NOFORK");
140   if (requested) {
141     srunner_set_fork_status(runner, CK_NOFORK);
142   } else {
143     requested = getenv("CK_DEFAULT_TIMEOUT");
144     if (requested == NULL) {
145       setenv("CK_DEFAULT_TIMEOUT", "60", 1);
146     }
147   }
148 
149   srunner_run_all(runner, CK_NORMAL);
150 
151   nfailed = srunner_ntests_failed(runner);
152 
153   if (runner)
154     srunner_free(runner);
155 
156   if (nfailed != 0) {
157     fprintf(stderr, "-------------------------------------------------\n");
158     fprintf(stderr, " FAILED %d %s\n\n", nfailed,
159       nfailed != 1 ? "tests" : "test");
160     fprintf(stderr, " Please send email to:\n\n");
161     fprintf(stderr, "   proftp-devel@lists.sourceforge.net\n\n");
162     fprintf(stderr, " containing the `%s' file (in the tests/ directory)\n", log_file);
163     fprintf(stderr, " and the output from running `proftpd -V'\n");
164     fprintf(stderr, "-------------------------------------------------\n");
165 
166     return EXIT_FAILURE;
167   }
168 
169   return EXIT_SUCCESS;
170 }
171