| ... | @@ -52,6 +52,7 @@ pub fn main() !void { | ... | @@ -52,6 +52,7 @@ pub fn main() !void { |
| 52 | .arena = arena, | 52 | .arena = arena, |
| 53 | .case = case, | 53 | .case = case, |
| 54 | .tmp_dir = tmp_dir, | 54 | .tmp_dir = tmp_dir, |
| | 55 | .tmp_dir_path = tmp_dir_path, |
| 55 | .child = &child, | 56 | .child = &child, |
| 56 | }; | 57 | }; |
| 57 | | 58 | |
| ... | @@ -78,6 +79,7 @@ const Eval = struct { | ... | @@ -78,6 +79,7 @@ const Eval = struct { |
| 78 | arena: Allocator, | 79 | arena: Allocator, |
| 79 | case: Case, | 80 | case: Case, |
| 80 | tmp_dir: std.fs.Dir, | 81 | tmp_dir: std.fs.Dir, |
| | 82 | tmp_dir_path: []const u8, |
| 81 | child: *std.process.Child, | 83 | child: *std.process.Child, |
| 82 | | 84 | |
| 83 | const StreamEnum = enum { stdout, stderr }; | 85 | const StreamEnum = enum { stdout, stderr }; |
| ... | @@ -115,7 +117,6 @@ const Eval = struct { | ... | @@ -115,7 +117,6 @@ const Eval = struct { |
| 115 | if (!(try poller.poll())) break :poll; | 117 | if (!(try poller.poll())) break :poll; |
| 116 | } | 118 | } |
| 117 | const body = stdout.readableSliceOfLen(header.bytes_len); | 119 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 118 | std.log.debug("received message: {s}", .{@tagName(header.tag)}); | | |
| 119 | | 120 | |
| 120 | switch (header.tag) { | 121 | switch (header.tag) { |
| 121 | .error_bundle => { | 122 | .error_bundle => { |
| ... | @@ -191,13 +192,46 @@ const Eval = struct { | ... | @@ -191,13 +192,46 @@ const Eval = struct { |
| 191 | } | 192 | } |
| 192 | | 193 | |
| 193 | fn checkSuccessOutcome(eval: *Eval, update: Case.Update, binary_path: []const u8) !void { | 194 | fn checkSuccessOutcome(eval: *Eval, update: Case.Update, binary_path: []const u8) !void { |
| 194 | _ = eval; | | |
| 195 | switch (update.outcome) { | 195 | switch (update.outcome) { |
| 196 | .unknown => return, | 196 | .unknown => return, |
| 197 | .compile_errors => fatal("expected compile errors but compilation incorrectly succeeded", .{}), | 197 | .compile_errors => fatal("expected compile errors but compilation incorrectly succeeded", .{}), |
| 198 | .stdout, .exit_code => {}, | 198 | .stdout, .exit_code => {}, |
| 199 | } | 199 | } |
| 200 | fatal("TODO: run this binary: '{s}'", .{binary_path}); | 200 | const result = std.process.Child.run(.{ |
| | 201 | .allocator = eval.arena, |
| | 202 | .argv = &.{binary_path}, |
| | 203 | .cwd_dir = eval.tmp_dir, |
| | 204 | .cwd = eval.tmp_dir_path, |
| | 205 | }) catch |err| { |
| | 206 | fatal("update '{s}': failed to run the generated executable '{s}': {s}", .{ |
| | 207 | update.name, binary_path, @errorName(err), |
| | 208 | }); |
| | 209 | }; |
| | 210 | if (result.stderr.len != 0) { |
| | 211 | std.log.err("update '{s}': generated executable '{s}' had unexpected stderr:\n{s}", .{ |
| | 212 | update.name, binary_path, result.stderr, |
| | 213 | }); |
| | 214 | } |
| | 215 | switch (result.term) { |
| | 216 | .Exited => |code| switch (update.outcome) { |
| | 217 | .unknown, .compile_errors => unreachable, |
| | 218 | .stdout => |expected_stdout| { |
| | 219 | if (code != 0) { |
| | 220 | fatal("update '{s}': generated executable '{s}' failed with code {d}", .{ |
| | 221 | update.name, binary_path, code, |
| | 222 | }); |
| | 223 | } |
| | 224 | try std.testing.expectEqualStrings(expected_stdout, result.stdout); |
| | 225 | }, |
| | 226 | .exit_code => |expected_code| try std.testing.expectEqual(expected_code, result.term.Exited), |
| | 227 | }, |
| | 228 | .Signal, .Stopped, .Unknown => { |
| | 229 | fatal("update '{s}': generated executable '{s}' terminated unexpectedly", .{ |
| | 230 | update.name, binary_path, |
| | 231 | }); |
| | 232 | }, |
| | 233 | } |
| | 234 | if (result.stderr.len != 0) std.process.exit(1); |
| 201 | } | 235 | } |
| 202 | | 236 | |
| 203 | fn requestUpdate(eval: *Eval) !void { | 237 | fn requestUpdate(eval: *Eval) !void { |