Add a simple language for scripting tests
This commit is contained in:
@@ -171,6 +171,10 @@ if(BUILD_TESTING)
|
||||
target_compile_options(driver PRIVATE ${TEST_FLAGS})
|
||||
target_link_libraries(driver PRIVATE ${PROJECT_NAME})
|
||||
|
||||
add_executable(script_test ScriptTest.cpp)
|
||||
target_compile_options(script_test PRIVATE ${TEST_FLAGS})
|
||||
target_link_libraries(script_test PRIVATE ${PROJECT_NAME})
|
||||
|
||||
add_executable(driver_skip_list TestDriver.cpp)
|
||||
target_compile_options(driver_skip_list PRIVATE ${TEST_FLAGS})
|
||||
target_link_libraries(driver_skip_list PRIVATE skip_list)
|
||||
|
136
ScriptTest.cpp
Normal file
136
ScriptTest.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "Internal.h"
|
||||
#include <ConflictSet.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
inline size_t getPageSize() {
|
||||
static size_t kPageSize = sysconf(_SC_PAGESIZE);
|
||||
return kPageSize;
|
||||
}
|
||||
|
||||
/// Helper for rounding up to page size (or some other alignment)
|
||||
constexpr inline size_t rightAlign(size_t offset, size_t alignment) {
|
||||
return offset % alignment == 0 ? offset
|
||||
: ((offset / alignment) + 1) * alignment;
|
||||
}
|
||||
|
||||
using StringView = std::basic_string_view<uint8_t>;
|
||||
|
||||
inline StringView operator"" _v(const char *str, size_t size) {
|
||||
return {reinterpret_cast<const uint8_t *>(str), size};
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
|
||||
ConflictSet cs{0};
|
||||
ReferenceImpl ref{0};
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
int fd = open(argv[i], O_RDONLY);
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1) {
|
||||
int err = errno;
|
||||
fprintf(stderr, "stat error %s - %s\n", argv[i], strerror(err));
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
int64_t size = rightAlign(st.st_size, getPageSize());
|
||||
const uint8_t *begin =
|
||||
(uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
madvise((void *)begin, size, MADV_SEQUENTIAL);
|
||||
auto *const mapOriginal = begin;
|
||||
const auto sizeOriginal = size;
|
||||
|
||||
StringView b;
|
||||
StringView e;
|
||||
int64_t v = 0;
|
||||
std::vector<ConflictSet::WriteRange> writeRanges;
|
||||
std::vector<ConflictSet::ReadRange> readRanges;
|
||||
std::vector<ConflictSet::Result> results;
|
||||
|
||||
for (uint8_t *end = (uint8_t *)memchr(begin, '\n', size); end != nullptr;) {
|
||||
StringView line{begin, static_cast<size_t>(end - begin)};
|
||||
size -= end - begin + 1;
|
||||
begin = end + 1;
|
||||
end = (uint8_t *)memchr(begin, '\n', size);
|
||||
|
||||
if (line.starts_with("begin"_v)) {
|
||||
b = line.substr("begin "_v.size(), line.size());
|
||||
printf("b <- %.*s\n", int(b.size()), b.data());
|
||||
} else if (line.starts_with("end"_v)) {
|
||||
e = line.substr("end "_v.size(), line.size());
|
||||
printf("e <- %.*s\n", int(e.size()), e.data());
|
||||
} else if (line.starts_with("version"_v)) {
|
||||
line = line.substr("version "_v.size(), line.size());
|
||||
v = 0;
|
||||
for (auto c : line) {
|
||||
v = v * 10 + int(c) - int('0');
|
||||
}
|
||||
printf("v <- %" PRId64 "\n", v);
|
||||
} else if (line.starts_with("pointread"_v)) {
|
||||
printf("pointread\n");
|
||||
ConflictSet::ReadRange r;
|
||||
r.begin.p = b.data();
|
||||
r.begin.len = b.size();
|
||||
r.end.len = 0;
|
||||
r.readVersion = v;
|
||||
readRanges.push_back(r);
|
||||
} else if (line.starts_with("pointwrite"_v)) {
|
||||
printf("pointwrite\n");
|
||||
ConflictSet::WriteRange w;
|
||||
w.begin.p = b.data();
|
||||
w.begin.len = b.size();
|
||||
w.end.len = 0;
|
||||
writeRanges.push_back(w);
|
||||
} else if (line.starts_with("rangeread"_v)) {
|
||||
printf("rangeread\n");
|
||||
ConflictSet::ReadRange r;
|
||||
r.begin.p = b.data();
|
||||
r.begin.len = b.size();
|
||||
r.end.p = e.data();
|
||||
r.end.len = e.size();
|
||||
r.readVersion = v;
|
||||
readRanges.push_back(r);
|
||||
} else if (line.starts_with("rangewrite"_v)) {
|
||||
printf("rangewrite\n");
|
||||
ConflictSet::WriteRange w;
|
||||
w.begin.p = b.data();
|
||||
w.begin.len = b.size();
|
||||
w.end.p = e.data();
|
||||
w.end.len = e.size();
|
||||
writeRanges.push_back(w);
|
||||
} else if (line.starts_with("check"_v)) {
|
||||
printf("check\n");
|
||||
Arena arena;
|
||||
auto *expected = new (arena) ConflictSet::Result[readRanges.size()];
|
||||
auto *actual = new (arena) ConflictSet::Result[readRanges.size()];
|
||||
ref.check(readRanges.data(), expected, readRanges.size());
|
||||
cs.check(readRanges.data(), actual, readRanges.size());
|
||||
for (int i = 0; i < int(readRanges.size()); ++i) {
|
||||
assert(expected[i] == actual[i]);
|
||||
}
|
||||
readRanges = {};
|
||||
} else if (line.starts_with("addwrites"_v)) {
|
||||
printf("addwrites\n");
|
||||
cs.addWrites(writeRanges.data(), writeRanges.size(), v);
|
||||
ref.addWrites(writeRanges.data(), writeRanges.size(), v);
|
||||
writeRanges = {};
|
||||
} else if (line.starts_with("setoldest"_v)) {
|
||||
printf("setoldest\n");
|
||||
cs.setOldestVersion(v);
|
||||
ref.setOldestVersion(v);
|
||||
} else {
|
||||
printf("Unrecognized line: %.*s\n", int(line.size()), line.data());
|
||||
}
|
||||
}
|
||||
munmap((void *)mapOriginal, sizeOriginal);
|
||||
close(fd);
|
||||
}
|
||||
}
|
9
script_tests/first.txt
Normal file
9
script_tests/first.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
begin aa
|
||||
pointwrite
|
||||
version 1
|
||||
addwrites
|
||||
begin aa
|
||||
end bb
|
||||
version 0
|
||||
rangeread
|
||||
check
|
Reference in New Issue
Block a user