Permalink
Browse files

Overhaul.

 * Remove groups and setup and teardown functions.
 * Redo codegen in sh.
 * Refactor and simplify greatly.
  • Loading branch information...
1 parent 68ad064 commit a8801ac81b36625e92e51284ef947383e01810d2 @kr committed Dec 7, 2010
Showing with 157 additions and 707 deletions.
  1. +0 −1 .gitignore
  2. +9 −7 Makefile
  3. +76 −221 ct/ct.c
  4. +3 −58 ct/ct.h
  5. +0 −414 ct/ctgen.c
  6. +43 −0 ct/gen
  7. +9 −0 ct/internal.h
  8. +17 −6 msg_test.c
View
@@ -1,4 +1,3 @@
*.o
_*
hello
-ct/ctgen
View
@@ -1,22 +1,24 @@
CFLAGS ?= -Werror -Wall
libs = msg.c
+objs = $(libs:.c=.o)
+testcs = $(wildcard *_test.c)
+tests = $(testcs:.c=.o)
all: hello
-hello: hello.o $(libs:.c=.o)
-
-tests = $(wildcard *_test.c)
+hello: hello.o $(objs)
.PHONY: check
check: ct/_ctcheck
ct/_ctcheck
-ct/_ctcheck: ct/_ctcheck.o ct/ct.o $(libs:.c=.o) $(tests:.c=.o)
+ct/_ctcheck: ct/_ctcheck.o ct/ct.o $(objs) $(tests)
-ct/_ctcheck.c: $(tests) ct/ctgen
- ct/ctgen -o ct/_ctcheck.c $(tests)
+ct/_ctcheck.c: $(tests) ct/gen
+ ct/gen $(tests) > $@.part
+ mv $@.part $@
.PHONY: clean
clean:
- rm -f ct/_* *.o ct/*.o ct/ctgen hello
+ rm -f ct/_* *.o ct/*.o hello
View
297 ct/ct.c
@@ -1,55 +1,17 @@
-/*
- * libcut.inc
- * CUT 2.1
- *
- * Copyright (c) 2001-2002 Samuel A. Falvo II, William D. Tanksley
- * See CUT-LICENSE.TXT for details.
- *
- * Based on WDT's 'TestAssert' package.
- *
- * $log$
- */
+/* CT - (Relatively) Easy Unit Testing for C */
+
+/* Inspired by CUT 2.1 by Sam Falvo and Billy Tanksley. */
+/* Also with ideas from the Go testing package. */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
+#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
-#include "ct.h"
-
-
-#define BUF_SIZE 1024
-
-#ifndef BOOL /* Just in case -- helps in portability */
-#define BOOL int
-#endif
-
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-typedef struct test_output *test_output;
-
-struct test_output {
- test_output next;
- int status;
- const char *desc;
- const char *group_name;
- const char *test_name;
- FILE *file;
-};
-
-static int breakpoint = 0;
-static int count = 0, count_failures = 0, count_errors = 0;
-static cut_fn cur_takedown = 0;
-static test_output problem_reports = 0;
-static const char *program;
+#include "internal.h"
static void
die(int code, const char *fmt, ...)
@@ -67,223 +29,116 @@ die(int code, const char *fmt, ...)
exit(code);
}
-/* I/O Functions */
-
-static void print_string( char *string )
-{
- printf( "%s", string );
- fflush( stdout );
-}
-
-static void print_string_as_error( char *filename, int lineNumber, char *string )
+static int
+failed(int s)
{
- printf( " %s:%d: %s", filename, lineNumber, string );
- fflush( stdout );
+ return WIFEXITED(s) && (WEXITSTATUS(s) == 255);
}
-static void print_integer( int i )
-{
- printf( "%d", i );
- fflush( stdout );
-}
-
-static void print_integer_in_field( int i, int width )
-{
- printf( "%*d", width, i );
- fflush( stdout );
-}
-
-static void new_line( void )
-{
- printf( "\n" );
- fflush( stdout );
-}
-
-static void print_character( char ch )
-{
- printf( "%c", ch );
- fflush( stdout );
-}
-
-/* CUT Initialization and Takedown Functions */
-
-void cut_init(const char *prog_name, int brkpoint )
-{
- breakpoint = brkpoint;
- count = 0;
- program = prog_name;
-
- if( brkpoint >= 0 )
- {
- print_string( "Breakpoint at test " );
- print_integer( brkpoint );
- new_line();
- }
-}
-
-void cut_exit( void )
+void
+ct_exit(T ts[], int n)
{
- int r, s;
- char buf[BUF_SIZE];
- test_output to;
-
- printf("\n");
- for (to = problem_reports; to; to = to->next) {
- printf("\n%s in %s/%s", to->desc, to->group_name, to->test_name);
- if (!WIFEXITED(to->status) || (WEXITSTATUS(to->status) != 255)) {
- if (WIFEXITED(to->status)) {
- printf(" (Exit Status %d)", WEXITSTATUS(to->status));
+ int i, r, s;
+ char buf[1024]; // arbitrary size
+ int cf = 0, ce = 0;
+
+ putchar('\n');
+ for (i = 0; i < n; i++) {
+ if (!ts[i].status) continue;
+
+ printf("\n%s: ", ts[i].name);
+ if (failed(ts[i].status)) {
+ cf++;
+ printf("failure");
+ } else {
+ ce++;
+ printf("error");
+ if (WIFEXITED(ts[i].status)) {
+ printf(" (exit status %d)", WEXITSTATUS(ts[i].status));
}
- if (WIFSIGNALED(to->status)) {
- printf(" (Signal %d)", WTERMSIG(to->status));
+ if (WIFSIGNALED(ts[i].status)) {
+ printf(" (signal %d)", WTERMSIG(ts[i].status));
}
}
- printf("\n");
- rewind(to->file);
- while ((r = fread(buf, 1, BUF_SIZE, to->file))) {
+
+ putchar('\n');
+ lseek(ts[i].fd, 0, SEEK_SET);
+ while ((r = read(ts[i].fd, buf, sizeof(buf)))) {
s = fwrite(buf, 1, r, stdout);
if (r != s) die(3, "fwrite");
}
}
- printf("\n%d tests; %d failures; %d errors.\n", count, count_failures,
- count_errors);
- exit(!!(count_failures + count_errors));
+ printf("\n%d tests; %d failures; %d errors.\n", n, cf, ce);
+ exit(!!(cf + ce));
}
-/* Test Progress Accounting functions */
-
-static void
-cut_mark_point(char out, char *filename, int lineNumber )
-{
- if ((count % 10) == 0) {
- if ((count % 50) == 0) new_line();
- print_integer_in_field( count, 5 );
- }
-
- print_character(out);
- count++;
-
- if( count == breakpoint )
- {
- print_string_as_error( filename, lineNumber, "Breakpoint hit" );
- new_line();
- cut_exit();
- }
-}
-
-
-void __cut_assert(
- char *filename,
- int lineNumber,
- char *message,
- char *expression,
- BOOL success
- )
+void
+ct_fail_(char *file, int line, char *exp, char *msg)
{
- if (success) return;
-
- print_string_as_error( filename, lineNumber, "(" );
- print_string( expression );
- print_string(") ");
- print_string( message );
- new_line();
-
- if (cur_takedown) cur_takedown();
+ printf(" %s:%d: (%s) %s\n", file, line, exp, msg);
fflush(stdout);
fflush(stderr);
exit(-1);
}
-typedef void(*collect_fn)(void *);
-
-static FILE *
-collect(pid_t *pid, collect_fn fn, void *data)
+void
+ct_run(T *t, int i, ct_fn f, const char *name)
{
- int r;
+ pid_t pid;
+ int status, r, ofd;
+ char c;
FILE *out;
+ t->name = name;
+
out = tmpfile();
- if (!out) return 0;
+ if (!out) die(1, "tmpfile");
+ ofd = fileno(out);
fflush(stdout);
fflush(stderr);
- if ((*pid = fork())) {
- if (*pid < 0) return 0;
- return out;
- } else {
- r = dup2(fileno(out), fileno(stdout));
+ pid = fork();
+ if (pid < 0) {
+ die(1, "fork");
+ } else if (!pid) {
+ r = dup2(ofd, 1); // send stdout to tmpfile
+ if (r == -1) die(3, "dup2");
+
+ r = close(ofd);
+ if (r == -1) die(3, "fclose");
+
+ r = dup2(1, 2); // send stderr to stdout
if (r < 0) die(3, "dup2");
- r = fclose(out);
- if (r) die(3, "fclose");
- out = 0;
- fn(data);
+ f();
exit(0);
}
-}
-
-static void
-run_in_child(void *data)
-{
- int r;
- cut_fn *fns = data, bringup = fns[0], test = fns[1], takedown = fns[2];
-
- r = dup2(fileno(stdout), fileno(stderr));
- if (r < 0) die(3, "dup2");
- bringup();
- cur_takedown = takedown;
- test();
- takedown();
- fflush(stdout);
- fflush(stderr);
-}
-
-void
-__cut_run(char *group_name, cut_fn bringup, cut_fn takedown, char *test_name,
- cut_fn test, char *filename, int lineno)
-{
- pid_t pid = -1;
- int status, r;
- FILE *out;
- test_output to;
- char *problem_desc = 0;
- cut_fn fns[3] = { bringup, test, takedown };
-
- out = collect(&pid, run_in_child, fns);
- if (!out) die(1, " %s:%d: collect", filename, lineno);
- if (pid < 0) die(3, "fork");
r = waitpid(pid, &status, 0);
if (r != pid) die(3, "wait");
+ t->status = status;
if (!status) {
- cut_mark_point('.', filename, lineno );
- } else if (WIFEXITED(status) && (WEXITSTATUS(status) == 255)) {
- cut_mark_point('F', filename, lineno );
- count_failures++;
- problem_desc = "Failure";
+ // Since we won't need the (potentially large) output,
+ // free its disk space immediately.
+ close(ofd);
+ c = '.';
+ } else if (failed(status)) {
+ c = 'F';
} else {
- cut_mark_point('E', filename, lineno );
- count_errors++;
- problem_desc = "Error";
+ c = 'E';
}
+ t->fd = ofd;
- if (!problem_desc) {
- fclose(out);
- return;
+ if (i % 10 == 0) {
+ if (i % 50 == 0) {
+ putchar('\n');
+ }
+ printf("%5d", i);
}
- /* collect the output */
- to = malloc(sizeof(struct test_output));
- if (!to) die(3, "malloc");
-
- to->desc = problem_desc;
- to->status = status;
- to->group_name = group_name;
- to->test_name = test_name;
- to->file = out;
- to->next = problem_reports;
- problem_reports = to;
+ putchar(c);
+ fflush(stdout);
}
Oops, something went wrong.

0 comments on commit a8801ac

Please sign in to comment.