diff --git a/tests/test_all.nim b/tests/test_all.nim index 9ba1c35..833b4f6 100644 --- a/tests/test_all.nim +++ b/tests/test_all.nim @@ -55,184 +55,6 @@ import barabadb/protocol/scram import barabadb/protocol/ratelimit import barabadb/schema/schema as schema -suite "Cypher-like Graph Queries": - test "Parse MATCH query": - let query = "MATCH (p:Person {name: 'Alice'}) RETURN p" - let cypher = parseCypher(query) - check cypher.kind == "MATCH" - check cypher.pattern.nodes.len == 1 - check cypher.pattern.nodes[0].label == "Person" - check cypher.returnExprs.len == 1 - - test "Parse MATCH with edge": - let query = "MATCH (a:Person)-[r:KNOWS]->(b:Person) RETURN a, b" - let cypher = parseCypher(query) - check cypher.pattern.nodes.len == 2 - check cypher.pattern.edges.len == 1 - check cypher.pattern.edges[0].label == "KNOWS" - - test "Parse MATCH with WHERE and LIMIT": - let query = "MATCH (p:Person) WHERE p.age > 18 RETURN p.name, p.age ORDER BY p.age LIMIT 10" - let cypher = parseCypher(query) - check cypher.whereClause.len > 0 - check cypher.returnExprs.len == 2 - check cypher.orderBy.len > 0 - check cypher.limit == 10 - - test "Execute basic MATCH": - var g = newGraph() - discard g.addNode("Person", {"name": "Alice"}.toTable) - discard g.addNode("Person", {"name": "Bob"}.toTable) - discard g.addNode("Company", {"name": "Acme"}.toTable) - - let query = parseCypher("MATCH (p:Person) RETURN p") - let result = executeCypher(g, query) - check result.rows.len == 2 - - test "Match nodes with properties": - var g = newGraph() - discard g.addNode("Person", {"name": "Alice", "age": "30"}.toTable) - discard g.addNode("Person", {"name": "Bob", "age": "25"}.toTable) - - let matches = matchNodes(g, "Person", {"name": "Alice"}.toTable) - check matches.len == 1 - check matches[0].properties["name"] == "Alice" - -suite "Crash Recovery": - test "Scan WAL file": - var walDir = "/tmp/baradb_test_recovery_wal" - var wal = newWriteAheadLog(walDir) - wal.writePut(@[1'u8], @[2'u8], 1) - wal.sync() - wal.close() - - var rec = newCrashRecovery(walDir, "/tmp") - let entries = rec.scanWAL() - check entries.len >= 1 # at least the put entry - - test "Analyze recovery": - var walDir = "/tmp/baradb_test_recovery_wal2" - var wal = newWriteAheadLog(walDir) - wal.writePut(@[1'u8], @[2'u8], 1) - wal.writeCommit(1) - wal.close() - - var rec = newCrashRecovery(walDir, "/tmp") - let result = rec.analyze() - check result.totalEntries >= 1 - check result.applied == true - - test "Recover returns summary": - var walDir = "/tmp/baradb_test_recovery_wal3" - var wal = newWriteAheadLog(walDir) - wal.writePut(@[1'u8], @[2'u8], 1) - wal.writeCommit(1) - wal.close() - - var rec = newCrashRecovery(walDir, "/tmp") - let summary = rec.summary() - check "WAL Recovery" in summary - check "Total" in summary - -suite "Raft Election Timer": - test "Election timer tick": - var cluster = newRaftCluster() - cluster.addNode("n1") - cluster.addNode("n2") - cluster.addNode("n3") - - let n1 = cluster.nodes["n1"] - var timer = newElectionTimer(n1, timeoutMs = 0) # immediate timeout - - # Force election - n1.becomeCandidate() - n1.becomeLeader() - timer.tick() - check n1.isLeader - - test "Timer reset": - var cluster = newRaftCluster() - cluster.addNode("n1") - let n1 = cluster.nodes["n1"] - var timer = newElectionTimer(n1, timeoutMs = 1000) - timer.resetTimeout() - check not timer.checkTimeout() - - test "Multi-node election with timer": - var cluster = newRaftCluster() - cluster.addNode("n1") - cluster.addNode("n2") - - let n2 = cluster.nodes["n2"] - var timer2 = newElectionTimer(n2, timeoutMs = 0) - n2.becomeCandidate() - let req = n2.requestVote() - check req.len == 1 # n2 requests vote from n1 - let reply = cluster.nodes["n1"].handleRequestVote(req[0]) - check reply.success - -suite "Raft Network Transport": - test "3-node election over TCP": - var n1 = newRaftNode("n1", @["n2", "n3"], raftPort = 19001) - var n2 = newRaftNode("n2", @["n1", "n3"], raftPort = 19002) - var n3 = newRaftNode("n3", @["n1", "n2"], raftPort = 19003) - - n1.peerAddrs["n2"] = ("127.0.0.1", 19002) - n1.peerAddrs["n3"] = ("127.0.0.1", 19003) - n2.peerAddrs["n1"] = ("127.0.0.1", 19001) - n2.peerAddrs["n3"] = ("127.0.0.1", 19003) - n3.peerAddrs["n1"] = ("127.0.0.1", 19001) - n3.peerAddrs["n2"] = ("127.0.0.1", 19002) - - let net1 = newRaftNetwork(n1) - let net2 = newRaftNetwork(n2) - let net3 = newRaftNetwork(n3) - - asyncCheck net1.run() - asyncCheck net2.run() - asyncCheck net3.run() - waitFor sleepAsync(50) - - var timer1 = newElectionTimer(n1, timeoutMs = 50) - var timer2 = newElectionTimer(n2, timeoutMs = 100) - var timer3 = newElectionTimer(n3, timeoutMs = 150) - - for i in 0 ..< 30: - timer1.tick(net1) - timer2.tick(net2) - timer3.tick(net3) - waitFor sleepAsync(20) - - net1.stop() - net2.stop() - net3.stop() - waitFor sleepAsync(50) - - var leaderCount = 0 - if n1.isLeader: inc leaderCount - if n2.isLeader: inc leaderCount - if n3.isLeader: inc leaderCount - check leaderCount == 1 - -suite "CLI Autocomplete": - test "Autocomplete commands": - let res = autocomplete("he") - check "help" in res - - test "Autocomplete keywords": - let res = autocomplete("SEL") - check "SELECT" in res - let res2 = autocomplete("SELECT FRO") - check "FROM" in res2 - - test "Suggest returns completions": - let suggestion = suggest("SE") - check suggestion.len > 0 - - test "Autocomplete empty": - let res = autocomplete("") - check res.len == 0 - suite "TLS/SSL": test "Create TLS config": let config = newTLSConfig("cert.pem", "key.pem", "ca.pem", verifyPeer = true)