- Add modern CLI interface built with Zig for performance - Include TUI (Terminal User Interface) with bubbletea-like features - Implement ML experiment commands (run, status, manage) - Add configuration management and validation - Include shell completion scripts for bash and zsh - Add comprehensive CLI testing framework - Support for multiple ML frameworks and project types CLI provides fast, efficient interface for ML experiment management with modern terminal UI and comprehensive feature set.
116 lines
4.6 KiB
Zig
116 lines
4.6 KiB
Zig
const std = @import("std");
|
|
const testing = std.testing;
|
|
const protocol = @import("src/net/protocol.zig");
|
|
|
|
test "ResponsePacket serialization - success" {
|
|
const timestamp = 1701234567;
|
|
const message = "Operation completed successfully";
|
|
|
|
var packet = protocol.ResponsePacket.initSuccess(timestamp, message);
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const allocator = gpa.allocator();
|
|
|
|
const serialized = try packet.serialize(allocator);
|
|
defer allocator.free(serialized);
|
|
|
|
const deserialized = try protocol.ResponsePacket.deserialize(serialized, allocator);
|
|
defer cleanupTestPacket(allocator, deserialized);
|
|
|
|
try testing.expect(deserialized.packet_type == .success);
|
|
try testing.expect(deserialized.timestamp == timestamp);
|
|
try testing.expect(std.mem.eql(u8, deserialized.success_message.?, message));
|
|
}
|
|
|
|
test "ResponsePacket serialization - error" {
|
|
const timestamp = 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";
|
|
|
|
var packet = protocol.ResponsePacket.initError(timestamp, error_code, error_message, error_details);
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const allocator = gpa.allocator();
|
|
|
|
const serialized = try packet.serialize(allocator);
|
|
defer allocator.free(serialized);
|
|
|
|
const deserialized = try protocol.ResponsePacket.deserialize(serialized, allocator);
|
|
defer cleanupTestPacket(allocator, deserialized);
|
|
|
|
try testing.expect(deserialized.packet_type == .error_packet);
|
|
try testing.expect(deserialized.timestamp == timestamp);
|
|
try testing.expect(deserialized.error_code.? == error_code);
|
|
try testing.expect(std.mem.eql(u8, deserialized.error_message.?, error_message));
|
|
try testing.expect(std.mem.eql(u8, deserialized.error_details.?, error_details));
|
|
}
|
|
|
|
test "ResponsePacket serialization - progress" {
|
|
const timestamp = 1701234567;
|
|
const progress_type = protocol.ProgressType.percentage;
|
|
const progress_value = 75;
|
|
const progress_total = 100;
|
|
const progress_message = "Processing files...";
|
|
|
|
var 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 serialized = try packet.serialize(allocator);
|
|
defer allocator.free(serialized);
|
|
|
|
const deserialized = try protocol.ResponsePacket.deserialize(serialized, allocator);
|
|
defer cleanupTestPacket(allocator, deserialized);
|
|
|
|
try testing.expect(deserialized.packet_type == .progress);
|
|
try testing.expect(deserialized.timestamp == timestamp);
|
|
try testing.expect(deserialized.progress_type.? == progress_type);
|
|
try testing.expect(deserialized.progress_value.? == progress_value);
|
|
try testing.expect(deserialized.progress_total.? == progress_total);
|
|
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);
|
|
}
|
|
}
|