aboutsummaryrefslogtreecommitdiff
path: root/test/tests.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-06-30 11:27:39 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-07-02 13:27:28 -0700
commit8ce880ca753ce95138bf03d956cf363ea2dfde5a (patch)
treecb9b26f3b186e3ea8da52974ef2cb4c1ac416dc1 /test/tests.zig
parent22b20f20b66a0225fe1d57ab8773ac066c205bdd (diff)
downloadzig-8ce880ca753ce95138bf03d956cf363ea2dfde5a.tar.gz
zig-8ce880ca753ce95138bf03d956cf363ea2dfde5a.zip
avoid calling into stage1 backend when AstGen fails
The motivation for this commit is that there exists source files which produce ast-check errors, but crash stage1 or otherwise trigger stage1 bugs. Previously to this commit, Zig would run AstGen, collect the compile errors, run stage1, report stage1 compile errors and exit if any, and then report AstGen compile errors. The main change in this commit is to report AstGen errors prior to invoking stage1, and in fact if any AstGen errors occur, do not invoke stage1 at all. This caused most of the compile error tests to fail due to things such as unused local variables and mismatched stage1/stage2 error messages. It was taking a long time to update the test cases one-by-one, so I took this opportunity to unify the stage1 and stage2 testing harness, specifically with regards to compile errors. In this way we can start keeping track of which tests pass for 1, 2, or both. `zig build test-compile-errors` no longer works; it is now integrated into `zig build test-stage2`. This is one step closer to executing compile error tests in parallel; in fact the ThreadPool object is already in scope. There are some cases where the stage1 compile errors were actually better; those are left failing in this commit, to be addressed in a follow-up commit. Other changes in this commit: * build.zig: improve support for -Dstage1 used with the test step. * AstGen: minor cosmetic changes to error messages. * stage2: add -fstage1 and -fno-stage1 flags. This now allows one to download a binary of the zig compiler and use the llvm backend of self-hosted. This was also needed for hooking up the test harness. However, I realized that stage1 calls exit() and also has memory leaks, so had to complicate the test harness by not using this flag after all and instead invoking as a child process. - These CLI flags will disappear once we start shipping the self-hosted compiler as the main compiler. Until then, they can be used to try out the work-in-progress stage2. * stage2: select the LLVM backend by default for release modes, as long as the target architecture is supported by LLVM. * test harness: support setting the optimize mode
Diffstat (limited to 'test/tests.zig')
-rw-r--r--test/tests.zig321
1 files changed, 0 insertions, 321 deletions
diff --git a/test/tests.zig b/test/tests.zig
index 8871c18428..0b736792b9 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -16,7 +16,6 @@ const LibExeObjStep = build.LibExeObjStep;
const compare_output = @import("compare_output.zig");
const standalone = @import("standalone.zig");
const stack_traces = @import("stack_traces.zig");
-const compile_errors = @import("compile_errors.zig");
const assemble_and_link = @import("assemble_and_link.zig");
const runtime_safety = @import("runtime_safety.zig");
const translate_c = @import("translate_c.zig");
@@ -384,21 +383,6 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:
return cases.step;
}
-pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
- const cases = b.allocator.create(CompileErrorContext) catch unreachable;
- cases.* = CompileErrorContext{
- .b = b,
- .step = b.step("test-compile-errors", "Run the compile error tests"),
- .test_index = 0,
- .test_filter = test_filter,
- .modes = modes,
- };
-
- compile_errors.addCases(cases);
-
- return cases.step;
-}
-
pub fn addStandaloneTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode, skip_non_native: bool, target: std.zig.CrossTarget) *build.Step {
const cases = b.allocator.create(StandaloneContext) catch unreachable;
cases.* = StandaloneContext{
@@ -840,304 +824,6 @@ pub const StackTracesContext = struct {
};
};
-pub const CompileErrorContext = struct {
- b: *build.Builder,
- step: *build.Step,
- test_index: usize,
- test_filter: ?[]const u8,
- modes: []const Mode,
-
- const TestCase = struct {
- name: []const u8,
- sources: ArrayList(SourceFile),
- expected_errors: ArrayList([]const u8),
- expect_exact: bool,
- link_libc: bool,
- is_exe: bool,
- is_test: bool,
- target: CrossTarget = CrossTarget{},
-
- const SourceFile = struct {
- filename: []const u8,
- source: []const u8,
- };
-
- pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
- self.sources.append(SourceFile{
- .filename = filename,
- .source = source,
- }) catch unreachable;
- }
-
- pub fn addExpectedError(self: *TestCase, text: []const u8) void {
- self.expected_errors.append(text) catch unreachable;
- }
- };
-
- const CompileCmpOutputStep = struct {
- pub const base_id = .custom;
-
- step: build.Step,
- context: *CompileErrorContext,
- name: []const u8,
- test_index: usize,
- case: *const TestCase,
- build_mode: Mode,
- write_src: *build.WriteFileStep,
-
- const ErrLineIter = struct {
- lines: mem.SplitIterator,
-
- const source_file = "tmp.zig";
-
- fn init(input: []const u8) ErrLineIter {
- return ErrLineIter{ .lines = mem.split(input, "\n") };
- }
-
- fn next(self: *ErrLineIter) ?[]const u8 {
- while (self.lines.next()) |line| {
- if (mem.indexOf(u8, line, source_file) != null)
- return line;
- }
- return null;
- }
- };
-
- pub fn create(
- context: *CompileErrorContext,
- name: []const u8,
- case: *const TestCase,
- build_mode: Mode,
- write_src: *build.WriteFileStep,
- ) *CompileCmpOutputStep {
- const allocator = context.b.allocator;
- const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
- ptr.* = CompileCmpOutputStep{
- .step = build.Step.init(.custom, "CompileCmpOutput", allocator, make),
- .context = context,
- .name = name,
- .test_index = context.test_index,
- .case = case,
- .build_mode = build_mode,
- .write_src = write_src,
- };
-
- context.test_index += 1;
- return ptr;
- }
-
- fn make(step: *build.Step) !void {
- const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
- const b = self.context.b;
-
- var zig_args = ArrayList([]const u8).init(b.allocator);
- zig_args.append(b.zig_exe) catch unreachable;
-
- if (self.case.is_exe) {
- try zig_args.append("build-exe");
- } else if (self.case.is_test) {
- try zig_args.append("test");
- } else {
- try zig_args.append("build-obj");
- }
- const root_src_basename = self.case.sources.items[0].filename;
- try zig_args.append(self.write_src.getFileSource(root_src_basename).?.getPath(b));
-
- zig_args.append("--name") catch unreachable;
- zig_args.append("test") catch unreachable;
-
- if (!self.case.target.isNative()) {
- try zig_args.append("-target");
- try zig_args.append(try self.case.target.zigTriple(b.allocator));
- }
-
- zig_args.append("-O") catch unreachable;
- zig_args.append(@tagName(self.build_mode)) catch unreachable;
-
- warn("Test {d}/{d} {s}...", .{ self.test_index + 1, self.context.test_index, self.name });
-
- if (b.verbose) {
- printInvocation(zig_args.items);
- }
-
- const child = std.ChildProcess.init(zig_args.items, b.allocator) catch unreachable;
- defer child.deinit();
-
- child.env_map = b.env_map;
- child.stdin_behavior = .Ignore;
- child.stdout_behavior = .Pipe;
- child.stderr_behavior = .Pipe;
-
- child.spawn() catch |err| debug.panic("Unable to spawn {s}: {s}\n", .{ zig_args.items[0], @errorName(err) });
-
- var stdout_buf = ArrayList(u8).init(b.allocator);
- var stderr_buf = ArrayList(u8).init(b.allocator);
-
- child.stdout.?.reader().readAllArrayList(&stdout_buf, max_stdout_size) catch unreachable;
- child.stderr.?.reader().readAllArrayList(&stderr_buf, max_stdout_size) catch unreachable;
-
- const term = child.wait() catch |err| {
- debug.panic("Unable to spawn {s}: {s}\n", .{ zig_args.items[0], @errorName(err) });
- };
- switch (term) {
- .Exited => |code| {
- if (code == 0) {
- printInvocation(zig_args.items);
- return error.CompilationIncorrectlySucceeded;
- }
- },
- else => {
- warn("Process {s} terminated unexpectedly\n", .{b.zig_exe});
- printInvocation(zig_args.items);
- return error.TestFailed;
- },
- }
-
- const stdout = stdout_buf.items;
- const stderr = stderr_buf.items;
-
- if (stdout.len != 0) {
- warn(
- \\
- \\Expected empty stdout, instead found:
- \\================================================
- \\{s}
- \\================================================
- \\
- , .{stdout});
- return error.TestFailed;
- }
-
- var ok = true;
- if (self.case.expect_exact) {
- var err_iter = ErrLineIter.init(stderr);
- var i: usize = 0;
- ok = while (err_iter.next()) |line| : (i += 1) {
- if (i >= self.case.expected_errors.items.len) break false;
- const expected = self.case.expected_errors.items[i];
- if (mem.indexOf(u8, line, expected) == null) break false;
- continue;
- } else true;
-
- ok = ok and i == self.case.expected_errors.items.len;
-
- if (!ok) {
- warn("\n======== Expected these compile errors: ========\n", .{});
- for (self.case.expected_errors.items) |expected| {
- warn("{s}\n", .{expected});
- }
- }
- } else {
- for (self.case.expected_errors.items) |expected| {
- if (mem.indexOf(u8, stderr, expected) == null) {
- warn(
- \\
- \\=========== Expected compile error: ============
- \\{s}
- \\
- , .{expected});
- ok = false;
- break;
- }
- }
- }
-
- if (!ok) {
- warn(
- \\================= Full output: =================
- \\{s}
- \\
- , .{stderr});
- return error.TestFailed;
- }
-
- warn("OK\n", .{});
- }
- };
-
- pub fn create(
- self: *CompileErrorContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) *TestCase {
- const tc = self.b.allocator.create(TestCase) catch unreachable;
- tc.* = TestCase{
- .name = name,
- .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
- .expected_errors = ArrayList([]const u8).init(self.b.allocator),
- .expect_exact = false,
- .link_libc = false,
- .is_exe = false,
- .is_test = false,
- };
-
- tc.addSourceFile("tmp.zig", source);
- var arg_i: usize = 0;
- while (arg_i < expected_lines.len) : (arg_i += 1) {
- tc.addExpectedError(expected_lines[arg_i]);
- }
- return tc;
- }
-
- pub fn addC(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: []const []const u8) void {
- var tc = self.create(name, source, expected_lines);
- tc.link_libc = true;
- self.addCase(tc);
- }
-
- pub fn addExe(
- self: *CompileErrorContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) void {
- var tc = self.create(name, source, expected_lines);
- tc.is_exe = true;
- self.addCase(tc);
- }
-
- pub fn add(
- self: *CompileErrorContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) void {
- const tc = self.create(name, source, expected_lines);
- self.addCase(tc);
- }
-
- pub fn addTest(
- self: *CompileErrorContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) void {
- const tc = self.create(name, source, expected_lines);
- tc.is_test = true;
- self.addCase(tc);
- }
-
- pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {
- const b = self.b;
-
- const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {s}", .{
- case.name,
- }) catch unreachable;
- if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
- }
- const write_src = b.addWriteFiles();
- for (case.sources.items) |src_file| {
- write_src.add(src_file.filename, src_file.source);
- }
-
- const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, .Debug, write_src);
- compile_and_cmp_errors.step.dependOn(&write_src.step);
- self.step.dependOn(&compile_and_cmp_errors.step);
- }
-};
-
pub const StandaloneContext = struct {
b: *build.Builder,
step: *build.Step,
@@ -1312,13 +998,6 @@ pub const GenHContext = struct {
}
};
- fn printInvocation(args: []const []const u8) void {
- for (args) |arg| {
- warn("{s} ", .{arg});
- }
- warn("\n", .{});
- }
-
pub fn create(
self: *GenHContext,
filename: []const u8,