]> git.saurik.com Git - apple/security.git/blobdiff - Security/regressions/test/testmore.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / regressions / test / testmore.c
diff --git a/Security/regressions/test/testmore.c b/Security/regressions/test/testmore.c
new file mode 100644 (file)
index 0000000..c632fe7
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2005-2007,2012-2014 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ *
+ * testmore.c
+ */
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <AvailabilityMacros.h>
+
+#include "testmore.h"
+#include "testenv.h"
+
+static int test_num = 0;
+static int test_fails = 0;
+static int test_cases = 0;
+static const char *test_plan_file;
+static int test_plan_line=0;
+
+const char *test_directive = NULL;
+const char *test_reason = NULL;
+
+static void fprint_string(FILE *file, CFStringRef string) {
+    UInt8 buf[256];
+    CFRange range = { .location = 0 };
+    range.length = CFStringGetLength(string);
+    while (range.length > 0) {
+        CFIndex bytesUsed = 0;
+        CFIndex converted = CFStringGetBytes(string, range, kCFStringEncodingUTF8, 0, false, buf, sizeof(buf), &bytesUsed);
+        fwrite(buf, 1, bytesUsed, file);
+        range.length -= converted;
+        range.location += converted;
+    }
+}
+
+static void cffprint(FILE *file, CFStringRef fmt, ...) CF_FORMAT_FUNCTION(2,0);
+
+static void cffprint_v(FILE *file, CFStringRef fmt, va_list args);
+static void cffprint_c_v(FILE *file, const char *fmt, va_list args);
+
+static void cffprint_v(FILE *file, CFStringRef fmt, va_list args) {
+    CFStringRef line = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, args);
+    fprint_string(file, line);
+    CFRelease(line);
+}
+
+static void cffprint_c_v(FILE *file, const char *fmt, va_list args) {
+    CFStringRef cffmt = CFStringCreateWithCString(kCFAllocatorDefault, fmt, kCFStringEncodingUTF8);
+    cffprint_v(file, cffmt, args);
+    CFRelease(cffmt);
+}
+
+static void cffprint(FILE *file, CFStringRef fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    cffprint_v(file, fmt, args);
+    va_end(args);
+}
+
+void test_skip(const char *reason, int how_many, int unless)
+{
+    if (unless)
+        return;
+
+    int done;
+    for (done = 0; done < how_many; ++done)
+        test_ok(1, NULL, "skip", reason, __FILE__, __LINE__, NULL);
+}
+
+void test_bail_out(const char *reason, const char *file, unsigned line)
+{
+    fprintf(stdout, "[FAIL] BAIL OUT! (%s at line %u) %s\n", file, line, reason);
+    fflush(stdout);
+    exit(255);
+}
+
+void test_plan_skip_all(const char *reason)
+{
+    if (test_num < test_cases)
+    {
+        test_skip(reason, test_cases - test_num, 0);
+    }
+}
+
+static int test_plan_exit(void)
+{
+    int status = 0;
+    fflush(stderr);
+
+    if (!test_num)
+    {
+        if (test_cases)
+        {
+            fprintf(stdout, "[BEGIN] plan_tests\nNo tests run!\n[WARN] plan_tests\n");
+            status = 1;
+        }
+        else
+        {
+            fprintf(stdout, "[BEGIN] plan_tests\nLooks like your test died before it could output anything.\n[FAIL] plan_tests\n");
+            status = 1;
+        }
+    }
+    else if (test_num < test_cases)
+    {
+        fprintf(stdout, "[BEGIN] plan_tests\nLooks like you planned %d tests but only ran %d.\n[WARN] plan_tests\n",
+               test_cases, test_num);
+    }
+    else if (test_num > test_cases)
+    {
+        fprintf(stdout, "[BEGIN] plan_tests\nLooks like you planned %d tests but ran %d.\n[WARN] plan_tests\n",
+               test_cases, test_num);
+    }
+    if (test_fails)
+    {
+        fprintf(stdout, "Failed %d tests of %d.\n", test_fails, test_num);
+        status = test_fails;
+    }
+    fflush(stdout);
+
+    /* reset the test plan */
+    test_num = 0;
+    test_fails = 0;
+    test_cases = 0;
+
+    return status;
+}
+
+void test_plan_tests(int count, const char *file, unsigned line)
+{
+#if 0
+    if (atexit(test_plan_exit) < 0)
+    {
+        fprintf(stdout, "failed to setup atexit handler: %s\n",
+                strerror(errno));
+        fflush(stdout);
+        exit(255);
+    }
+#endif
+
+       if (test_cases)
+    {
+        fprintf(stdout,
+                "[FAIL] You tried to plan twice!\n");
+        
+        fflush(stdout);
+        exit(255);
+    }
+    else
+       {
+        if (!count)
+        {
+            fprintf(stdout, "[BEGIN] plan_tests\nYou said to run 0 tests!  "
+                "You've got to run something.\n[WARN] plan_tests\n");
+            fflush(stdout);
+        }
+
+        test_plan_file=file;
+        test_plan_line=line;
+
+        test_cases = count;
+       }
+}
+
+int
+test_diag(const char *directive, const char *reason,
+       const char *file, unsigned line, const char *fmt, ...)
+{
+       int is_todo = directive && !strcmp(directive, "TODO");
+       va_list args;
+
+       va_start(args, fmt);
+
+       if (is_todo)
+       {
+               fputs("# ", stdout);
+               if (fmt)
+                       vprintf(fmt, args);
+               fputs("\n", stdout);
+               fflush(stdout);
+       }
+       else
+       {
+               fputs("# ", stdout);
+               if (fmt)
+                       vfprintf(stdout, fmt, args);
+               fputs("\n", stdout);
+               fflush(stdout);
+       }
+
+       va_end(args);
+
+       return 1;
+}
+
+int
+test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const char *directive,
+       const char *reason, const char *file, unsigned line,
+       const char *fmt, ...)
+{
+       int is_todo = !passed && directive && !strcmp(directive, "TODO");
+       int is_setup = directive && !is_todo && !strcmp(directive, "SETUP");
+
+       if (is_setup)
+       {
+               if (!passed)
+               {
+                       fflush(stderr);
+            fprintf(stdout, "[BEGIN] SETUP\n");
+            if (fmt) {
+                va_list args;
+                va_start(args, fmt);
+                cffprint_c_v(stdout, fmt, args);
+                va_end(args);
+            }
+            cffprint(stdout, CFSTR("[WARN] SETUP%s%@%s%s\n"),
+                                  description ? " - " : "",
+                                  description ? description : CFSTR(""),
+                                  reason ? " - " : "",
+                                  reason ? reason : "");
+            fflush(stdout);
+               }
+       }
+       else
+       {
+               if (!test_cases)
+               {
+                       atexit((void(*)(void))test_plan_exit);
+                       fprintf(stdout, "[FAIL] You tried to run a test without a plan!  "
+                                       "Gotta have a plan. at %s line %u\n", file, line);
+                       fflush(stdout);
+                       exit(255);
+               }
+
+               ++test_num;
+               if (!passed && !is_todo)
+                       ++test_fails;
+
+        /* We only print this when a test fail, unless verbose is enabled */
+        if ((!passed && !is_todo) || test_verbose > 0) {
+            fflush(stderr);
+            if (test_strict_bats) {
+                cffprint(stdout, CFSTR("[BEGIN] %d%s%@\n"),
+                         test_num,
+                         description ? " - " : "",
+                         description ? description : CFSTR(""));
+            }
+            if (is_todo && passed) {
+                fprintf(stdout, "%s:%d: warning: Unexpectedly passed (TODO) test\n", file, line);
+            } else if (is_todo && !passed) {
+                /* Enable this to output TODO as warning */
+                fprintf(stdout, "%s:%d: ok: Failed (TODO) test\n", file, line);
+            } else if (!passed) {
+                fprintf(stdout, "%s:%d: error: Failed test\n", file, line);
+            }
+            if (fmt) {
+                va_list args;
+                va_start(args, fmt);
+                cffprint_c_v(stdout, fmt, args);
+                va_end(args);
+            }
+            cffprint(stdout, CFSTR("[%s] %d%s%@%s%s%s%s\n"), passed ? (is_todo ? "WARN" : "PASS") : (is_todo ? "PASS" : "FAIL"),
+                     test_num,
+                     description ? " - " : "",
+                     description ? description : CFSTR(""),
+                     directive ? " # " : "",
+                     directive ? directive : "",
+                     reason ? " " : "",
+                     reason ? reason : "");
+            fflush(stdout);
+        }
+    }
+
+    if (description)
+        CFRelease(description);
+
+    return passed;
+}
+
+
+const char *
+sec_errstr(int err)
+{
+#if 1
+       static int bufnum = 0;
+    static char buf[2][20];
+       bufnum = bufnum ? 0 : 1;
+    sprintf(buf[bufnum], "0x%X", err);
+    return buf[bufnum];
+#else /* !1 */
+    if (err >= errSecErrnoBase && err <= errSecErrnoLimit)
+        return strerror(err - 100000);
+
+#ifdef MAC_OS_X_VERSION_10_4
+    /* AvailabilityMacros.h would only define this if we are on a
+       Tiger or later machine. */
+    extern const char *cssmErrorString(long);
+    return cssmErrorString(err);
+#else /* !defined(MAC_OS_X_VERSION_10_4) */
+    extern const char *_ZN8Security15cssmErrorStringEl(long);
+    return _ZN8Security15cssmErrorStringEl(err);
+#endif /* MAC_OS_X_VERSION_10_4 */
+#endif /* !1 */
+}
+
+/* run one test, described by test, return info in test struct */
+int run_one_test(struct one_test_s *test, int argc, char * const *argv)
+{
+    struct timeval start, stop;
+    
+    if(test->entry==NULL) {
+        fprintf(stdout, "%s:%d: error, no entry\n", __FILE__, __LINE__);
+        return -1;
+    }
+    
+    gettimeofday(&start, NULL);
+    test->entry(argc, argv);
+    gettimeofday(&stop, NULL);
+    
+    
+    /* this may overflow... */
+    test->duration=(stop.tv_sec-start.tv_sec)*1000+(stop.tv_usec/1000)-(start.tv_usec/1000);
+    test->failed_tests=test_fails;
+
+    return test_plan_exit();
+ };