36 using std::unique_ptr;
40 static std::string currentTestName;
43 CheckResult::~CheckResult()
47 std::cerr <<
"Check failed";
49 if (not currentTestName.empty())
50 std::cerr <<
" in test '" << currentTestName <<
"'";
54 if (expected_.empty())
55 std::cerr <<
" " << actual_ <<
"\n";
59 <<
" expected `" << expected_
60 <<
"`, got `" << actual_ <<
"`\n"
64 <<
" " << message_.str()
73 static TestResult ProcessChildStatus(
int status)
75 if (WIFEXITED(status))
76 return static_cast<TestResult>(WEXITSTATUS(status));
78 if (WIFSIGNALED(status))
80 if (WTERMSIG(status) == SIGSEGV)
87 assert(
false &&
"unhandled child exit mode");
98 PosixSharedMemory(
int fd,
size_t len,
void *rawPtr)
99 : shmfd(fd), length(len), ptr(rawPtr)
109 virtual void *rawPointer()
const override {
return ptr; }
120 int shmfd = shm_open(
"shm.tmp", O_RDWR);
121 void *map = mmap(0, len, PROT_READ | PROT_WRITE,
122 MAP_ANON | MAP_SHARED, shmfd, 0);
124 return unique_ptr<SharedMemory>(
new PosixSharedMemory(shmfd, len, map));
129 time_t timeout, std::ostream& errorStream)
135 pid_t child = fork();
139 currentTestName = name;
142 std::cerr.rdbuf(errorStream.rdbuf());
145 exit(static_cast<int>(result));
150 int options = (timeout ? WNOHANG : 0);
152 time_t start = time(
nullptr);
156 pid_t result = waitpid(child, &status, options);
165 assert(errno == EINTR);
170 const time_t now = time(
nullptr);
171 if ((now - start) > timeout)
173 kill(child, SIGKILL);
174 waitpid(child, &status, 0);
181 return ProcessChildStatus(status);
the test took too long to run
A library for grading C- and C++-based assignments.
TestResult
The result of running one test within a separate process.
std::unique_ptr< SharedMemory > MapSharedData(size_t size)
Map data into the address space that can be shared with other processes.
the test caused a segmentation fault
A representation of a shared memory object.
TestResult RunTest(std::function< TestResult()> test, std::string name="<unnamed test>", time_t timeout=0, std::ostream &errorStream=std::cerr)
Run a test closure in a separate process, capturing segmentation faults and other errors that lead to...
the test terminated for another reason
Container for all libgrading names.