Skip to content

Commit

Permalink
Merge pull request #783 from Expensify/master
Browse files Browse the repository at this point in the history
Update expensify_prod branch
  • Loading branch information
rafecolton authored May 4, 2020
2 parents ec46169 + c920508 commit bcc6ee9
Showing 1 changed file with 72 additions and 63 deletions.
135 changes: 72 additions & 63 deletions test/clustertest/tests/BadCommandTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,81 +2,90 @@

struct BadCommandTest : tpunit::TestFixture {
BadCommandTest()
: tpunit::TestFixture("BadCommand",
BEFORE_CLASS(BadCommandTest::setup),
AFTER_CLASS(BadCommandTest::teardown),
TEST(BadCommandTest::test)) { }

BedrockClusterTester* tester;

void setup() {
tester = new BedrockClusterTester();
}

void teardown() {
delete tester;
}
: tpunit::TestFixture("BadCommand", TEST(BadCommandTest::test)) { }

void test()
{
BedrockTester& leader = tester->getTester(0);
BedrockTester& follower = tester->getTester(1);
int successfulRunCount = 0;
for (int i = 0; i < 5; i++) {
try {
BedrockClusterTester tester;
BedrockTester& leader = tester.getTester(0);
BedrockTester& follower = tester.getTester(1);

int userID = 31;
int userID = 31;

// Make sure unhandled exceptions send an error response, but don't crash the server.
SData cmd("exceptioninpeek");
cmd["userID"] = to_string(userID++);
try {
leader.executeWaitVerifyContent(cmd, "500 Unhandled Exception");
} catch (...) {
cout << "[BadCommandTest] failing in first block." << endl;
throw;
}
// Make sure unhandled exceptions send an error response, but don't crash the server.
SData cmd("exceptioninpeek");
cmd["userID"] = to_string(userID++);
try {
leader.executeWaitVerifyContent(cmd, "500 Unhandled Exception");
} catch (...) {
cout << "[BadCommandTest] failing in first block." << endl;
throw;
}

// Same in process.
cmd = SData("exceptioninprocess");
cmd["userID"] = to_string(userID++);
try {
leader.executeWaitVerifyContent(cmd, "500 Unhandled Exception");
} catch (...) {
cout << "[BadCommandTest] failing in second block." << endl;
throw;
}
// Same in process.
cmd = SData("exceptioninprocess");
cmd["userID"] = to_string(userID++);
try {
leader.executeWaitVerifyContent(cmd, "500 Unhandled Exception");
} catch (...) {
cout << "[BadCommandTest] failing in second block." << endl;
throw;
}

// Then for three other commands, verify they kill the leader, but the follower then refuses the same command.
// This tests cases where keeping leader alive isn't feasible.
for (auto commandName : {"generatesegfaultpeek", "generateassertpeek", "generatesegfaultprocess"}) {

// Create the command with the current userID.
userID++;
SData command(commandName);
command.methodLine = commandName;
command["userID"] = to_string(userID);
int error = 0;
leader.executeWaitMultipleData({command}, 1, false, true, &error);
// Then for three other commands, verify they kill the leader, but the follower then refuses the same command.
// This tests cases where keeping leader alive isn't feasible.
bool testFailed = false;
for (auto commandName : {"generatesegfaultpeek", "generateassertpeek", "generatesegfaultprocess"}) {

// Create the command with the current userID.
userID++;
SData command(commandName);
command.methodLine = commandName;
command["userID"] = to_string(userID);
int error = 0;
leader.executeWaitMultipleData({command}, 1, false, true, &error);

// This error indicates we couldn't read a response after sending a command. We assume this means the
// server died. Even if it didn't and we just had a weird flaky network connection, we'll still fail this
// test if the follower doesn't refuse the same command.
ASSERT_EQUAL(error, 4);
// This error indicates we couldn't read a response after sending a command. We assume this means the
// server died. Even if it didn't and we just had a weird flaky network connection, we'll still fail this
// test if the follower doesn't refuse the same command.
if (error != 4) {
testFailed = true;
break;
}

// Now send the command to the follower and verify the command was refused.
error = 0;
vector<SData> results = follower.executeWaitMultipleData({command}, 1, false, false, &error);
if (results[0].methodLine != "500 Refused") {
cout << "[BadCommandTest] Didn't get '500 refused', got '" << results[0].methodLine << "' testing '" << commandName << "', error code was set to: " << error << endl;
ASSERT_TRUE(false);
}
// Now send the command to the follower and verify the command was refused.
error = 0;
vector<SData> results = follower.executeWaitMultipleData({command}, 1, false, false, &error);
if (results[0].methodLine != "500 Refused") {
cout << "[BadCommandTest] Didn't get '500 refused', got '" << results[0].methodLine << "' testing '" << commandName << "', error code was set to: " << error << endl;
testFailed = true;
break;
}

// TODO: This is where we could send the command with a different userID to the follower and verify it's not
// refused. We don't currently do this because these commands will kill the follower. We could handle that as
// the expected case as well, though.
// TODO: This is where we could send the command with a different userID to the follower and verify it's not
// refused. We don't currently do this because these commands will kill the follower. We could handle that as
// the expected case as well, though.

// Bring leader back up.
leader.startServer();
ASSERT_TRUE(leader.waitForState("LEADING"));
// Bring leader back up.
leader.startServer();
if (!leader.waitForState("LEADING")) {
testFailed = true;
break;
}
}

// If we made it to the end of the test, increment our successfulRunCount count.
if (!testFailed) {
successfulRunCount++;
}
} catch (...) {
cout << "Caught exception running test." << endl;
}
}
ASSERT_GREATER_THAN_EQUAL(successfulRunCount, 3);
}

} __BadCommandTest;

0 comments on commit bcc6ee9

Please sign in to comment.