## Wire Protocol Fuzz Tests import std/unittest import std/random import std/strutils import barabadb/protocol/wire suite "Wire Protocol Fuzz": # ────────────────────────────────────────────────── # Core robustness # ────────────────────────────────────────────────── test "deserializeValue survives random bytes": var rng = initRand(12345) for i in 0..<500: var buf = newSeq[byte](rng.rand(1..256)) for b in buf.mitems: b = byte(rng.rand(0..255)) var pos = 0 try: discard deserializeValue(buf, pos) except: discard # Exceptions are expected for garbage input test "deserializeValue survives truncated buffers": var rng = initRand(12346) for i in 0..<200: var buf: seq[byte] = @[byte(rng.rand(0..12))] let extra = rng.rand(0..64) for j in 0..= 12 test "serializeMessage roundtrip with random payloads": var rng = initRand(12350) for i in 0..<100: let reqId = uint32(rng.rand(int64(high(uint32)))) var msg = WireMessage( header: MessageHeader(kind: mkQuery, length: uint32(rng.rand(0..1000)), requestId: reqId), payload: newSeq[byte](rng.rand(0..200)) ) for j in 0..= 12 test "serializeMessage with max payload length": var rng = initRand(5004) for i in 0..<50: let reqId = uint32(rng.rand(int64(high(uint32)))) let payloadLen = rng.rand(0..4096) var msg = WireMessage( header: MessageHeader(kind: mkQuery, length: uint32(payloadLen), requestId: reqId), payload: newSeq[byte](payloadLen) ) for j in 0.. 0 test "makeErrorMessage with long error string": var rng = initRand(5005) for i in 0..<50: let reqId = uint32(rng.rand(int64(high(uint32)))) var errStr = "" let errLen = rng.rand(0..1000) for j in 0..= 12 + errStr.len # ────────────────────────────────────────────────── # SerializeValue roundtrip for all field kinds # ────────────────────────────────────────────────── test "serializeValue/deserializeValue roundtrip — fkNull": var buf: seq[byte] = @[] var val = WireValue(kind: fkNull) serializeValue(buf, val) var pos = 0 let back = deserializeValue(buf, pos) check back.kind == fkNull test "serializeValue/deserializeValue roundtrip — fkBool": var rng = initRand(5006) for i in 0..<100: var buf: seq[byte] = @[] let bv = rng.rand(0..1) == 1 var val = WireValue(kind: fkBool, boolVal: bv) serializeValue(buf, val) var pos = 0 let back = deserializeValue(buf, pos) check back.kind == fkBool check back.boolVal == bv test "serializeValue/deserializeValue roundtrip — fkInt64": var rng = initRand(5007) for i in 0..<100: var buf: seq[byte] = @[] let iv = int64(rng.rand(int64.low..int64.high)) var val = WireValue(kind: fkInt64, int64Val: iv) serializeValue(buf, val) var pos = 0 let back = deserializeValue(buf, pos) check back.kind == fkInt64 check back.int64Val == iv test "serializeValue/deserializeValue roundtrip — fkFloat64": var rng = initRand(5008) for i in 0..<100: var buf: seq[byte] = @[] let fv = float64(rng.rand(-1000.0..1000.0)) var val = WireValue(kind: fkFloat64, float64Val: fv) serializeValue(buf, val) var pos = 0 let back = deserializeValue(buf, pos) check back.kind == fkFloat64 check back.float64Val == fv test "serializeValue/deserializeValue roundtrip — fkString": var rng = initRand(5009) for i in 0..<100: var buf: seq[byte] = @[] var s = "" let sl = rng.rand(0..200) for j in 0.. 0: let idx = rng.rand(0..buf.len-1) buf[idx] = byte(rng.rand(0..255)) var pos = 0 try: discard deserializeValue(buf, pos) except: discard test "Mutated serialized messages parse without crash": var rng = initRand(5018) for i in 0..<200: let header = MessageHeader(kind: mkQuery, length: 10, requestId: uint32(i)) var payload = newSeq[byte](10) for j in 0..<10: payload[j] = byte(rng.rand(0..255)) var msg = WireMessage(header: header, payload: payload) var s = serializeMessage(msg) for mutation in 0..<3: if s.len > 0: s[rng.rand(0..s.len-1)] = byte(rng.rand(0..255)) check s.len >= 12 test "makeQueryMessage with empty query": let msg = makeQueryMessage(1, "") check msg.len >= 12 test "makeQueryMessage with special characters": var rng = initRand(5019) for i in 0..<50: var query = "" let sl = rng.rand(0..100) for j in 0..= 12 # ────────────────────────────────────────────────── # makeCompleteMessage # ────────────────────────────────────────────────── test "makeCompleteMessage with random affected rows": var rng = initRand(5020) for i in 0..<50: let affectedRows = rng.rand(0..100_000) let msg = makeCompleteMessage(uint32(i), affectedRows) check msg.len >= 12 # ────────────────────────────────────────────────── # makeAuthOkMessage # ────────────────────────────────────────────────── test "makeAuthOkMessage produces valid message": let msg = makeAuthOkMessage(42) check msg.len == 12 # ────────────────────────────────────────────────── # makeAuthChallengeMessage # ────────────────────────────────────────────────── test "makeAuthChallengeMessage with random challenges": var rng = initRand(5021) for i in 0..<50: var challenge = "" let cl = rng.rand(0..100) for j in 0..= 12 # ────────────────────────────────────────────────── # Stress: many iterations # ────────────────────────────────────────────────── test "Stress: 2000 random deserializeValue calls": var rng = initRand(5022) for i in 0..<2000: var buf = newSeq[byte](rng.rand(1..128)) for b in buf.mitems: b = byte(rng.rand(0..255)) var pos = 0 try: discard deserializeValue(buf, pos) except: discard test "Stress: 1000 serializeMessage with random content": var rng = initRand(5023) for i in 0..<1000: let kind = cast[MsgKind](uint32(rng.rand(1..0xFF))) let payloadLen = rng.rand(0..256) var payload = newSeq[byte](payloadLen) for j in 0..