| ... | @@ -1413,12 +1413,23 @@ fn evalZigTest( | ... | @@ -1413,12 +1413,23 @@ fn evalZigTest( |
| 1413 | }); | 1413 | }); |
| 1414 | defer poller.deinit(); | 1414 | defer poller.deinit(); |
| 1415 | | 1415 | |
| 1416 | if (fuzz_context) |fuzz| { | 1416 | // If this is `true`, we avoid ever entering the polling loop below, because the stdin pipe has |
| 1417 | try sendRunTestMessage(child.stdin.?, .start_fuzzing, fuzz.unit_test_index); | 1417 | // somehow already closed; instead, we go straight to capturing stderr in case it has anything |
| 1418 | } else { | 1418 | // useful. |
| | 1419 | const first_write_failed = if (fuzz_context) |fuzz| failed: { |
| | 1420 | sendRunTestMessage(child.stdin.?, .start_fuzzing, fuzz.unit_test_index) catch |err| { |
| | 1421 | try run.step.addError("unable to write stdin: {s}", .{@errorName(err)}); |
| | 1422 | break :failed true; |
| | 1423 | }; |
| | 1424 | break :failed false; |
| | 1425 | } else failed: { |
| 1419 | run.fuzz_tests.clearRetainingCapacity(); | 1426 | run.fuzz_tests.clearRetainingCapacity(); |
| 1420 | try sendMessage(child.stdin.?, .query_test_metadata); | 1427 | sendMessage(child.stdin.?, .query_test_metadata) catch |err| { |
| 1421 | } | 1428 | try run.step.addError("unable to write stdin: {s}", .{@errorName(err)}); |
| | 1429 | break :failed true; |
| | 1430 | }; |
| | 1431 | break :failed false; |
| | 1432 | }; |
| 1422 | | 1433 | |
| 1423 | const Header = std.zig.Server.Message.Header; | 1434 | const Header = std.zig.Server.Message.Header; |
| 1424 | | 1435 | |
| ... | @@ -1437,13 +1448,13 @@ fn evalZigTest( | ... | @@ -1437,13 +1448,13 @@ fn evalZigTest( |
| 1437 | var sub_prog_node: ?std.Progress.Node = null; | 1448 | var sub_prog_node: ?std.Progress.Node = null; |
| 1438 | defer if (sub_prog_node) |n| n.end(); | 1449 | defer if (sub_prog_node) |n| n.end(); |
| 1439 | | 1450 | |
| 1440 | poll: while (true) { | 1451 | const any_write_failed = first_write_failed or poll: while (true) { |
| 1441 | while (stdout.readableLength() < @sizeOf(Header)) { | 1452 | while (stdout.readableLength() < @sizeOf(Header)) { |
| 1442 | if (!(try poller.poll())) break :poll; | 1453 | if (!(try poller.poll())) break :poll false; |
| 1443 | } | 1454 | } |
| 1444 | const header = stdout.reader().readStruct(Header) catch unreachable; | 1455 | const header = stdout.reader().readStruct(Header) catch unreachable; |
| 1445 | while (stdout.readableLength() < header.bytes_len) { | 1456 | while (stdout.readableLength() < header.bytes_len) { |
| 1446 | if (!(try poller.poll())) break :poll; | 1457 | if (!(try poller.poll())) break :poll false; |
| 1447 | } | 1458 | } |
| 1448 | const body = stdout.readableSliceOfLen(header.bytes_len); | 1459 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 1449 | | 1460 | |
| ... | @@ -1483,7 +1494,10 @@ fn evalZigTest( | ... | @@ -1483,7 +1494,10 @@ fn evalZigTest( |
| 1483 | .prog_node = prog_node, | 1494 | .prog_node = prog_node, |
| 1484 | }; | 1495 | }; |
| 1485 | | 1496 | |
| 1486 | try requestNextTest(child.stdin.?, &metadata.?, &sub_prog_node); | 1497 | requestNextTest(child.stdin.?, &metadata.?, &sub_prog_node) catch |err| { |
| | 1498 | try run.step.addError("unable to write stdin: {s}", .{@errorName(err)}); |
| | 1499 | break :poll true; |
| | 1500 | }; |
| 1487 | }, | 1501 | }, |
| 1488 | .test_results => { | 1502 | .test_results => { |
| 1489 | assert(fuzz_context == null); | 1503 | assert(fuzz_context == null); |
| ... | @@ -1518,7 +1532,10 @@ fn evalZigTest( | ... | @@ -1518,7 +1532,10 @@ fn evalZigTest( |
| 1518 | } | 1532 | } |
| 1519 | } | 1533 | } |
| 1520 | | 1534 | |
| 1521 | try requestNextTest(child.stdin.?, &metadata.?, &sub_prog_node); | 1535 | requestNextTest(child.stdin.?, &metadata.?, &sub_prog_node) catch |err| { |
| | 1536 | try run.step.addError("unable to write stdin: {s}", .{@errorName(err)}); |
| | 1537 | break :poll true; |
| | 1538 | }; |
| 1522 | }, | 1539 | }, |
| 1523 | .coverage_id => { | 1540 | .coverage_id => { |
| 1524 | const web_server = fuzz_context.?.web_server; | 1541 | const web_server = fuzz_context.?.web_server; |
| ... | @@ -1552,6 +1569,12 @@ fn evalZigTest( | ... | @@ -1552,6 +1569,12 @@ fn evalZigTest( |
| 1552 | } | 1569 | } |
| 1553 | | 1570 | |
| 1554 | stdout.discard(body.len); | 1571 | stdout.discard(body.len); |
| | 1572 | }; |
| | 1573 | |
| | 1574 | if (any_write_failed) { |
| | 1575 | // The compiler unexpectedly closed stdin; something is very wrong and has probably crashed. |
| | 1576 | // We want to make sure we've captured all of stderr so that it's logged below. |
| | 1577 | while (try poller.poll()) {} |
| 1555 | } | 1578 | } |
| 1556 | | 1579 | |
| 1557 | if (stderr.readableLength() > 0) { | 1580 | if (stderr.readableLength() > 0) { |