update ZIR compare output test to test incremental updates

This commit is contained in:
Andrew Kelley 2020-05-17 13:49:22 -04:00
parent 88c8ff6e37
commit b0968abccb
2 changed files with 202 additions and 116 deletions

View File

@ -21,8 +21,8 @@ pub const TestContext = struct {
pub const ZIRCompareOutputCase = struct {
name: []const u8,
src: [:0]const u8,
expected_stdout: []const u8,
src_list: []const []const u8,
expected_stdout_list: []const []const u8,
};
pub const ZIRTransformCase = struct {
@ -35,13 +35,13 @@ pub const TestContext = struct {
pub fn addZIRCompareOutput(
ctx: *TestContext,
name: []const u8,
src: [:0]const u8,
expected_stdout: []const u8,
src_list: []const []const u8,
expected_stdout_list: []const []const u8,
) void {
ctx.zir_cmp_output_cases.append(.{
.name = name,
.src = src,
.expected_stdout = expected_stdout,
.src_list = src_list,
.expected_stdout_list = expected_stdout_list,
}) catch unreachable;
}
@ -104,56 +104,68 @@ pub const TestContext = struct {
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
var prg_node = root_node.start(case.name, 2);
prg_node.activate();
defer prg_node.end();
const tmp_src_path = "test-case.zir";
try tmp.dir.writeFile(tmp_src_path, case.src);
const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path);
defer root_pkg.destroy();
{
var module = try Module.init(allocator, .{
.target = target,
.output_mode = .Exe,
.optimize_mode = .Debug,
.bin_file_dir = tmp.dir,
.bin_file_path = "a.out",
.root_pkg = root_pkg,
});
defer module.deinit();
var prg_node = root_node.start(case.name, case.src_list.len);
prg_node.activate();
defer prg_node.end();
var module_node = prg_node.start("parse,analysis,codegen", null);
module_node.activate();
var module = try Module.init(allocator, .{
.target = target,
.output_mode = .Exe,
.optimize_mode = .Debug,
.bin_file_dir = tmp.dir,
.bin_file_path = "a.out",
.root_pkg = root_pkg,
});
defer module.deinit();
for (case.src_list) |source, i| {
var src_node = prg_node.start("update", 2);
src_node.activate();
defer src_node.end();
try tmp.dir.writeFile(tmp_src_path, source);
var update_node = src_node.start("parse,analysis,codegen", null);
update_node.activate();
try module.makeBinFileWritable();
try module.update();
module_node.end();
}
update_node.end();
var exec_result = x: {
var exec_node = prg_node.start("execute", null);
exec_node.activate();
defer exec_node.end();
var exec_result = x: {
var exec_node = src_node.start("execute", null);
exec_node.activate();
defer exec_node.end();
break :x try std.ChildProcess.exec(.{
.allocator = allocator,
.argv = &[_][]const u8{"./a.out"},
.cwd_dir = tmp.dir,
});
};
defer allocator.free(exec_result.stdout);
defer allocator.free(exec_result.stderr);
switch (exec_result.term) {
.Exited => |code| {
if (code != 0) {
std.debug.warn("elf file exited with code {}\n", .{code});
return error.BinaryBadExitCode;
}
},
else => return error.BinaryCrashed,
try module.makeBinFileExecutable();
break :x try std.ChildProcess.exec(.{
.allocator = allocator,
.argv = &[_][]const u8{"./a.out"},
.cwd_dir = tmp.dir,
});
};
defer allocator.free(exec_result.stdout);
defer allocator.free(exec_result.stderr);
switch (exec_result.term) {
.Exited => |code| {
if (code != 0) {
std.debug.warn("elf file exited with code {}\n", .{code});
return error.BinaryBadExitCode;
}
},
else => return error.BinaryCrashed,
}
const expected_stdout = case.expected_stdout_list[i];
if (!std.mem.eql(u8, expected_stdout, exec_result.stdout)) {
std.debug.panic(
"update index {}, mismatched stdout\n====Expected (len={}):====\n{}\n====Actual (len={}):====\n{}\n========\n",
.{ i, expected_stdout.len, expected_stdout, exec_result.stdout.len, exec_result.stdout },
);
}
}
std.testing.expectEqualSlices(u8, case.expected_stdout, exec_result.stdout);
}
fn runOneZIRTransformCase(

View File

@ -65,74 +65,148 @@ pub fn addCases(ctx: *TestContext) void {
return;
}
ctx.addZIRCompareOutput("hello world ZIR",
\\@noreturn = primitive(noreturn)
\\@void = primitive(void)
\\@usize = primitive(usize)
\\@0 = int(0)
\\@1 = int(1)
\\@2 = int(2)
\\@3 = int(3)
\\
\\@syscall_array = str("syscall")
\\@sysoutreg_array = str("={rax}")
\\@rax_array = str("{rax}")
\\@rdi_array = str("{rdi}")
\\@rcx_array = str("rcx")
\\@r11_array = str("r11")
\\@rdx_array = str("{rdx}")
\\@rsi_array = str("{rsi}")
\\@memory_array = str("memory")
\\@len_array = str("len")
\\
\\@msg = str("Hello, world!\n")
\\
\\@start_fnty = fntype([], @noreturn, cc=Naked)
\\@start = fn(@start_fnty, {
\\ %SYS_exit_group = int(231)
\\ %exit_code = as(@usize, @0)
\\
\\ %syscall = ref(@syscall_array)
\\ %sysoutreg = ref(@sysoutreg_array)
\\ %rax = ref(@rax_array)
\\ %rdi = ref(@rdi_array)
\\ %rcx = ref(@rcx_array)
\\ %rdx = ref(@rdx_array)
\\ %rsi = ref(@rsi_array)
\\ %r11 = ref(@r11_array)
\\ %memory = ref(@memory_array)
\\
\\ %SYS_write = as(@usize, @1)
\\ %STDOUT_FILENO = as(@usize, @1)
\\
\\ %msg_ptr = ref(@msg)
\\ %msg_addr = ptrtoint(%msg_ptr)
\\
\\ %len_name = ref(@len_array)
\\ %msg_len_ptr = fieldptr(%msg_ptr, %len_name)
\\ %msg_len = deref(%msg_len_ptr)
\\ %rc_write = asm(%syscall, @usize,
\\ volatile=1,
\\ output=%sysoutreg,
\\ inputs=[%rax, %rdi, %rsi, %rdx],
\\ clobbers=[%rcx, %r11, %memory],
\\ args=[%SYS_write, %STDOUT_FILENO, %msg_addr, %msg_len])
\\
\\ %rc_exit = asm(%syscall, @usize,
\\ volatile=1,
\\ output=%sysoutreg,
\\ inputs=[%rax, %rdi],
\\ clobbers=[%rcx, %r11, %memory],
\\ args=[%SYS_exit_group, %exit_code])
\\
\\ %99 = unreachable()
\\});
\\
\\@9 = str("_start")
\\@10 = ref(@9)
\\@11 = export(@10, @start)
,
\\Hello, world!
\\
ctx.addZIRCompareOutput(
"hello world ZIR, update msg",
&[_][]const u8{
\\@noreturn = primitive(noreturn)
\\@void = primitive(void)
\\@usize = primitive(usize)
\\@0 = int(0)
\\@1 = int(1)
\\@2 = int(2)
\\@3 = int(3)
\\
\\@syscall_array = str("syscall")
\\@sysoutreg_array = str("={rax}")
\\@rax_array = str("{rax}")
\\@rdi_array = str("{rdi}")
\\@rcx_array = str("rcx")
\\@r11_array = str("r11")
\\@rdx_array = str("{rdx}")
\\@rsi_array = str("{rsi}")
\\@memory_array = str("memory")
\\@len_array = str("len")
\\
\\@msg = str("Hello, world!\n")
\\
\\@start_fnty = fntype([], @noreturn, cc=Naked)
\\@start = fn(@start_fnty, {
\\ %SYS_exit_group = int(231)
\\ %exit_code = as(@usize, @0)
\\
\\ %syscall = ref(@syscall_array)
\\ %sysoutreg = ref(@sysoutreg_array)
\\ %rax = ref(@rax_array)
\\ %rdi = ref(@rdi_array)
\\ %rcx = ref(@rcx_array)
\\ %rdx = ref(@rdx_array)
\\ %rsi = ref(@rsi_array)
\\ %r11 = ref(@r11_array)
\\ %memory = ref(@memory_array)
\\
\\ %SYS_write = as(@usize, @1)
\\ %STDOUT_FILENO = as(@usize, @1)
\\
\\ %msg_ptr = ref(@msg)
\\ %msg_addr = ptrtoint(%msg_ptr)
\\
\\ %len_name = ref(@len_array)
\\ %msg_len_ptr = fieldptr(%msg_ptr, %len_name)
\\ %msg_len = deref(%msg_len_ptr)
\\ %rc_write = asm(%syscall, @usize,
\\ volatile=1,
\\ output=%sysoutreg,
\\ inputs=[%rax, %rdi, %rsi, %rdx],
\\ clobbers=[%rcx, %r11, %memory],
\\ args=[%SYS_write, %STDOUT_FILENO, %msg_addr, %msg_len])
\\
\\ %rc_exit = asm(%syscall, @usize,
\\ volatile=1,
\\ output=%sysoutreg,
\\ inputs=[%rax, %rdi],
\\ clobbers=[%rcx, %r11, %memory],
\\ args=[%SYS_exit_group, %exit_code])
\\
\\ %99 = unreachable()
\\});
\\
\\@9 = str("_start")
\\@10 = ref(@9)
\\@11 = export(@10, @start)
,
\\@noreturn = primitive(noreturn)
\\@void = primitive(void)
\\@usize = primitive(usize)
\\@0 = int(0)
\\@1 = int(1)
\\@2 = int(2)
\\@3 = int(3)
\\
\\@syscall_array = str("syscall")
\\@sysoutreg_array = str("={rax}")
\\@rax_array = str("{rax}")
\\@rdi_array = str("{rdi}")
\\@rcx_array = str("rcx")
\\@r11_array = str("r11")
\\@rdx_array = str("{rdx}")
\\@rsi_array = str("{rsi}")
\\@memory_array = str("memory")
\\@len_array = str("len")
\\
\\@msg = str("Hello, world!\n")
\\@msg2 = str("HELL WORLD\n")
\\
\\@start_fnty = fntype([], @noreturn, cc=Naked)
\\@start = fn(@start_fnty, {
\\ %SYS_exit_group = int(231)
\\ %exit_code = as(@usize, @0)
\\
\\ %syscall = ref(@syscall_array)
\\ %sysoutreg = ref(@sysoutreg_array)
\\ %rax = ref(@rax_array)
\\ %rdi = ref(@rdi_array)
\\ %rcx = ref(@rcx_array)
\\ %rdx = ref(@rdx_array)
\\ %rsi = ref(@rsi_array)
\\ %r11 = ref(@r11_array)
\\ %memory = ref(@memory_array)
\\
\\ %SYS_write = as(@usize, @1)
\\ %STDOUT_FILENO = as(@usize, @1)
\\
\\ %msg_ptr = ref(@msg2)
\\ %msg_addr = ptrtoint(%msg_ptr)
\\
\\ %len_name = ref(@len_array)
\\ %msg_len_ptr = fieldptr(%msg_ptr, %len_name)
\\ %msg_len = deref(%msg_len_ptr)
\\ %rc_write = asm(%syscall, @usize,
\\ volatile=1,
\\ output=%sysoutreg,
\\ inputs=[%rax, %rdi, %rsi, %rdx],
\\ clobbers=[%rcx, %r11, %memory],
\\ args=[%SYS_write, %STDOUT_FILENO, %msg_addr, %msg_len])
\\
\\ %rc_exit = asm(%syscall, @usize,
\\ volatile=1,
\\ output=%sysoutreg,
\\ inputs=[%rax, %rdi],
\\ clobbers=[%rcx, %r11, %memory],
\\ args=[%SYS_exit_group, %exit_code])
\\
\\ %99 = unreachable()
\\});
\\
\\@9 = str("_start")
\\@10 = ref(@9)
\\@11 = export(@10, @start)
},
&[_][]const u8{
\\Hello, world!
\\
,
\\HELL WORLD
\\
},
);
}