You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-05 16:15:50 +03:00
Started writing unit tests to verify SM does the right thing
when given short data (sender crashed).
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "SMLogging.h"
|
#include "SMLogging.h"
|
||||||
|
|
||||||
|
namespace bf = boost::filesystem;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -53,6 +54,17 @@ Config * Config::get()
|
|||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Config * Config::get(const string &configFile)
|
||||||
|
{
|
||||||
|
if (inst)
|
||||||
|
return inst;
|
||||||
|
boost::mutex::scoped_lock s(m);
|
||||||
|
if (inst)
|
||||||
|
return inst;
|
||||||
|
inst = new Config(configFile);
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
Config::Config() : die(false)
|
Config::Config() : die(false)
|
||||||
{
|
{
|
||||||
/* This will search the current directory,
|
/* This will search the current directory,
|
||||||
@@ -91,6 +103,17 @@ Config::Config() : die(false)
|
|||||||
reloader = boost::thread([this] { this->reloadThreadFcn(); });
|
reloader = boost::thread([this] { this->reloadThreadFcn(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Config::Config(const string &configFile) : filename(configFile), die(false)
|
||||||
|
{
|
||||||
|
if (!bf::is_regular_file(configFile))
|
||||||
|
throw runtime_error("Config: Could not find the config file for StorageManager");
|
||||||
|
|
||||||
|
reloadInterval = boost::posix_time::seconds(60);
|
||||||
|
last_mtime = {0, 0};
|
||||||
|
reload();
|
||||||
|
reloader = boost::thread([this] { this->reloadThreadFcn(); });
|
||||||
|
}
|
||||||
|
|
||||||
Config::~Config()
|
Config::~Config()
|
||||||
{
|
{
|
||||||
die = true;
|
die = true;
|
||||||
|
@@ -37,8 +37,12 @@ class Config : public boost::noncopyable
|
|||||||
|
|
||||||
std::string getValue(const std::string §ion, const std::string &key) const;
|
std::string getValue(const std::string §ion, const std::string &key) const;
|
||||||
|
|
||||||
|
// for testing, lets caller specify a config file to use
|
||||||
|
static Config *get(const std::string &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config();
|
Config();
|
||||||
|
Config(const std::string &);
|
||||||
|
|
||||||
void reload();
|
void reload();
|
||||||
void reloadThreadFcn();
|
void reloadThreadFcn();
|
||||||
|
@@ -116,7 +116,7 @@ bool ListDirectoryTask::run()
|
|||||||
|
|
||||||
sm_response *resp = (sm_response *) buf;
|
sm_response *resp = (sm_response *) buf;
|
||||||
resp->header.type = SM_MSG_START;
|
resp->header.type = SM_MSG_START;
|
||||||
resp->header.payloadLen = payloadLen + sizeof(sm_response) - sizeof(sm_msg_header); // the +4 is for the length of the return code
|
resp->header.payloadLen = payloadLen + sizeof(sm_response) - sizeof(sm_msg_header);
|
||||||
resp->header.flags = 0;
|
resp->header.flags = 0;
|
||||||
resp->returnCode = 0;
|
resp->returnCode = 0;
|
||||||
listdir_resp *r = (listdir_resp *) resp->payload;
|
listdir_resp *r = (listdir_resp *) resp->payload;
|
||||||
|
@@ -1582,6 +1582,68 @@ void bigMergeJournal1()
|
|||||||
assert(buf);
|
assert(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This should write an incomplete msg(s) to make sure SM does the right thing. Not
|
||||||
|
// done yet, handing this off to Ben.
|
||||||
|
void shortWriteMsg()
|
||||||
|
{
|
||||||
|
// copy/modified/pasted from writetask().
|
||||||
|
bf::path fullPath = homepath / prefix / "writetest1";
|
||||||
|
const char *filename = fullPath.string().c_str();
|
||||||
|
::unlink(filename);
|
||||||
|
int fd = ::open(filename, O_CREAT | O_RDWR, 0666);
|
||||||
|
assert(fd > 0);
|
||||||
|
scoped_closer f(fd);
|
||||||
|
|
||||||
|
uint8_t buf[1024];
|
||||||
|
sm_msg_header *hdr = (sm_msg_header *) buf;
|
||||||
|
write_cmd *cmd = (write_cmd *) &hdr[1];
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
cmd->opcode = WRITE;
|
||||||
|
cmd->offset = 0;
|
||||||
|
cmd->count = 9;
|
||||||
|
cmd->flen = 10;
|
||||||
|
memcpy(&cmd->filename, filename, cmd->flen);
|
||||||
|
data = (uint8_t *) &cmd->filename[cmd->flen];
|
||||||
|
memcpy(data, "123456789", cmd->count);
|
||||||
|
|
||||||
|
hdr->type = SM_MSG_START;
|
||||||
|
hdr->payloadLen = sizeof(*cmd) + cmd->flen + cmd->count;
|
||||||
|
|
||||||
|
WriteTask w(clientSock, hdr->payloadLen);
|
||||||
|
ssize_t result = ::write(sessionSock, cmd, hdr->payloadLen);
|
||||||
|
assert(result==(hdr->payloadLen));
|
||||||
|
|
||||||
|
w.run();
|
||||||
|
|
||||||
|
// verify response
|
||||||
|
int err = ::recv(sessionSock, buf, 1024, MSG_DONTWAIT);
|
||||||
|
sm_response *resp = (sm_response *) buf;
|
||||||
|
assert(err == sizeof(*resp));
|
||||||
|
assert(resp->header.type == SM_MSG_START);
|
||||||
|
assert(resp->header.payloadLen == sizeof(ssize_t));
|
||||||
|
assert(resp->header.flags == 0);
|
||||||
|
assert(resp->returnCode == 9);
|
||||||
|
|
||||||
|
//check file contents
|
||||||
|
err = ::read(fd, buf, 1024);
|
||||||
|
assert(err == 9);
|
||||||
|
buf[9] = 0;
|
||||||
|
assert(!strcmp("123456789", (const char *) buf));
|
||||||
|
::unlink(filename);
|
||||||
|
cout << "write task OK" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write and append are the biggest vulnerabilities here b/c those msgs could be sent in multiple
|
||||||
|
// pieces, are much larger, and thus if there is a crash mid-message it's most likely to happen
|
||||||
|
// during a call to write/append().
|
||||||
|
// it may not even be possible for CS to write a partial open/stat/read/etc msg, but that should be
|
||||||
|
// tested as well.
|
||||||
|
void shortMsgTests()
|
||||||
|
{
|
||||||
|
shortWriteMsg();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
@@ -1612,6 +1674,18 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!bf::is_regular_file("test_data/storagemanager.cnf"))
|
||||||
|
{
|
||||||
|
cerr << "This should be run in a dir where ./test_data/storagemanager.cnf exists" << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
Config *config = Config::get("test_data/storagemanager.cnf");
|
||||||
|
cout << "Cleaning out debris from previous runs" << endl;
|
||||||
|
bf::remove_all(config->getValue("ObjectStorage", "metadata_path"));
|
||||||
|
bf::remove_all(config->getValue("ObjectStorage", "journal_path"));
|
||||||
|
bf::remove_all(config->getValue("LocalStorage", "path"));
|
||||||
|
bf::remove_all(config->getValue("Cache", "path"));
|
||||||
|
|
||||||
cout << "connecting" << endl;
|
cout << "connecting" << endl;
|
||||||
makeConnection();
|
makeConnection();
|
||||||
cout << "connected" << endl;
|
cout << "connected" << endl;
|
||||||
@@ -1639,12 +1713,11 @@ int main(int argc, char* argv[])
|
|||||||
// this starts in one object and crosses into new object
|
// this starts in one object and crosses into new object
|
||||||
metadataJournalTest_append((7*sizeKB));
|
metadataJournalTest_append((7*sizeKB));
|
||||||
|
|
||||||
|
|
||||||
//writetask();
|
//writetask();
|
||||||
//appendtask();
|
//appendtask();
|
||||||
unlinktask();
|
unlinktask();
|
||||||
stattask();
|
stattask();
|
||||||
truncatetask(); // currently waiting on IOC::write() to be completed.
|
truncatetask();
|
||||||
listdirtask();
|
listdirtask();
|
||||||
pingtask();
|
pingtask();
|
||||||
copytask();
|
copytask();
|
||||||
@@ -1655,16 +1728,26 @@ int main(int argc, char* argv[])
|
|||||||
replicatorTest();
|
replicatorTest();
|
||||||
syncTest1();
|
syncTest1();
|
||||||
|
|
||||||
s3storageTest1();
|
|
||||||
IOCReadTest1();
|
IOCReadTest1();
|
||||||
IOCTruncate();
|
IOCTruncate();
|
||||||
IOCUnlink();
|
IOCUnlink();
|
||||||
IOCCopyFile();
|
IOCCopyFile();
|
||||||
|
//shortMsgTests();
|
||||||
|
|
||||||
// For the moment, this next one just verifies no error happens as reported by the fcns called.
|
// For the moment, this next one just verifies no error happens as reported by the fcns called.
|
||||||
// It doesn't verify the result yet.
|
// It doesn't verify the result yet.
|
||||||
bigMergeJournal1();
|
bigMergeJournal1();
|
||||||
|
|
||||||
|
// skip the s3 test if s3 is not configured
|
||||||
|
if (config->getValue("S3", "region") != "")
|
||||||
|
{
|
||||||
|
s3storageTest1();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cout << "To run the S3Storage unit tests, configure the S3 section of test-data/storagemanager.cnf"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
metadataJournalTestCleanup();
|
metadataJournalTestCleanup();
|
||||||
|
|
||||||
(Cache::get())->shutdown();
|
(Cache::get())->shutdown();
|
||||||
|
Reference in New Issue
Block a user