its kind of working now
This commit is contained in:
183
tests/integration.zig
Normal file
183
tests/integration.zig
Normal file
@@ -0,0 +1,183 @@
|
||||
/// Integration tests for ZynamoDB
|
||||
const std = @import("std");
|
||||
|
||||
// Import modules from main source
|
||||
const rocksdb = @import("../src/rocksdb.zig");
|
||||
const storage = @import("../src/dynamodb/storage.zig");
|
||||
const types = @import("../src/dynamodb/types.zig");
|
||||
|
||||
test "integration: full table lifecycle" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
// Setup
|
||||
const path = "/tmp/test_integration_lifecycle";
|
||||
defer std.fs.deleteTreeAbsolute(path) catch {};
|
||||
|
||||
var engine = try storage.StorageEngine.init(allocator, path);
|
||||
defer engine.deinit();
|
||||
|
||||
// Create table
|
||||
const key_schema = [_]types.KeySchemaElement{
|
||||
.{ .attribute_name = "pk", .key_type = .HASH },
|
||||
};
|
||||
const attr_defs = [_]types.AttributeDefinition{
|
||||
.{ .attribute_name = "pk", .attribute_type = .S },
|
||||
};
|
||||
|
||||
const desc = try engine.createTable("Users", &key_schema, &attr_defs);
|
||||
try std.testing.expectEqualStrings("Users", desc.table_name);
|
||||
try std.testing.expectEqual(types.TableStatus.ACTIVE, desc.table_status);
|
||||
|
||||
// Put items
|
||||
try engine.putItem("Users", "{\"pk\":{\"S\":\"user1\"},\"name\":{\"S\":\"Alice\"}}");
|
||||
try engine.putItem("Users", "{\"pk\":{\"S\":\"user2\"},\"name\":{\"S\":\"Bob\"}}");
|
||||
try engine.putItem("Users", "{\"pk\":{\"S\":\"user3\"},\"name\":{\"S\":\"Charlie\"}}");
|
||||
|
||||
// Get item
|
||||
const item = try engine.getItem("Users", "{\"pk\":{\"S\":\"user1\"}}");
|
||||
try std.testing.expect(item != null);
|
||||
defer allocator.free(item.?);
|
||||
|
||||
// Scan
|
||||
const all_items = try engine.scan("Users", null);
|
||||
defer {
|
||||
for (all_items) |i| allocator.free(i);
|
||||
allocator.free(all_items);
|
||||
}
|
||||
try std.testing.expectEqual(@as(usize, 3), all_items.len);
|
||||
|
||||
// Delete item
|
||||
try engine.deleteItem("Users", "{\"pk\":{\"S\":\"user2\"}}");
|
||||
|
||||
// Verify deletion
|
||||
const after_delete = try engine.scan("Users", null);
|
||||
defer {
|
||||
for (after_delete) |i| allocator.free(i);
|
||||
allocator.free(after_delete);
|
||||
}
|
||||
try std.testing.expectEqual(@as(usize, 2), after_delete.len);
|
||||
|
||||
// Delete table
|
||||
try engine.deleteTable("Users");
|
||||
|
||||
// Verify table deletion
|
||||
const tables = try engine.listTables();
|
||||
defer allocator.free(tables);
|
||||
try std.testing.expectEqual(@as(usize, 0), tables.len);
|
||||
}
|
||||
|
||||
test "integration: multiple tables" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
const path = "/tmp/test_integration_multi_table";
|
||||
defer std.fs.deleteTreeAbsolute(path) catch {};
|
||||
|
||||
var engine = try storage.StorageEngine.init(allocator, path);
|
||||
defer engine.deinit();
|
||||
|
||||
const key_schema = [_]types.KeySchemaElement{
|
||||
.{ .attribute_name = "pk", .key_type = .HASH },
|
||||
};
|
||||
const attr_defs = [_]types.AttributeDefinition{
|
||||
.{ .attribute_name = "pk", .attribute_type = .S },
|
||||
};
|
||||
|
||||
// Create multiple tables
|
||||
_ = try engine.createTable("Table1", &key_schema, &attr_defs);
|
||||
_ = try engine.createTable("Table2", &key_schema, &attr_defs);
|
||||
_ = try engine.createTable("Table3", &key_schema, &attr_defs);
|
||||
|
||||
// List tables
|
||||
const tables = try engine.listTables();
|
||||
defer {
|
||||
for (tables) |t| allocator.free(t);
|
||||
allocator.free(tables);
|
||||
}
|
||||
try std.testing.expectEqual(@as(usize, 3), tables.len);
|
||||
|
||||
// Put items in different tables
|
||||
try engine.putItem("Table1", "{\"pk\":{\"S\":\"item1\"}}");
|
||||
try engine.putItem("Table2", "{\"pk\":{\"S\":\"item2\"}}");
|
||||
try engine.putItem("Table3", "{\"pk\":{\"S\":\"item3\"}}");
|
||||
|
||||
// Verify isolation - scan should only return items from that table
|
||||
const table1_items = try engine.scan("Table1", null);
|
||||
defer {
|
||||
for (table1_items) |i| allocator.free(i);
|
||||
allocator.free(table1_items);
|
||||
}
|
||||
try std.testing.expectEqual(@as(usize, 1), table1_items.len);
|
||||
}
|
||||
|
||||
test "integration: table already exists error" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
const path = "/tmp/test_integration_exists";
|
||||
defer std.fs.deleteTreeAbsolute(path) catch {};
|
||||
|
||||
var engine = try storage.StorageEngine.init(allocator, path);
|
||||
defer engine.deinit();
|
||||
|
||||
const key_schema = [_]types.KeySchemaElement{
|
||||
.{ .attribute_name = "pk", .key_type = .HASH },
|
||||
};
|
||||
const attr_defs = [_]types.AttributeDefinition{
|
||||
.{ .attribute_name = "pk", .attribute_type = .S },
|
||||
};
|
||||
|
||||
// Create table
|
||||
_ = try engine.createTable("DuplicateTest", &key_schema, &attr_defs);
|
||||
|
||||
// Try to create again - should fail
|
||||
const result = engine.createTable("DuplicateTest", &key_schema, &attr_defs);
|
||||
try std.testing.expectError(storage.StorageError.TableAlreadyExists, result);
|
||||
}
|
||||
|
||||
test "integration: table not found error" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
const path = "/tmp/test_integration_notfound";
|
||||
defer std.fs.deleteTreeAbsolute(path) catch {};
|
||||
|
||||
var engine = try storage.StorageEngine.init(allocator, path);
|
||||
defer engine.deinit();
|
||||
|
||||
// Try to put item in non-existent table
|
||||
const result = engine.putItem("NonExistent", "{\"pk\":{\"S\":\"item1\"}}");
|
||||
try std.testing.expectError(storage.StorageError.TableNotFound, result);
|
||||
}
|
||||
|
||||
test "integration: scan with limit" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
const path = "/tmp/test_integration_scan_limit";
|
||||
defer std.fs.deleteTreeAbsolute(path) catch {};
|
||||
|
||||
var engine = try storage.StorageEngine.init(allocator, path);
|
||||
defer engine.deinit();
|
||||
|
||||
const key_schema = [_]types.KeySchemaElement{
|
||||
.{ .attribute_name = "pk", .key_type = .HASH },
|
||||
};
|
||||
const attr_defs = [_]types.AttributeDefinition{
|
||||
.{ .attribute_name = "pk", .attribute_type = .S },
|
||||
};
|
||||
|
||||
_ = try engine.createTable("LimitTest", &key_schema, &attr_defs);
|
||||
|
||||
// Add many items
|
||||
var i: usize = 0;
|
||||
while (i < 10) : (i += 1) {
|
||||
var buf: [128]u8 = undefined;
|
||||
const item = try std.fmt.bufPrint(&buf, "{{\"pk\":{{\"S\":\"item{d}\"}}}}", .{i});
|
||||
try engine.putItem("LimitTest", item);
|
||||
}
|
||||
|
||||
// Scan with limit
|
||||
const limited = try engine.scan("LimitTest", 5);
|
||||
defer {
|
||||
for (limited) |item| allocator.free(item);
|
||||
allocator.free(limited);
|
||||
}
|
||||
try std.testing.expectEqual(@as(usize, 5), limited.len);
|
||||
}
|
||||
Reference in New Issue
Block a user