132 lines
5.9 KiB
Zig
132 lines
5.9 KiB
Zig
const std = @import("std");
|
|
const testing = std.testing;
|
|
|
|
const src = @import("src");
|
|
|
|
const protocol = src.net.protocol;
|
|
|
|
fn roundTrip(allocator: std.mem.Allocator, packet: protocol.ResponsePacket) !protocol.ResponsePacket {
|
|
const serialized = try packet.serialize(allocator);
|
|
defer allocator.free(serialized);
|
|
return try protocol.ResponsePacket.deserialize(serialized, allocator);
|
|
}
|
|
|
|
test "ResponsePacket serialization - success" {
|
|
const timestamp: u64 = 1701234567;
|
|
const message = "Operation completed successfully";
|
|
|
|
const packet = protocol.ResponsePacket.initSuccess(timestamp, message);
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const allocator = gpa.allocator();
|
|
|
|
const deserialized = try roundTrip(allocator, packet);
|
|
defer cleanupTestPacket(allocator, deserialized);
|
|
|
|
try testing.expectEqual(protocol.PacketType.success, deserialized.packet_type);
|
|
try testing.expectEqual(timestamp, deserialized.timestamp);
|
|
try testing.expect(deserialized.success_message != null);
|
|
try testing.expect(std.mem.eql(u8, deserialized.success_message.?, message));
|
|
}
|
|
|
|
test "ResponsePacket deserialize rejects too-short packets" {
|
|
const allocator = testing.allocator;
|
|
|
|
// Must be at least 1 byte packet_type + 8 bytes timestamp.
|
|
try testing.expectError(error.InvalidPacket, protocol.ResponsePacket.deserialize(&[_]u8{}, allocator));
|
|
try testing.expectError(error.InvalidPacket, protocol.ResponsePacket.deserialize(&[_]u8{0x00}, allocator));
|
|
|
|
var buf: [8]u8 = undefined;
|
|
@memset(&buf, 0);
|
|
try testing.expectError(error.InvalidPacket, protocol.ResponsePacket.deserialize(&buf, allocator));
|
|
}
|
|
|
|
test "ResponsePacket deserialize rejects truncated progress packet" {
|
|
const allocator = testing.allocator;
|
|
|
|
// packet_type + timestamp is present, but missing the progress fields.
|
|
var buf = std.ArrayList(u8).initCapacity(allocator, 16) catch unreachable;
|
|
defer buf.deinit(allocator);
|
|
|
|
try buf.append(allocator, @intFromEnum(protocol.PacketType.progress));
|
|
var ts: [8]u8 = undefined;
|
|
std.mem.writeInt(u64, ts[0..8], 1, .big);
|
|
try buf.appendSlice(allocator, &ts);
|
|
|
|
try testing.expectError(error.InvalidPacket, protocol.ResponsePacket.deserialize(buf.items, allocator));
|
|
}
|
|
|
|
test "ResponsePacket serialization - error" {
|
|
const timestamp: u64 = 1701234567;
|
|
const error_code = protocol.ErrorCode.job_not_found;
|
|
const error_message = "Job not found";
|
|
const error_details = "The specified job ID does not exist";
|
|
|
|
const packet = protocol.ResponsePacket.initError(timestamp, error_code, error_message, error_details);
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const allocator = gpa.allocator();
|
|
|
|
const deserialized = try roundTrip(allocator, packet);
|
|
defer cleanupTestPacket(allocator, deserialized);
|
|
|
|
try testing.expectEqual(protocol.PacketType.error_packet, deserialized.packet_type);
|
|
try testing.expectEqual(timestamp, deserialized.timestamp);
|
|
try testing.expect(deserialized.error_code != null);
|
|
try testing.expectEqual(error_code, deserialized.error_code.?);
|
|
try testing.expect(std.mem.eql(u8, deserialized.error_message.?, error_message));
|
|
try testing.expect(deserialized.error_details != null);
|
|
try testing.expect(std.mem.eql(u8, deserialized.error_details.?, error_details));
|
|
}
|
|
|
|
test "ResponsePacket serialization - progress" {
|
|
const timestamp: u64 = 1701234567;
|
|
const progress_type = protocol.ProgressType.percentage;
|
|
const progress_value: u32 = 75;
|
|
const progress_total: u32 = 100;
|
|
const progress_message = "Processing files...";
|
|
|
|
const packet = protocol.ResponsePacket.initProgress(timestamp, progress_type, progress_value, progress_total, progress_message);
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const allocator = gpa.allocator();
|
|
|
|
const deserialized = try roundTrip(allocator, packet);
|
|
defer cleanupTestPacket(allocator, deserialized);
|
|
|
|
try testing.expectEqual(protocol.PacketType.progress, deserialized.packet_type);
|
|
try testing.expectEqual(timestamp, deserialized.timestamp);
|
|
try testing.expectEqual(progress_type, deserialized.progress_type.?);
|
|
try testing.expectEqual(progress_value, deserialized.progress_value.?);
|
|
try testing.expect(deserialized.progress_total != null);
|
|
try testing.expectEqual(progress_total, deserialized.progress_total.?);
|
|
try testing.expect(deserialized.progress_message != null);
|
|
try testing.expect(std.mem.eql(u8, deserialized.progress_message.?, progress_message));
|
|
}
|
|
|
|
test "Error message mapping" {
|
|
try testing.expect(std.mem.eql(u8, protocol.ResponsePacket.getErrorMessage(.job_not_found), "Job not found"));
|
|
try testing.expect(std.mem.eql(u8, protocol.ResponsePacket.getErrorMessage(.authentication_failed), "Authentication failed"));
|
|
try testing.expect(std.mem.eql(u8, protocol.ResponsePacket.getErrorMessage(.server_overloaded), "Server is overloaded"));
|
|
}
|
|
|
|
test "Log level names" {
|
|
try testing.expect(std.mem.eql(u8, protocol.ResponsePacket.getLogLevelName(0), "DEBUG"));
|
|
try testing.expect(std.mem.eql(u8, protocol.ResponsePacket.getLogLevelName(1), "INFO"));
|
|
try testing.expect(std.mem.eql(u8, protocol.ResponsePacket.getLogLevelName(2), "WARN"));
|
|
try testing.expect(std.mem.eql(u8, protocol.ResponsePacket.getLogLevelName(3), "ERROR"));
|
|
}
|
|
|
|
fn cleanupTestPacket(allocator: std.mem.Allocator, packet: protocol.ResponsePacket) void {
|
|
if (packet.success_message) |msg| allocator.free(msg);
|
|
if (packet.error_message) |msg| allocator.free(msg);
|
|
if (packet.error_details) |details| allocator.free(details);
|
|
if (packet.progress_message) |msg| allocator.free(msg);
|
|
if (packet.status_data) |data| allocator.free(data);
|
|
if (packet.data_type) |dtype| allocator.free(dtype);
|
|
if (packet.data_payload) |payload| allocator.free(payload);
|
|
if (packet.log_message) |msg| allocator.free(msg);
|
|
}
|