]> git.saurik.com Git - apple/security.git/blob - OSX/sectests/test/testenv.c
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / sectests / test / testenv.c
1 /*
2 * Copyright (c) 2005-2007,2009-2013 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 * testenv.c
24 */
25
26 #include <fcntl.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 #include <stdbool.h>
34
35 #include "testmore.h"
36 #include "testenv.h"
37
38 int test_verbose = 0;
39
40 #if NO_SERVER
41 #include <securityd/spi.h>
42
43 static int current_dir = -1;
44 static char scratch_dir[50];
45 static char *home_var;
46 static bool keep_scratch_dir = false;
47
48 static int
49 rmdir_recursive(const char *path)
50 {
51 char command_buf[256];
52 if (strlen(path) + 10 > sizeof(command_buf) || strchr(path, '\''))
53 {
54 fprintf(stderr, "# rmdir_recursive: invalid path: %s", path);
55 return -1;
56 }
57
58 sprintf(command_buf, "rm -rf '%s'", path);
59 return system(command_buf);
60 }
61 #endif
62
63 static int tests_init(void) {
64 #if NO_SERVER
65 char preferences_dir[80];
66 char library_dir[70];
67
68 char *path = getenv("TESTHOME");
69 if (path)
70 setenv("TESTHOME", path, 1);
71 securityd_init();
72
73 setup("tests_init");
74
75 /* Create scratch dir for tests to run in. */
76 sprintf(scratch_dir, "/tmp/tst-%d", getpid());
77 if (keep_scratch_dir) {
78 printf("running tests with HOME=%s\n", scratch_dir);
79 }
80 sprintf(library_dir, "%s/Library", scratch_dir);
81 sprintf(preferences_dir, "%s/Preferences", library_dir);
82 return (ok_unix(mkdir(scratch_dir, 0755), "mkdir") &&
83 ok_unix(current_dir = open(".", O_RDONLY), "open") &&
84 ok_unix(chdir(scratch_dir), "chdir") &&
85 ok_unix(setenv("HOME", scratch_dir, 1), "setenv") &&
86 /* @@@ Work around a bug that the prefs code in
87 libsecurity_keychain never creates the Library/Preferences
88 dir. */
89 ok_unix(mkdir(library_dir, 0755), "mkdir") &&
90 ok_unix(mkdir(preferences_dir, 0755), "mkdir") &&
91 ok(home_var = getenv("HOME"), "getenv"));
92
93 #else
94 return 0;
95 #endif
96 }
97
98 static int
99 tests_end(void)
100 {
101 #if NO_SERVER
102 setup("tests_end");
103 /* Restore previous cwd and remove scratch dir. */
104 int ok = ok_unix(fchdir(current_dir), "fchdir");
105 if (ok)
106 ok = ok_unix(close(current_dir), "close");
107 if (ok) {
108 if (!keep_scratch_dir) {
109 ok = ok_unix(rmdir_recursive(scratch_dir), "rmdir_recursive");
110 }
111 }
112
113 return ok;
114 #else
115 return 0;
116 #endif
117 }
118
119 static void usage(const char *progname)
120 {
121 fprintf(stderr, "usage: %s [-k][-w][testname [testargs] ...]\n", progname);
122 exit(1);
123 }
124
125 static int tests_run_index(int i, int argc, char * const *argv)
126 {
127 int ch;
128
129 while ((ch = getopt(argc, argv, "v")) != -1)
130 {
131 switch (ch)
132 {
133 case 'v':
134 test_verbose++;
135 break;
136 default:
137 usage(argv[0]);
138 }
139 }
140
141 fprintf(stderr, "TEST: Test Case '%s' started.\n", testlist[i].name);
142
143 run_one_test(&testlist[i], argc, argv);
144 if(testlist[i].failed_tests) {
145 fprintf(stderr, "FAIL: Test Case '%s' failed.\n", testlist[i].name);
146 } else {
147 fprintf(stderr, "PASS: Test Case '%s' passed. (%lu ms)\n", testlist[i].name, testlist[i].duration);
148 }
149 return testlist[i].failed_tests;
150 }
151
152 static int strcmp_under_is_dash(const char *s, const char *t) {
153 for (;;) {
154 char a = *s++, b = *t++;
155 if (a != b) {
156 if (a != '_' || b != '-')
157 return a - b;
158 } else if (a == 0) {
159 return 0;
160 }
161 }
162 }
163
164 static int tests_named_index(const char *testcase)
165 {
166 int i;
167
168 for (i = 0; testlist[i].name; ++i) {
169 if (strcmp_under_is_dash(testlist[i].name, testcase) == 0) {
170 return i;
171 }
172 }
173
174 return -1;
175 }
176
177 static int tests_run_all(int argc, char * const *argv)
178 {
179 int curroptind = optind;
180 int i;
181 int failcount=0;
182
183 for (i = 0; testlist[i].name; ++i) {
184 if(!testlist[i].off) {
185 failcount+=tests_run_index(i, argc, argv);
186 optind = curroptind;
187 }
188 }
189
190 return failcount;
191 }
192
193 int
194 tests_begin(int argc, char * const *argv)
195 {
196 const char *testcase = NULL;
197 bool initialized = false;
198 int testix = -1;
199 int failcount = 0;
200 int ch;
201 int loop = 0;
202
203 for (;;) {
204 while (!testcase && (ch = getopt(argc, argv, "klw")) != -1)
205 {
206 switch (ch)
207 {
208 #ifdef NO_SERVER
209 case 'k':
210 keep_scratch_dir = true;
211 break;
212 #endif
213 case 'w':
214 sleep(100);
215 break;
216 case 'l':
217 loop=1;
218 break;
219 case '?':
220 default:
221 printf("invalid option %c\n",ch);
222 usage(argv[0]);
223 }
224 }
225
226 if (optind < argc) {
227 testix = tests_named_index(argv[optind]);
228 if(testix<0) {
229 printf("invalid test %s\n",argv[optind]);
230 usage(argv[0]);
231 }
232 }
233
234 if (testix < 0) {
235 if (!initialized) {
236 initialized = true;
237 tests_init();
238 failcount+=tests_run_all(argc, argv);
239 }
240 break;
241 } else {
242 if (!initialized) {
243 tests_init();
244 initialized = true;
245 }
246 optind++;
247 failcount+=tests_run_index(testix, argc, argv);
248 testix = -1;
249 }
250 }
251
252 printf("Total failcount = %d\n", failcount);
253
254 /* Cleanups */
255 tests_end();
256
257 if(loop) {
258 printf("Looping until key press 'q'. You can run leaks now.\n");
259 while(getchar()!='q');
260 }
261
262 return failcount;
263 }
264