Skip to content

Commit

Permalink
Convert e2e_exception_test to end to end test #1584
Browse files Browse the repository at this point in the history
* Adds support for -BEGIN_WRITE_TRANSACTION within the test file
* Splits exception.test into multiple files
* Raises an exception if the test file is invalid
* Deletes e2e_exception_test.cpp file
* Add TestException and improve error messages
  • Loading branch information
rfdavid committed May 30, 2023
1 parent bac02bf commit 5fc4f24
Show file tree
Hide file tree
Showing 16 changed files with 285 additions and 270 deletions.
5 changes: 5 additions & 0 deletions src/include/common/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,10 @@ class InterruptException : public Exception {
explicit InterruptException() : Exception("Interrupted."){};
};

class TestException : public Exception {
public:
explicit TestException(const std::string& msg) : Exception("Test exception: " + msg){};
};

} // namespace common
} // namespace kuzu
1 change: 1 addition & 0 deletions test/include/test_runner/test_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct TestStatement {
std::string errorMessage;
bool enumerate = false;
bool checkOutputOrder = false;
bool isBeginWriteTransaction = false;
};

// Test group is a collection of test cases in a single file.
Expand Down
23 changes: 17 additions & 6 deletions test/include/test_runner/test_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum class TokenType {
GROUP,
DATASET,
TEST,
BEGIN_WRITE_TRANSACTION,
BUFFER_POOL_SIZE,
CASE,
CHECK_ORDER,
Expand All @@ -34,6 +35,7 @@ const std::unordered_map<std::string, TokenType> tokenMap = {{"-GROUP", TokenTyp
{"-CHECK_ORDER", TokenType::CHECK_ORDER}, {"-ENCODED_JOIN", TokenType::ENCODED_JOIN},
{"-DEFINE_STATEMENT_BLOCK", TokenType::DEFINE_STATEMENT_BLOCK},
{"-ENUMERATE", TokenType::ENUMERATE}, {"-NAME", TokenType::NAME},
{"-BEGIN_WRITE_TRANSACTION", TokenType::BEGIN_WRITE_TRANSACTION},
{"-PARALLELISM", TokenType::PARALLELISM}, {"-QUERY", TokenType::QUERY},
{"-READ_ONLY", TokenType::READ_ONLY}, {"-SKIP", TokenType::SKIP},
{"-STATEMENT", TokenType::STATEMENT}, {"-STATEMENT_BLOCK", TokenType::STATEMENT_BLOCK},
Expand All @@ -51,18 +53,21 @@ class LogicToken {

class TestParser {
public:
TestParser() : testGroup(std::make_unique<TestGroup>()) {}
std::unique_ptr<TestGroup> parseTestFile(const std::string& path);
explicit TestParser(const std::string& path)
: testGroup{std::make_unique<TestGroup>()}, path{path} {}
std::unique_ptr<TestGroup> parseTestFile();

private:
std::string path;
std::ifstream fileStream;
std::streampos previousFilePosition;
std::string line;
std::string name;
std::unique_ptr<TestGroup> testGroup;
std::string paramsToString();
std::string extractTextBeforeNextStatement();
LogicToken currentToken;
void openFile(const std::string& path);
void openFile();
void tokenize();
void parseHeader();
void parseBody();
Expand All @@ -71,10 +76,16 @@ class TestParser {
void addStatementBlock(const std::string& blockName, const std::string& testGroupName);
void replaceVariables(std::string& str);
inline bool endOfFile() { return fileStream.eof(); }
inline bool nextLine() { return static_cast<bool>(getline(fileStream, line)); }
inline void setCursorToPreviousLine() { fileStream.seekg(previousFilePosition); }
inline bool nextLine() {
previousFilePosition = fileStream.tellg();
return static_cast<bool>(getline(fileStream, line));
}
inline void checkMinimumParams(int minimumParams) {
if (currentToken.params.size() < minimumParams) {
throw common::Exception("Invalid number of parameters for statement [" + line + "]");
if (currentToken.params.size() - 1 < minimumParams) {
throw common::TestException("Minimum number of parameters is " +
std::to_string(minimumParams) + ". [" + path + ":" + line +
"]");
}
}
TestStatement* extractStatement(TestStatement* currentStatement);
Expand Down
1 change: 0 additions & 1 deletion test/runner/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
add_kuzu_test(e2e_copy_csv_transaction_test e2e_copy_transaction_test.cpp)
add_kuzu_test(e2e_ddl_test e2e_ddl_test.cpp)
add_kuzu_test(e2e_delete_create_transaction_test e2e_delete_create_transaction_test.cpp)
add_kuzu_test(e2e_exception_test e2e_exception_test.cpp)
add_kuzu_test(e2e_read_test e2e_read_test.cpp)
add_kuzu_test(e2e_set_transaction_test e2e_set_transaction_test.cpp)
add_kuzu_test(e2e_update_node_test e2e_update_node_test.cpp)
Expand Down
243 changes: 0 additions & 243 deletions test/runner/e2e_exception_test.cpp

This file was deleted.

8 changes: 5 additions & 3 deletions test/runner/e2e_read_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class EndToEndReadTest : public DBTest {
};

void parseAndRegisterTestGroup(const std::string& path) {
auto testParser = std::make_unique<TestParser>();
auto testGroup = std::move(testParser->parseTestFile(path));
auto testParser = std::make_unique<TestParser>(path);
auto testGroup = std::move(testParser->parseTestFile());
if (testGroup->isValid() && testGroup->hasStatements()) {
auto dataset = testGroup->dataset;
auto testCases = std::move(testGroup->testCases);
Expand All @@ -45,6 +45,8 @@ void parseAndRegisterTestGroup(const std::string& path) {
return new EndToEndReadTest(dataset, bufferPoolSize, std::move(testStatements));
});
}
} else {
throw TestException("Invalid test file [" + path + "].");
}
}

Expand All @@ -68,7 +70,7 @@ int main(int argc, char** argv) {
}
path = TestHelper::appendKuzuRootPath(path);
if (!FileUtils::fileOrPathExists(path)) {
throw Exception("Test directory not exists! [" + path + "].");
throw TestException("Test path not exists [" + path + "].");
}
scanTestFiles(path);
return RUN_ALL_TESTS();
Expand Down
34 changes: 34 additions & 0 deletions test/test_files/tinysnb/exception/exception.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
-GROUP TinySnbExceptionTest
-DATASET tinysnb

--

-CASE DivideBy0Error
-QUERY RETURN 1 / 0
---- error
Runtime exception: Divide by zero.

-CASE ModuloBy0Error
-QUERY RETURN 1 % 0
---- error
Runtime exception: Modulo by zero.

-CASE EmptyQuery
-QUERY
---- error
Connection Exception: Query is empty.

-CASE ReadAfterUpdate2
-QUERY MATCH (a:person) WHERE a.age = 35 DELETE a WITH a MATCH (a)-[:knows]->(b:person) RETURN a.age
---- error
Binder exception: Read after update is not supported.

-CASE Overflow
-QUERY RETURN to_int16(10000000000)
---- error
Runtime exception: Cast failed. 10000000000 is not in INT16 range.

-CASE Int32PrimaryKey
-STATEMENT CREATE NODE TABLE play(a INT32, PRIMARY KEY (a))
---- error
Binder exception: Invalid primary key type: INT32. Expected STRING or INT64.
Loading

0 comments on commit 5fc4f24

Please sign in to comment.