Permalink
Browse files

scratch dir

  • Loading branch information...
1 parent c33eea9 commit eea3fa3ba30b0becab17188e654bf1acca27a542 @kr committed Dec 17, 2012
Showing with 77 additions and 5 deletions.
  1. +4 −1 Readme.md
  2. +56 −0 ct/ct.c
  3. +3 −2 ct/ct.h
  4. +2 −2 ct/gen
  5. +3 −0 ct/internal.h
  6. +9 −0 msg-test.c
View
@@ -23,6 +23,9 @@ put a `+` in front of the _ctcheck command (as in the sample
makefile) and run make with its `-jN` flag, for example
`make -j16 check`, CT will run tests concurrently (and
hopefully in parallel).
+- A scratch directory can be obtained by calling ctdir()
+inside the test. This directory will be removed by the test
+runner after the test finishes.
## Terminal Output
@@ -38,7 +41,7 @@ cc -Werror -Wall -c -o ct/ct.o ct/ct.c
cc -Werror -Wall -c -o msg.o msg.c
cc ct/_ctcheck.o ct/ct.o msg.o msg-test.o -o ct/_ctcheck
ct/_ctcheck
-E..FEF
+E...FEF
cttestexit: error (exit status 2)
View
56 ct/ct.c
@@ -6,14 +6,17 @@
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
+#include <dirent.h>
#include <errno.h>
#include "internal.h"
#include "ct.h"
+static T *curtest;
static int rjobfd = -1, wjobfd = -1;
@@ -39,6 +42,14 @@ ctfail(void)
}
+char *
+ctdir(void)
+{
+ mkdir(curtest->dir, 0700);
+ return curtest->dir;
+}
+
+
static void
die(int code, int err, char *msg)
{
@@ -99,6 +110,8 @@ start(T *t)
die(1, errno, "tmpfile");
}
t->fd = fileno(out);
+ strcpy(t->dir, TmpDirPat);
+ mktemp(t->dir);
t->pid = fork();
if (t->pid < 0) {
die(1, errno, "fork");
@@ -113,6 +126,7 @@ start(T *t)
if (dup2(1, 2) == -1) {
die(3, errno, "dup2");
}
+ curtest = t;
t->f();
_exit(0);
}
@@ -152,13 +166,55 @@ copyfd(FILE *out, int in)
}
+// Removes path and all of its children.
+// Writes errors to stderr and keeps going.
+// If path doesn't exist, rmtree returns silently.
+static void
+rmtree(char *path)
+{
+ int r = unlink(path);
+ if (r == 0 || errno == ENOENT) {
+ return; // success
+ }
+ int unlinkerr = errno;
+
+ DIR *d = opendir(path);
+ if (!d) {
+ if (errno == ENOTDIR) {
+ fprintf(stderr, "ct: unlink: %s\n", strerror(unlinkerr));
+ } else {
+ perror("ct: opendir");
+ }
+ fprintf(stderr, "ct: path %s\n", path);
+ return;
+ }
+ struct dirent *ent;
+ while ((ent = readdir(d))) {
+ if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
+ continue;
+ }
+ int n = strlen(path) + 1 + strlen(ent->d_name);
+ char s[n];
+ sprintf(s, "%s/%s", path, ent->d_name);
+ rmtree(s);
+ }
+ closedir(d);
+ r = rmdir(path);
+ if (r == -1) {
+ perror("ct: rmdir");
+ fprintf(stderr, "ct: path %s\n", path);
+ }
+}
+
+
static int
report(T t[])
{
int nfail = 0, nerr = 0;
putchar('\n');
for (; t->f; t++) {
+ rmtree(t->dir);
if (!t->status) {
continue;
}
View
@@ -1,5 +1,6 @@
-void ctfail(void);
-void ctlogpn(char*, int, char*, ...) __attribute__((format(printf, 3, 4)));
+char *ctdir(void);
+void ctfail(void);
+void ctlogpn(char*, int, char*, ...) __attribute__((format(printf, 3, 4)));
#define ctlog(...) ctlogpn(__FILE__, __LINE__, __VA_ARGS__)
#define assert(x) do if (!(x)) {\
ctlog("%s", "test: " #x);\
View
4 ct/gen
@@ -26,9 +26,9 @@ gen() {
printf 'T ctmain[] = {\n'
for t in "$@"
- do printf ' {%s, "%s", 0, 0, 0},\n' $t $t
+ do printf ' {%s, "%s", 0, 0, 0, {}},\n' $t $t
done
- printf ' {0, 0, 0, 0, 0},\n'
+ printf ' {0, 0, 0, 0, 0, {}},\n'
printf '};\n'
}
View
@@ -1,3 +1,5 @@
+#define TmpDirPat "/tmp/ct.XXXXXX"
+
typedef struct T T;
struct T {
@@ -6,6 +8,7 @@ struct T {
int status;
int fd;
int pid;
+ char dir[sizeof TmpDirPat];
};
extern T ctmain[];
View
@@ -1,5 +1,7 @@
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <stdio.h>
#include "msg.h"
#include "ct/ct.h"
@@ -43,6 +45,13 @@ cttestsegfault()
*(volatile int*)0 = 0;
}
+void
+cttesttmpdir()
+{
+ assert(chdir(ctdir()) == 0);
+ assert(open("x", O_CREAT|O_RDWR, 0777));
+}
+
void
cttestexit()
{

0 comments on commit eea3fa3

Please sign in to comment.