You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by rb...@rkbloom.net on 2004/06/06 00:09:28 UTC

Re: cvs commit: apr-util/test abts.c abts.h abts_tests.h testutil.c testutil.h Makefile.in testuuid.c test_aprutil.h testall.c

This commit removes all instances of CuTest from the apr-util test suite
(I had some time while Abby ate dinner tonight).  Somebody still needs to
port all of the existing tests to abts and combine them into the test
framework.  I may start this work soon, but I'm going to be going very
slowly with it, so somebody else could easily beat me to it.

Ryan

On 5 Jun 2004 rbb@apache.org wrote:

> rbb         2004/06/05 15:19:42
>
>   Modified:    test     Makefile.in testuuid.c
>   Added:       test     abts.c abts.h abts_tests.h testutil.c testutil.h
>   Removed:     test     test_aprutil.h testall.c
>   Log:
>   Migrate APR-Util to abts for the test suite.  Testuuid is still the only
>   test using the unified framework for apr-util.
>
>   Revision  Changes    Path
>   1.41      +1 -1      apr-util/test/Makefile.in
>
>   Index: Makefile.in
>   ===================================================================
>   RCS file: /home/cvs/apr-util/test/Makefile.in,v
>   retrieving revision 1.40
>   retrieving revision 1.41
>   diff -u -r1.40 -r1.41
>   --- Makefile.in	28 Mar 2004 14:58:04 -0000	1.40
>   +++ Makefile.in	5 Jun 2004 22:19:41 -0000	1.41
>   @@ -81,7 +81,7 @@
>    testpass: $(testpass_OBJECTS) $(testpass_LDADD)
>    	$(LINK) $(APRUTIL_LDFLAGS) $(testpass_OBJECTS) $(testpass_LDADD) $(PROGRAM_DEPENDENCIES)
>
>   -testall_OBJECTS = testall.lo testuuid.lo CuTest.lo
>   +testall_OBJECTS = testuuid.lo abts.lo testutil.lo
>    testall_LDADD =  $(TARGET_LIB_PATH)
>    testall: $(testall_OBJECTS) $(testall_LDADD)
>    	$(LINK) $(APRUTIL_LDFLAGS) $(testall_OBJECTS) $(testall_LDADD) $(PROGRAM_DEPENDENCIES)
>
>
>
>   1.5       +9 -9      apr-util/test/testuuid.c
>
>   Index: testuuid.c
>   ===================================================================
>   RCS file: /home/cvs/apr-util/test/testuuid.c,v
>   retrieving revision 1.4
>   retrieving revision 1.5
>   diff -u -r1.4 -r1.5
>   --- testuuid.c	11 Mar 2004 02:42:34 -0000	1.4
>   +++ testuuid.c	5 Jun 2004 22:19:41 -0000	1.5
>   @@ -13,11 +13,11 @@
>     * limitations under the License.
>     */
>
>   -#include "test_aprutil.h"
>   +#include "testutil.h"
>    #include "apr_general.h"
>    #include "apr_uuid.h"
>
>   -static void test_uuid_parse(CuTest *tc)
>   +static void test_uuid_parse(abts_case *tc, void *data)
>    {
>        apr_uuid_t uuid;
>        apr_uuid_t uuid2;
>   @@ -27,11 +27,11 @@
>        apr_uuid_format(buf, &uuid);
>
>        apr_uuid_parse(&uuid2, buf);
>   -    CuAssert(tc, "parse produced a different UUID",
>   +    ABTS_ASSERT(tc, "parse produced a different UUID",
>                 memcmp(&uuid, &uuid2, sizeof(uuid)) == 0);
>    }
>
>   -static void test_gen2(CuTest *tc)
>   +static void test_gen2(abts_case *tc, void *data)
>    {
>        apr_uuid_t uuid;
>        apr_uuid_t uuid2;
>   @@ -40,16 +40,16 @@
>        apr_uuid_get(&uuid);
>        apr_uuid_get(&uuid2);
>
>   -    CuAssert(tc, "generated the same UUID twice",
>   +    ABTS_ASSERT(tc, "generated the same UUID twice",
>                 memcmp(&uuid, &uuid2, sizeof(uuid)) != 0);
>    }
>
>   -CuSuite *testuuid(void)
>   +abts_suite *testuuid(abts_suite *suite)
>    {
>   -    CuSuite *suite = CuSuiteNew("UUID");
>   +    suite = ADD_SUITE(suite);
>
>   -    SUITE_ADD_TEST(suite, test_uuid_parse);
>   -    SUITE_ADD_TEST(suite, test_gen2);
>   +    abts_run_test(suite, test_uuid_parse, NULL);
>   +    abts_run_test(suite, test_gen2, NULL);
>
>        return suite;
>    }
>
>
>
>   1.1                  apr-util/test/abts.c
>
>   Index: abts.c
>   ===================================================================
>   /* Copyright 2000-2004 Ryan Bloom
>    *
>    * Licensed under the Apache License, Version 2.0 (the "License");
>    * you may not use this file except in compliance with the License.
>    * You may obtain a copy of the License at
>    *
>    *     http://www.apache.org/licenses/LICENSE-2.0
>    *
>    * Unless required by applicable law or agreed to in writing, software
>    * distributed under the License is distributed on an "AS IS" BASIS,
>    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>    * See the License for the specific language governing permissions and
>    * limitations under the License.
>    *
>    * Portions of this file were taken from testall.c in the APR test suite,
>    * written by members of the Apache Software Foundation.
>    */
>
>   #include "abts.h"
>   #include "abts_tests.h"
>   #include "testutil.h"
>
>   #define ABTS_STAT_SIZE 6
>   static char status[ABTS_STAT_SIZE] = {'|', '/', '-', '|', '\\', '-'};
>   static int curr_char;
>   static int verbose = 0;
>   static int exclude = 0;
>   static int quiet = 0;
>   static int list_tests = 0;
>
>   const char **testlist = NULL;
>
>   static int find_test_name(const char *testname) {
>       int i;
>       for (i = 0; testlist[i] != NULL; i++) {
>           if (!strcmp(testlist[i], testname)) {
>               return 1;
>           }
>       }
>       return 0;
>   }
>
>   /* Determine if the test should be run at all */
>   static int should_test_run(const char *testname) {
>       int found = 0;
>       if (list_tests == 1) {
>           return 0;
>       }
>       if (testlist == NULL) {
>           return 1;
>       }
>       found = find_test_name(testname);
>       if ((found && !exclude) || (!found && exclude)) {
>           return 1;
>       }
>       return 0;
>   }
>
>   static void reset_status(void)
>   {
>       curr_char = 0;
>   }
>
>   static void update_status(void)
>   {
>       if (!quiet) {
>           curr_char = (curr_char + 1) % ABTS_STAT_SIZE;
>           fprintf(stdout, "\b%c", status[curr_char]);
>           fflush(stdout);
>       }
>   }
>
>   static void end_suite(abts_suite *suite)
>   {
>       if (suite != NULL) {
>           sub_suite *last = suite->tail;
>           if (!quiet) {
>               fprintf(stdout, "\b");
>               fflush(stdout);
>           }
>           if (last->failed == 0) {
>               fprintf(stdout, "SUCCESS\n");
>               fflush(stdout);
>           }
>           else {
>               fprintf(stdout, "FAILED %d of %d\n", last->failed, last->num_test);
>               fflush(stdout);
>           }
>       }
>   }
>
>   abts_suite *abts_add_suite(abts_suite *suite, const char *suite_name_full)
>   {
>       sub_suite *subsuite;
>       char *p;
>       const char *suite_name;
>       curr_char = 0;
>
>       /* Only end the suite if we actually ran it */
>       if (suite && suite->tail &&!suite->tail->not_run) {
>           end_suite(suite);
>       }
>
>       subsuite = malloc(sizeof(*subsuite));
>       subsuite->num_test = 0;
>       subsuite->failed = 0;
>       subsuite->next = NULL;
>       /* suite_name_full may be an absolute path depending on __FILE__
>        * expansion */
>       suite_name = strrchr(suite_name_full, '/');
>       if (suite_name) {
>           suite_name++;
>       } else {
>           suite_name = suite_name_full;
>       }
>       p = strrchr(suite_name, '.');
>       if (p) {
>           subsuite->name = memcpy(calloc(p - suite_name + 1, 1),
>                                   suite_name, p - suite_name);
>       }
>       else {
>           subsuite->name = suite_name;
>       }
>
>       if (list_tests) {
>           fprintf(stdout, "%s\n", subsuite->name);
>       }
>
>       subsuite->not_run = 0;
>
>       if (suite == NULL) {
>           suite = malloc(sizeof(*suite));
>           suite->head = subsuite;
>           suite->tail = subsuite;
>       }
>       else {
>           suite->tail->next = subsuite;
>           suite->tail = subsuite;
>       }
>
>       if (!should_test_run(subsuite->name)) {
>           subsuite->not_run = 1;
>           return suite;
>       }
>
>       reset_status();
>       fprintf(stdout, "%s:  ", subsuite->name);
>       update_status();
>       fflush(stdout);
>
>       return suite;
>   }
>
>   void abts_run_test(abts_suite *ts, test_func f, void *value)
>   {
>       abts_case *tc;
>       sub_suite *ss;
>
>       if (!should_test_run(ts->tail->name)) {
>           return;
>       }
>       ss = ts->tail;
>
>       tc = malloc(sizeof(tc));
>       tc->failed = 0;
>       tc->suite = ss;
>
>       ss->num_test++;
>       update_status();
>
>       f(tc, value);
>
>       if (tc->failed) {
>           ss->failed++;
>       }
>       free(tc);
>   }
>
>   static int report(abts_suite *suite)
>   {
>       int count = 0;
>       sub_suite *dptr;
>
>       if (suite && suite->tail &&!suite->tail->not_run) {
>           end_suite(suite);
>       }
>
>       for (dptr = suite->head; dptr; dptr = dptr->next) {
>           count += dptr->failed;
>       }
>
>       if (count == 0) {
>           printf("All tests passed.\n");
>           return 0;
>       }
>
>       dptr = suite->head;
>       fprintf(stdout, "%-15s\t\tTotal\tFail\tFailed %%\n", "Failed Tests");
>       fprintf(stdout, "===================================================\n");
>       while (dptr != NULL) {
>           if (dptr->failed != 0) {
>               float percent = ((float)dptr->failed / (float)dptr->num_test);
>               fprintf(stdout, "%-15s\t\t%5d\t%4d\t%6.2f%%\n", dptr->name,
>                       dptr->num_test, dptr->failed, percent * 100);
>           }
>           dptr = dptr->next;
>       }
>       return 1;
>   }
>
>   void abts_log_message(const char *fmt, ...)
>   {
>       va_list args;
>       update_status();
>
>       if (verbose) {
>           va_start(args, fmt);
>           vfprintf(stderr, fmt, args);
>           va_end(args);
>           fprintf(stderr, "\n");
>           fflush(stderr);
>       }
>   }
>
>   void abts_int_equal(abts_case *tc, const int expected, const int actual, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (expected == actual) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: expected <%d>, but saw <%d>\n", lineno, expected, actual);
>           fflush(stderr);
>       }
>   }
>
>   void abts_int_nequal(abts_case *tc, const int expected, const int actual, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (expected != actual) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: expected <%d>, but saw <%d>\n", lineno, expected, actual);
>           fflush(stderr);
>       }
>   }
>
>   void abts_str_equal(abts_case *tc, const char *expected, const char *actual, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (!strcmp(expected, actual)) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: expected <%s>, but saw <%s>\n", lineno, expected, actual);
>           fflush(stderr);
>       }
>   }
>
>   void abts_str_nequal(abts_case *tc, const char *expected, const char *actual,
>                          size_t n, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (!strncmp(expected, actual, n)) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: expected <%s>, but saw <%s>\n", lineno, expected, actual);
>           fflush(stderr);
>       }
>   }
>
>   void abts_ptr_notnull(abts_case *tc, const void *ptr, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (ptr != NULL) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: Expected NULL, but saw <%p>\n", lineno, ptr);
>           fflush(stderr);
>       }
>   }
>
>   void abts_ptr_equal(abts_case *tc, const void *expected, const void *actual, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (expected == actual) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: expected <%p>, but saw <%p>\n", lineno, expected, actual);
>           fflush(stderr);
>       }
>   }
>
>   void abts_fail(abts_case *tc, const char *message, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: %s\n", lineno, message);
>           fflush(stderr);
>       }
>   }
>
>   void abts_assert(abts_case *tc, const char *message, int condition, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (condition) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: %s\n", lineno, message);
>           fflush(stderr);
>       }
>   }
>
>   void abts_true(abts_case *tc, int condition, int lineno)
>   {
>       update_status();
>       if (tc->failed) return;
>
>       if (condition) return;
>
>       tc->failed = TRUE;
>       if (verbose) {
>           fprintf(stderr, "Line %d: Condition is false, but expected true\n", lineno);
>           fflush(stderr);
>       }
>   }
>
>   void abts_not_impl(abts_case *tc, const char *message, int lineno)
>   {
>       update_status();
>
>       tc->suite->not_impl++;
>       if (verbose) {
>           fprintf(stderr, "Line %d: %s\n", lineno, message);
>           fflush(stderr);
>       }
>   }
>
>   int main(int argc, const char *const argv[]) {
>       int i;
>       int rv;
>       int list_provided = 0;
>       abts_suite *suite = NULL;
>
>       initialize();
>       for (i = 1; i < argc; i++) {
>           if (!strcmp(argv[i], "-v")) {
>               verbose = 1;
>               continue;
>           }
>           if (!strcmp(argv[i], "-x")) {
>               exclude = 1;
>               continue;
>           }
>           if (!strcmp(argv[i], "-l")) {
>               list_tests = 1;
>               continue;
>           }
>           if (!strcmp(argv[i], "-q")) {
>               quiet = 1;
>               continue;
>           }
>           if (argv[i][0] == '-') {
>               fprintf(stderr, "Invalid option: `%s'\n", argv[i]);
>               exit(1);
>           }
>           list_provided = 1;
>       }
>
>       if (list_provided) {
>           /* Waste a little space here, because it is easier than counting the
>            * number of tests listed.  Besides it is at most three char *.
>            */
>           testlist = calloc(argc + 1, sizeof(char *));
>           for (i = 1; i < argc; i++) {
>               testlist[i - 1] = argv[i];
>           }
>       }
>
>       for (i = 0; i < (sizeof(alltests) / sizeof(struct testlist *)); i++) {
>           suite = alltests[i].func(suite);
>       }
>
>       rv = report(suite);
>       return rv;
>   }
>
>
>
>
>   1.1                  apr-util/test/abts.h
>
>   Index: abts.h
>   ===================================================================
>   /* Copyright 2000-2004 Ryan Bloom
>    *
>    * Licensed under the Apache License, Version 2.0 (the "License");
>    * you may not use this file except in compliance with the License.
>    * You may obtain a copy of the License at
>    *
>    *     http://www.apache.org/licenses/LICENSE-2.0
>    *
>    * Unless required by applicable law or agreed to in writing, software
>    * distributed under the License is distributed on an "AS IS" BASIS,
>    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>    * See the License for the specific language governing permissions and
>    * limitations under the License.
>    */
>
>   #ifdef __cplusplus
>   extern "C" {
>   #endif
>
>   #include <stdarg.h>
>   #include <stdio.h>
>   #include <stdlib.h>
>   #include <string.h>
>
>   #ifndef ABTS_H
>   #define ABTS_H
>
>   #ifndef FALSE
>   #define FALSE 0
>   #endif
>   #ifndef TRUE
>   #define TRUE  1
>   #endif
>
>   struct sub_suite {
>       const char *name;
>       int num_test;
>       int failed;
>       int not_run;
>       int not_impl;
>       struct sub_suite *next;
>   };
>   typedef struct sub_suite sub_suite;
>
>   struct abts_suite {
>       sub_suite *head;
>       sub_suite *tail;
>   };
>   typedef struct abts_suite abts_suite;
>
>   struct abts_case {
>       int failed;
>       sub_suite *suite;
>   };
>   typedef struct abts_case abts_case;
>
>   typedef void (*test_func)(abts_case *tc, void *data);
>
>   #define ADD_SUITE(suite) abts_add_suite(suite, __FILE__);
>
>   abts_suite *abts_add_suite(abts_suite *suite, const char *suite_name);
>   void abts_run_test(abts_suite *ts, test_func f, void *value);
>   void abts_log_message(const char *fmt, ...);
>
>   void abts_int_equal(abts_case *tc, const int expected, const int actual, int lineno);
>   void abts_int_nequal(abts_case *tc, const int expected, const int actual, int lineno);
>   void abts_str_equal(abts_case *tc, const char *expected, const char *actual, int lineno);
>   void abts_str_nequal(abts_case *tc, const char *expected, const char *actual,
>                          size_t n, int lineno);
>   void abts_ptr_notnull(abts_case *tc, const void *ptr, int lineno);
>   void abts_ptr_equal(abts_case *tc, const void *expected, const void *actual, int lineno);
>   void abts_true(abts_case *tc, int condition, int lineno);
>   void abts_fail(abts_case *tc, const char *message, int lineno);
>   void abts_not_impl(abts_case *tc, const char *message, int lineno);
>   void abts_assert(abts_case *tc, const char *message, int condition, int lineno);
>
>   /* Convenience macros. Ryan hates these! */
>   #define ABTS_INT_EQUAL(a, b, c)     abts_int_equal(a, b, c, __LINE__)
>   #define ABTS_INT_NEQUAL(a, b, c)    abts_int_nequal(a, b, c, __LINE__)
>   #define ABTS_STR_EQUAL(a, b, c)     abts_str_equal(a, b, c, __LINE__)
>   #define ABTS_STR_NEQUAL(a, b, c, d) abts_str_nequal(a, b, c, d, __LINE__)
>   #define ABTS_PTR_NOTNULL(a, b)      abts_ptr_notnull(a, b, __LINE__)
>   #define ABTS_PTR_EQUAL(a, b, c)     abts_ptr_equal(a, b, c, __LINE__)
>   #define ABTS_TRUE(a, b)             abts_true(a, b, __LINE__);
>   #define ABTS_FAIL(a, b)             abts_fail(a, b, __LINE__);
>   #define ABTS_NOT_IMPL(a, b)         abts_not_impl(a, b, __LINE__);
>   #define ABTS_ASSERT(a, b, c)        abts_assert(a, b, c, __LINE__);
>
>   abts_suite *run_tests(abts_suite *suite);
>   abts_suite *run_tests1(abts_suite *suite);
>
>
>   #endif
>
>   #ifdef __cplusplus
>   }
>   #endif
>
>
>
>
>   1.1                  apr-util/test/abts_tests.h
>
>   Index: abts_tests.h
>   ===================================================================
>   /* Copyright 2000-2004 The Apache Software Foundation
>    *
>    * Licensed under the Apache License, Version 2.0 (the "License");
>    * you may not use this file except in compliance with the License.
>    * You may obtain a copy of the License at
>    *
>    *     http://www.apache.org/licenses/LICENSE-2.0
>    *
>    * Unless required by applicable law or agreed to in writing, software
>    * distributed under the License is distributed on an "AS IS" BASIS,
>    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>    * See the License for the specific language governing permissions and
>    * limitations under the License.
>    */
>
>   #ifndef APR_TEST_INCLUDES
>   #define APR_TEST_INCLUDES
>
>   #include "abts.h"
>   #include "testutil.h"
>
>   const struct testlist {
>       abts_suite *(*func)(abts_suite *suite);
>   } alltests[] = {
>       {testuuid}
>   };
>
>   #endif /* APR_TEST_INCLUDES */
>
>
>
>   1.1                  apr-util/test/testutil.c
>
>   Index: testutil.c
>   ===================================================================
>   /* Copyright 2000-2004 The Apache Software Foundation
>    *
>    * Licensed under the Apache License, Version 2.0 (the "License");
>    * you may not use this file except in compliance with the License.
>    * You may obtain a copy of the License at
>    *
>    *     http://www.apache.org/licenses/LICENSE-2.0
>    *
>    * Unless required by applicable law or agreed to in writing, software
>    * distributed under the License is distributed on an "AS IS" BASIS,
>    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>    * See the License for the specific language governing permissions and
>    * limitations under the License.
>    */
>
>   #include <stdio.h>
>   #include <stdlib.h>
>
>   #include "abts.h"
>   #include "testutil.h"
>   #include "apr_pools.h"
>
>   apr_pool_t *p;
>
>   void apr_assert_success(abts_case* tc, const char* context, apr_status_t rv)
>   {
>       if (rv == APR_ENOTIMPL) {
>           ABTS_NOT_IMPL(tc, context);
>       }
>
>       if (rv != APR_SUCCESS) {
>           char buf[STRING_MAX], ebuf[128];
>           sprintf(buf, "%s (%d): %s\n", context, rv,
>                   apr_strerror(rv, ebuf, sizeof ebuf));
>           ABTS_FAIL(tc, buf);
>       }
>   }
>
>   void initialize(void) {
>       apr_initialize();
>       atexit(apr_terminate);
>
>       apr_pool_create(&p, NULL);
>   }
>
>
>
>   1.1                  apr-util/test/testutil.h
>
>   Index: testutil.h
>   ===================================================================
>   /* Copyright 2000-2004 The Apache Software Foundation
>    *
>    * Licensed under the Apache License, Version 2.0 (the "License");
>    * you may not use this file except in compliance with the License.
>    * You may obtain a copy of the License at
>    *
>    *     http://www.apache.org/licenses/LICENSE-2.0
>    *
>    * Unless required by applicable law or agreed to in writing, software
>    * distributed under the License is distributed on an "AS IS" BASIS,
>    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>    * See the License for the specific language governing permissions and
>    * limitations under the License.
>    */
>
>   #include "apr_pools.h"
>   #include "abts.h"
>
>   #ifndef APR_TEST_UTIL
>   #define APR_TEST_UTIL
>
>   /* XXX FIXME */
>   #ifdef WIN32
>   #define EXTENSION ".exe"
>   #elif NETWARE
>   #define EXTENSION ".nlm"
>   #else
>   #define EXTENSION
>   #endif
>
>   #define STRING_MAX 8096
>
>   /* Some simple functions to make the test apps easier to write and
>    * a bit more consistent...
>    */
>
>   extern apr_pool_t *p;
>
>   /* Assert that RV is an APR_SUCCESS value; else fail giving strerror
>    * for RV and CONTEXT message. */
>   void apr_assert_success(abts_case* tc, const char *context, apr_status_t rv);
>
>   void initialize(void);
>
>   abts_suite *testuuid(abts_suite *suite);
>
>   #endif /* APR_TEST_INCLUDES */
>
>
>
>


Re: cvs commit: apr-util/test abts.c abts.h abts_tests.h testutil.c testutil.h Makefile.in testuuid.c test_aprutil.h testall.c

Posted by David Reid <da...@jetnet.co.uk>.
> This commit removes all instances of CuTest from the apr-util test suite
> (I had some time while Abby ate dinner tonight).  Somebody still needs to
> port all of the existing tests to abts and combine them into the test
> framework.  I may start this work soon, but I'm going to be going very
> slowly with it, so somebody else could easily beat me to it.

Thanks Ryan!

david