70d75d7acf
The following change imports google/capsicum-test@9333154 from GitHub, omitting the embedded version of googletest, as well as the incomplete libcasper. This test suite helps verify capsicum(3) support via functional tests written in the GoogleTest test framework. Kernel support for capsicum(4) is tested by side-effect of testing capsicum(3). NB: as discussed in a previous [closed] PR [1], the casper(3) tests are incomplete/buggy and will not pass on FreeBSD. Thus, I have no intention of integrating them into the build/test on FreeBSD as-is. The import command used was: ``` curl -L https://github.com/google/capsicum-test/tarball/9333154 | tar --strip-components=1 -xvzf - -C dist/ rm -Rf dist/*/ ``` 1. https://github.com/google/capsicum-test/pull/26 Reviewed by: emaste (mentor) Differential Revision: https://reviews.freebsd.org/D19261
103 lines
2.6 KiB
C++
103 lines
2.6 KiB
C++
#include "capsicum-test.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
|
|
#include <map>
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
bool verbose = false;
|
|
bool tmpdir_on_tmpfs = false;
|
|
bool force_mt = false;
|
|
bool force_nofork = false;
|
|
uid_t other_uid = 0;
|
|
|
|
namespace {
|
|
std::map<std::string, std::string> tmp_paths;
|
|
}
|
|
|
|
const char *TmpFile(const char *p) {
|
|
std::string pathname(p);
|
|
if (tmp_paths.find(pathname) == tmp_paths.end()) {
|
|
std::string fullname = tmpdir + "/" + pathname;
|
|
tmp_paths[pathname] = fullname;
|
|
}
|
|
return tmp_paths[pathname].c_str();
|
|
}
|
|
|
|
char ProcessState(int pid) {
|
|
#ifdef __linux__
|
|
// Open the process status file.
|
|
char s[1024];
|
|
snprintf(s, sizeof(s), "/proc/%d/status", pid);
|
|
FILE *f = fopen(s, "r");
|
|
if (f == NULL) return '\0';
|
|
|
|
// Read the file line by line looking for the state line.
|
|
const char *prompt = "State:\t";
|
|
while (!feof(f)) {
|
|
fgets(s, sizeof(s), f);
|
|
if (!strncmp(s, prompt, strlen(prompt))) {
|
|
fclose(f);
|
|
return s[strlen(prompt)];
|
|
}
|
|
}
|
|
fclose(f);
|
|
return '?';
|
|
#endif
|
|
#ifdef __FreeBSD__
|
|
char buffer[1024];
|
|
snprintf(buffer, sizeof(buffer), "ps -p %d -o state | grep -v STAT", pid);
|
|
sig_t original = signal(SIGCHLD, SIG_IGN);
|
|
FILE* cmd = popen(buffer, "r");
|
|
usleep(50000); // allow any pending SIGCHLD signals to arrive
|
|
signal(SIGCHLD, original);
|
|
int result = fgetc(cmd);
|
|
fclose(cmd);
|
|
// Map FreeBSD codes to Linux codes.
|
|
switch (result) {
|
|
case EOF:
|
|
return '\0';
|
|
case 'D': // disk wait
|
|
case 'R': // runnable
|
|
case 'S': // sleeping
|
|
case 'T': // stopped
|
|
case 'Z': // zombie
|
|
return result;
|
|
case 'W': // idle interrupt thread
|
|
return 'S';
|
|
case 'I': // idle
|
|
return 'S';
|
|
case 'L': // waiting to acquire lock
|
|
default:
|
|
return '?';
|
|
}
|
|
#endif
|
|
}
|
|
|
|
typedef std::vector<std::string> TestList;
|
|
typedef std::map<std::string, TestList*> SkippedTestMap;
|
|
static SkippedTestMap skipped_tests;
|
|
void TestSkipped(const char *testcase, const char *test, const std::string& reason) {
|
|
if (skipped_tests.find(reason) == skipped_tests.end()) {
|
|
skipped_tests[reason] = new TestList;
|
|
}
|
|
std::string testname(testcase);
|
|
testname += ".";
|
|
testname += test;
|
|
skipped_tests[reason]->push_back(testname);
|
|
}
|
|
|
|
void ShowSkippedTests(std::ostream& os) {
|
|
for (SkippedTestMap::iterator skiplist = skipped_tests.begin();
|
|
skiplist != skipped_tests.end(); ++skiplist) {
|
|
os << "Following tests were skipped because: " << skiplist->first << std::endl;
|
|
for (size_t ii = 0; ii < skiplist->second->size(); ++ii) {
|
|
const std::string& testname((*skiplist->second)[ii]);
|
|
os << " " << testname << std::endl;
|
|
}
|
|
}
|
|
}
|