Skip to content

Commit 94c2cf7

Browse files
Merge pull request #28 from hendriknielaender/improved-test-suite
chore: add test suite
2 parents 842c9db + 59dc05f commit 94c2cf7

File tree

6 files changed

+468
-65
lines changed

6 files changed

+468
-65
lines changed

src/config.zig

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,65 @@ pub const Config = struct {
4949
enable_logging: bool = true,
5050
enable_simd: bool = true,
5151
};
52+
53+
const testing = std.testing;
54+
55+
test "Level.string returns correct strings" {
56+
try testing.expectEqualStrings("TRACE", Level.trace.string());
57+
try testing.expectEqualStrings("DEBUG", Level.debug.string());
58+
try testing.expectEqualStrings("INFO", Level.info.string());
59+
try testing.expectEqualStrings("WARN", Level.warn.string());
60+
try testing.expectEqualStrings("ERROR", Level.err.string());
61+
try testing.expectEqualStrings("FATAL", Level.fatal.string());
62+
}
63+
64+
test "Level.json_string returns correct JSON strings" {
65+
try testing.expectEqualStrings("Trace", Level.trace.json_string());
66+
try testing.expectEqualStrings("Debug", Level.debug.json_string());
67+
try testing.expectEqualStrings("Info", Level.info.json_string());
68+
try testing.expectEqualStrings("Warn", Level.warn.json_string());
69+
try testing.expectEqualStrings("Error", Level.err.json_string());
70+
try testing.expectEqualStrings("Fatal", Level.fatal.json_string());
71+
}
72+
73+
test "Level enum ordering" {
74+
try testing.expect(@intFromEnum(Level.trace) < @intFromEnum(Level.debug));
75+
try testing.expect(@intFromEnum(Level.debug) < @intFromEnum(Level.info));
76+
try testing.expect(@intFromEnum(Level.info) < @intFromEnum(Level.warn));
77+
try testing.expect(@intFromEnum(Level.warn) < @intFromEnum(Level.err));
78+
try testing.expect(@intFromEnum(Level.err) < @intFromEnum(Level.fatal));
79+
}
80+
81+
test "Config default values" {
82+
const config = Config{};
83+
try testing.expect(config.level == .info);
84+
try testing.expect(config.max_fields == 32);
85+
try testing.expect(config.buffer_size == 4096);
86+
try testing.expect(config.async_mode == false);
87+
try testing.expect(config.async_queue_size == 65536);
88+
try testing.expect(config.batch_size == 256);
89+
try testing.expect(config.enable_logging == true);
90+
try testing.expect(config.enable_simd == true);
91+
}
92+
93+
test "Config custom values" {
94+
const config = Config{
95+
.level = .debug,
96+
.max_fields = 64,
97+
.buffer_size = 8192,
98+
.async_mode = true,
99+
.async_queue_size = 32768,
100+
.batch_size = 128,
101+
.enable_logging = false,
102+
.enable_simd = false,
103+
};
104+
105+
try testing.expect(config.level == .debug);
106+
try testing.expect(config.max_fields == 64);
107+
try testing.expect(config.buffer_size == 8192);
108+
try testing.expect(config.async_mode == true);
109+
try testing.expect(config.async_queue_size == 32768);
110+
try testing.expect(config.batch_size == 128);
111+
try testing.expect(config.enable_logging == false);
112+
try testing.expect(config.enable_simd == false);
113+
}

src/correlation.zig

Lines changed: 140 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,6 @@ pub const Span = struct {
4343
return span_result;
4444
}
4545

46-
pub fn initLegacy(span_name: []const u8, parent_span_id: ?u64, task_context_id: u64) Span {
47-
assert(span_name.len > 0);
48-
assert(span_name.len < 256);
49-
assert(task_context_id >= 1);
50-
assert(parent_span_id == null or parent_span_id.? >= 1);
51-
52-
const trace_id_expanded = trace_mod.expand_short_to_trace_id(task_context_id);
53-
const parent_id_bytes = trace_mod.generate_span_id();
54-
const trace_ctx = trace_mod.TraceContext{
55-
.version = 0x00,
56-
.trace_id = trace_id_expanded,
57-
.parent_id = parent_id_bytes,
58-
.trace_flags = trace_mod.TraceFlags.sampled_only(false),
59-
};
60-
61-
var parent_span_bytes: ?[8]u8 = null;
62-
if (parent_span_id) |pid| {
63-
var pb: [8]u8 = undefined;
64-
std.mem.writeInt(u64, &pb, pid, .big);
65-
parent_span_bytes = pb;
66-
}
67-
68-
return init(span_name, parent_span_bytes, trace_ctx);
69-
}
70-
7146
pub fn getSpanIdBytes(self: *const Span) [8]u8 {
7247
return self.trace_context.parent_id;
7348
}
@@ -271,3 +246,143 @@ pub fn createChildTaskContext() TaskContext {
271246
assert(child_context.parent_id.? == parent_context.id);
272247
return child_context;
273248
}
249+
250+
const testing = std.testing;
251+
252+
test "Span.init creates valid span" {
253+
const trace_ctx = trace_mod.TraceContext.init(true);
254+
const span = Span.init("test_span", null, trace_ctx);
255+
256+
try testing.expectEqualStrings("test_span", span.name);
257+
try testing.expect(span.start_time > 0);
258+
try testing.expect(span.thread_id > 0);
259+
try testing.expect(span.id > 0);
260+
try testing.expect(span.parent_id == null);
261+
try testing.expect(span.task_id > 0);
262+
}
263+
264+
test "Span.getSpanIdBytes returns correct bytes" {
265+
const trace_ctx = trace_mod.TraceContext.init(false);
266+
const span = Span.init("test", null, trace_ctx);
267+
const span_bytes = span.getSpanIdBytes();
268+
269+
try testing.expect(span_bytes.len == 8);
270+
try testing.expect(!trace_mod.is_all_zero_id(span_bytes[0..]));
271+
}
272+
273+
test "TaskContext.init creates valid context" {
274+
const context = TaskContext.init(null);
275+
276+
try testing.expect(context.id >= 1);
277+
try testing.expect(context.parent_id == null);
278+
try testing.expect(context.span_stack.len == 0);
279+
try testing.expect(context.span_stack.capacity() == 32);
280+
}
281+
282+
test "TaskContext.fromTraceContext creates valid context" {
283+
const trace_ctx = trace_mod.TraceContext.init(true);
284+
const context = TaskContext.fromTraceContext(trace_ctx);
285+
286+
try testing.expect(context.id >= 1);
287+
try testing.expect(context.parent_id == null);
288+
try testing.expect(context.span_stack.len == 0);
289+
}
290+
291+
test "TaskContext span stack operations" {
292+
var context = TaskContext.init(null);
293+
const span_bytes = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
294+
295+
try testing.expect(context.currentSpan() == null);
296+
try testing.expect(context.popSpan() == null);
297+
298+
try context.pushSpan(span_bytes);
299+
try testing.expect(context.span_stack.len == 1);
300+
301+
const current = context.currentSpan().?;
302+
try testing.expect(std.mem.eql(u8, &current, &span_bytes));
303+
304+
const popped = context.popSpan().?;
305+
try testing.expect(std.mem.eql(u8, &popped, &span_bytes));
306+
try testing.expect(context.span_stack.len == 0);
307+
}
308+
309+
test "TaskContext legacy span operations" {
310+
var context = TaskContext.init(null);
311+
const span_id: u64 = 12345;
312+
313+
try context.pushSpanLegacy(span_id);
314+
try testing.expect(context.span_stack.len == 1);
315+
316+
const current_legacy = context.currentSpanLegacy().?;
317+
try testing.expect(current_legacy == span_id);
318+
319+
const popped_legacy = context.popSpanLegacy().?;
320+
try testing.expect(popped_legacy == span_id);
321+
try testing.expect(context.span_stack.len == 0);
322+
}
323+
324+
test "TaskContext.createChildTraceContext" {
325+
const context = TaskContext.init(null);
326+
const child_trace = context.createChildTraceContext(true);
327+
328+
try testing.expect(std.mem.eql(u8, &child_trace.trace_id, &context.trace_context.trace_id));
329+
try testing.expect(!std.mem.eql(u8, &child_trace.parent_id, &context.trace_context.parent_id));
330+
try testing.expect(child_trace.trace_flags.sampled == true);
331+
}
332+
333+
test "CorrelationContext.fromTraceContext" {
334+
const trace_ctx = trace_mod.TraceContext.init(false);
335+
const corr_ctx = CorrelationContext.fromTraceContext(trace_ctx, null, .info);
336+
337+
try testing.expect(corr_ctx.task_id >= 1);
338+
try testing.expect(corr_ctx.span_id > 0);
339+
try testing.expect(corr_ctx.thread_id > 0);
340+
try testing.expect(corr_ctx.level == .info);
341+
}
342+
343+
test "CorrelationContext.fromIds" {
344+
const corr_ctx = CorrelationContext.fromIds(12345, 67890, .warn);
345+
346+
try testing.expect(corr_ctx.task_id == @as(u32, @truncate(12345)));
347+
try testing.expect(corr_ctx.span_id == @as(u32, @truncate(67890)));
348+
try testing.expect(corr_ctx.thread_id > 0);
349+
try testing.expect(corr_ctx.level == .warn);
350+
}
351+
352+
test "generate_task_id produces unique IDs" {
353+
const id1 = generate_task_id();
354+
const id2 = generate_task_id();
355+
356+
try testing.expect(id1 >= 1);
357+
try testing.expect(id2 >= 1);
358+
try testing.expect(id1 != id2);
359+
try testing.expect(id2 > id1);
360+
}
361+
362+
test "getCurrentTaskContext returns valid context" {
363+
const context = getCurrentTaskContext();
364+
365+
try testing.expect(context.id >= 1);
366+
try testing.expect(context.span_stack.capacity() == 32);
367+
}
368+
369+
test "setTaskContext and getCurrentTaskContext" {
370+
var custom_context = TaskContext.init(null);
371+
const original_id = custom_context.id;
372+
373+
setTaskContext(&custom_context);
374+
const retrieved_context = getCurrentTaskContext();
375+
376+
try testing.expect(retrieved_context.id == original_id);
377+
}
378+
379+
test "createChildTaskContext creates child with parent reference" {
380+
var parent_context = TaskContext.init(null);
381+
setTaskContext(&parent_context);
382+
383+
const child_context = createChildTaskContext();
384+
385+
try testing.expect(child_context.id >= 1);
386+
try testing.expect(child_context.parent_id.? == parent_context.id);
387+
try testing.expect(child_context.id != parent_context.id);
388+
}

src/event.zig

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -53,49 +53,32 @@ pub const LogEvent = struct {
5353
assert(event_result.timestamp_ms > 0);
5454
return event_result;
5555
}
56+
};
5657

57-
pub fn initLegacy(
58-
log_level: config.Level,
59-
log_message: []const u8,
60-
log_fields: []const field.Field,
61-
task_context_id: u64,
62-
span_context_id: ?u64,
63-
) LogEvent {
64-
assert(@intFromEnum(log_level) <= @intFromEnum(config.Level.fatal));
65-
assert(log_message.len > 0);
66-
assert(log_message.len < 64 * 1024);
67-
assert(log_fields.len <= 64);
68-
assert(task_context_id >= 1);
69-
assert(span_context_id == null or span_context_id.? >= 1);
70-
71-
const trace_id_expanded = trace_mod.expand_short_to_trace_id(task_context_id);
72-
const parent_id_generated = trace_mod.generate_span_id();
58+
const testing = std.testing;
7359

74-
var trace_id_hex_buf: [32]u8 = undefined;
75-
var span_id_hex_buf: [16]u8 = undefined;
60+
test "LogEvent.init creates valid event" {
61+
const trace_ctx = trace_mod.TraceContext.init(true);
62+
const fields = [_]field.Field{
63+
field.Field.string("key", "value"),
64+
field.Field.int("count", 42),
65+
};
7666

77-
_ = trace_mod.bytes_to_hex_lowercase(&trace_id_expanded, &trace_id_hex_buf) catch @panic("hex conversion failed with correct buffer size");
78-
_ = trace_mod.bytes_to_hex_lowercase(&parent_id_generated, &span_id_hex_buf) catch @panic("hex conversion failed with correct buffer size");
67+
const event = LogEvent.init(.info, "Test message", &fields, trace_ctx);
7968

80-
var parent_span_hex_opt: ?[16]u8 = null;
81-
if (span_context_id) |sid| {
82-
var span_bytes: [8]u8 = undefined;
83-
std.mem.writeInt(u64, &span_bytes, sid, .big);
84-
var parent_hex_buf: [16]u8 = undefined;
85-
_ = trace_mod.bytes_to_hex_lowercase(&span_bytes, &parent_hex_buf) catch @panic("hex conversion failed with correct buffer size");
86-
parent_span_hex_opt = parent_hex_buf;
87-
}
69+
try testing.expectEqualStrings("Test message", event.message);
70+
try testing.expect(event.fields.len == 2);
71+
try testing.expect(event.sampled == true);
72+
try testing.expect(event.timestamp_ms > 0);
73+
try testing.expect(event.thread_id > 0);
74+
try testing.expect(event.trace_id_hex.len == 32);
75+
try testing.expect(event.span_id_hex.len == 16);
76+
}
8877

89-
const fake_trace_ctx = trace_mod.TraceContext{
90-
.version = 0x00,
91-
.trace_id = trace_id_expanded,
92-
.parent_id = parent_id_generated,
93-
.trace_flags = trace_mod.TraceFlags.sampled_only(false),
94-
.trace_id_hex = trace_id_hex_buf,
95-
.span_id_hex = span_id_hex_buf,
96-
.parent_span_hex = parent_span_hex_opt,
97-
};
78+
test "LogEvent level string formatting" {
79+
const trace_ctx = trace_mod.TraceContext.init(false);
80+
const event = LogEvent.init(.debug, "Debug test", &.{}, trace_ctx);
9881

99-
return init(log_level, log_message, log_fields, fake_trace_ctx);
100-
}
101-
};
82+
const level_str = std.mem.sliceTo(&event.level_str, ' ');
83+
try testing.expectEqualStrings("DEBUG", level_str);
84+
}

0 commit comments

Comments
 (0)