1/* 2 * Copyright (c) 2005-2007,2009-2010 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#if NO_SERVER 39#include <securityd/spi.h> 40 41static int current_dir = -1; 42static char scratch_dir[50]; 43static char *home_var; 44static bool keep_scratch_dir = false; 45 46static int 47rmdir_recursive(const char *path) 48{ 49 char command_buf[256]; 50 if (strlen(path) + 10 > sizeof(command_buf) || strchr(path, '\'')) 51 { 52 fprintf(stderr, "# rmdir_recursive: invalid path: %s", path); 53 return -1; 54 } 55 56 sprintf(command_buf, "rm -rf '%s'", path); 57 return system(command_buf); 58} 59#endif 60 61static int tests_init(void) { 62 printf("[TEST] CommonCrypto\n"); 63#if NO_SERVER 64 char preferences_dir[80]; 65 char library_dir[70]; 66 67 securityd_init(); 68 69 setup("tests_init"); 70 71 /* Create scratch dir for tests to run in. */ 72 sprintf(scratch_dir, "/tmp/tst-%d", getpid()); 73 if (keep_scratch_dir) { 74 printf("running tests with HOME=%s\n", scratch_dir); 75 } 76 sprintf(library_dir, "%s/Library", scratch_dir); 77 sprintf(preferences_dir, "%s/Preferences", library_dir); 78 return (ok_unix(mkdir(scratch_dir, 0755), "mkdir") && 79 ok_unix(current_dir = open(".", O_RDONLY), "open") && 80 ok_unix(chdir(scratch_dir), "chdir") && 81 ok_unix(setenv("HOME", scratch_dir, 1), "setenv") && 82 /* @@@ Work around a bug that the prefs code in 83 libsecurity_keychain never creates the Library/Preferences 84 dir. */ 85 ok_unix(mkdir(library_dir, 0755), "mkdir") && 86 ok_unix(mkdir(preferences_dir, 0755), "mkdir") && 87 ok(home_var = getenv("HOME"), "getenv")); 88 89#else 90 return 0; 91#endif 92} 93 94static int 95tests_end(void) 96{ 97 printf("[SUMMARY]\n"); 98#if NO_SERVER 99 setup("tests_end"); 100 /* Restore previous cwd and remove scratch dir. */ 101 int ok = ok_unix(fchdir(current_dir), "fchdir"); 102 if (ok) 103 ok = ok_unix(close(current_dir), "close"); 104 if (ok) { 105 if (!keep_scratch_dir) { 106 ok = ok_unix(rmdir_recursive(scratch_dir), "rmdir_recursive"); 107 } 108 } 109 110 return ok; 111#else 112 return 0; 113#endif 114} 115 116static void usage(const char *progname) 117{ 118 fprintf(stderr, "usage: %s [-k][-w][testname [testargs] ...]\n", progname); 119 exit(1); 120} 121 122static int tests_run_index(int i, int argc, char * const *argv) 123{ 124 int verbose = 0; 125 int ch; 126 127 while ((ch = getopt(argc, argv, "v")) != -1) 128 { 129 switch (ch) 130 { 131 case 'v': 132 verbose++; 133 break; 134 default: 135 usage(argv[0]); 136 } 137 } 138 139 fprintf(stderr, "[BEGIN] %s\n", testlist[i].name); 140 141 run_one_test(&testlist[i], argc, argv); 142 if(testlist[i].failed_tests) { 143 fprintf(stderr, "[FAIL] %s\n", testlist[i].name); 144 } else { 145 fprintf(stderr, "duration: %u ms\n", testlist[i].duration); 146 fprintf(stderr, "[PASS] %s\n", testlist[i].name); 147 } 148 149 return 0; 150} 151 152static int tests_named_index(const char *testcase) 153{ 154 int i; 155 156 for (i = 0; testlist[i].name; ++i) { 157 if (strcmp(testlist[i].name, testcase) == 0) { 158 return i; 159 } 160 } 161 162 return -1; 163} 164 165static int tests_run_all(int argc, char * const *argv) 166{ 167 int curroptind = optind; 168 int i; 169 170 for (i = 0; testlist[i].name; ++i) { 171 tests_run_index(i, argc, argv); 172 optind = curroptind; 173 } 174 175 return 0; 176} 177 178int 179tests_begin(int argc, char * const *argv) 180{ 181 const char *testcase = NULL; 182 bool initialized = false; 183 int testix = -1; 184 int ch; 185 186 for (;;) { 187 while (!testcase && (ch = getopt(argc, argv, "kw")) != -1) 188 { 189 switch (ch) 190 { 191#ifdef NO_SERVER 192 case 'k': 193 keep_scratch_dir = true; 194 break; 195#endif 196 case 'w': 197 sleep(100); 198 break; 199 case '?': 200 default: 201 printf("invalid option %c\n",ch); 202 usage(argv[0]); 203 } 204 } 205 206 if (optind < argc) { 207 testix = tests_named_index(argv[optind]); 208 if(testix<0) { 209 printf("invalid test %s\n",argv[optind]); 210 usage(argv[0]); 211 } 212 } 213 214 if (testix < 0) { 215 if (!initialized) { 216 // initialized = true; 217 tests_init(); 218 tests_run_all(argc, argv); 219 } 220 break; 221 } else { 222 if (!initialized) { 223 tests_init(); 224 initialized = true; 225 } 226 optind++; 227 tests_run_index(testix, argc, argv); 228 testix = -1; 229 } 230 } 231 232 /* Cleanups */ 233 tests_end(); 234 235 return 0; 236} 237 238