╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───╮ │src/test.zig│ ╰────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │78 -test "git push large subprocess" { │ │83 +test "push large subprocess" { │ │84 const io = std.testing.io; │ │85 const allocator = std.testing.allocator; │ │81 - try testPushLarge(.git, .xit, .{ .wire = .http }, 3028, true, false, io, allocator); │ │82 - try testPushLarge(.git, .xit, .{ .wire = .http }, 3029, true, true, io, allocator); │ │86 + try testPushLarge(.git, .xit, .{ .wire = .http }, 3070, true, false, io, allocator); │ │87 + try testPushLarge(.git, .xit, .{ .wire = .http }, 3071, true, true, io, allocator); │ │88 if (.windows != builtin.os.tag) { │ │84 - try testPushLarge(.git, .xit, .{ .wire = .ssh }, 3030, true, false, io, allocator);│ │89 + try testPushLarge(.git, .xit, .{ .wire = .ssh }, 3072, true, false, io, allocator);│ │90 + try testPushLarge(.git, .xit, .{ .wire = .ssh }, 3073, true, true, io, allocator); │ │91 } │ │92 } │ │93 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────╮ │117 server_thread: std.Thread, │ │118 }, │ │119 .raw => unreachable, │ │114 - .ssh => struct { │ │120 + .ssh => if (use_serve_command) struct {│ │121 + io: std.Io, │ │122 + allocator: std.mem.Allocator, │ │123 + sshd_process: ?std.process.Child, │ │124 + serve_process: ?std.process.Child, │ │125 + } else struct { │ │126 io: std.Io, │ │127 process: ?std.process.Child, │ │128 }, │ ╰────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │274 } │ │275 } │ │276 │ │266 - return .{ │ │267 - .core = .{ .io = io, .process = null }, │ │268 - }; │ │277 + if (use_serve_command) { │ │278 + comptime { │ │279 + std.debug.assert(server_repo_kind == .xit);│ │280 + } │ │281 + return .{ │ │282 + .core = .{ │ │283 + .io = io, │ │284 + .allocator = allocator, │ │285 + .sshd_process = null, │ │286 + .serve_process = null, │ │287 + }, │ │288 + }; │ │289 + } else { │ │290 + return .{ │ │291 + .core = .{ .io = io, .process = null }, │ │292 + }; │ │293 + } │ │294 }, │ │295 }, │ │296 } │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │478 }, │ │479 .raw => unreachable, │ │480 .ssh => { │ │456 - std.debug.assert(self.core.process == null); │ │457 - self.core.process = try std.process.spawn(self.core.io, .{ │ │458 - .argv = &.{"./sshd.sh"}, │ │459 - .cwd = .{ .path = temp_dir_name }, │ │460 - .stdin = .pipe, │ │461 - .stdout = .ignore, │ │462 - .stderr = .ignore, │ │463 - }); │ │481 + if (use_serve_command) { │ │482 + std.debug.assert(self.core.sshd_process == null); │ │483 + std.debug.assert(self.core.serve_process == null); │ │484 + │ │485 + const cwd_path = try std.process.currentPathAlloc(self.core.io, self.core.allocator); │ │486 + defer self.core.allocator.free(cwd_path); │ │487 + const haxy_path = try std.fs.path.join(self.core.allocator, &.{ cwd_path, "zig-out/bin/haxy" }); │ │488 + defer self.core.allocator.free(haxy_path); │ │489 + const ssh_listen_arg = std.fmt.comptimePrint("127.0.0.1:{}", .{port + 1000}); │ │490 + const http_listen_arg = std.fmt.comptimePrint("127.0.0.1:{}", .{port + 2000}); │ │491 + │ │492 + self.core.serve_process = try std.process.spawn(self.core.io, .{ │ │493 + .argv = &.{ haxy_path, "serve", "--http-listen", http_listen_arg, "--ssh-listen", ssh_listen_arg, "--project-root", temp_dir_name },│ │494 + .stdin = .ignore, │ │495 + .stdout = .ignore, │ │496 + .stderr = .ignore, │ │497 + }); │ │498 + │ │499 + const serve_address = try std.Io.net.IpAddress.parseIp4("127.0.0.1", port + 1000); │ │500 + for (0..50) |_| { │ │501 + const stream = serve_address.connect(self.core.io, .{ .mode = .stream }) catch { │ │502 + try std.Io.sleep(self.core.io, .fromMilliseconds(100), .real); │ │503 + continue; │ │504 + }; │ │505 + var probe_buf = [_]u8{0} ** 16; │ │506 + var probe_writer = stream.writer(self.core.io, &probe_buf); │ │507 + try probe_writer.interface.writeAll("probe\n"); │ │508 + try probe_writer.interface.flush(); │ │509 + stream.close(self.core.io); │ │510 + break; │ │511 + } │ │512 + │ │513 + self.core.sshd_process = try std.process.spawn(self.core.io, .{ │ │514 + .argv = &.{"./sshd.sh"}, │ │515 + .cwd = .{ .path = temp_dir_name }, │ │516 + .stdin = .pipe, │ │517 + .stdout = .ignore, │ │518 + .stderr = .ignore, │ │519 + }); │ │520 + } else { │ │521 + std.debug.assert(self.core.process == null); │ │522 + self.core.process = try std.process.spawn(self.core.io, .{ │ │523 + .argv = &.{"./sshd.sh"}, │ │524 + .cwd = .{ .path = temp_dir_name }, │ │525 + .stdin = .pipe, │ │526 + .stdout = .ignore, │ │527 + .stderr = .ignore, │ │528 + }); │ │529 + } │ │530 }, │ │531 }, │ │532 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │565 }, │ │566 .raw => unreachable, │ │567 .ssh => { │ │502 - _ = self.core.process.?.kill(self.core.io); │ │503 - self.core.process = null; │ │568 + if (use_serve_command) { │ │569 + if (self.core.sshd_process) |*process| { │ │570 + _ = process.kill(self.core.io); │ │571 + self.core.sshd_process = null; │ │572 + } │ │573 + if (self.core.serve_process) |*process| { │ │574 + _ = process.kill(self.core.io); │ │575 + self.core.serve_process = null; │ │576 + } │ │577 + } else { │ │578 + _ = self.core.process.?.kill(self.core.io);│ │579 + self.core.process = null; │ │580 + } │ │581 }, │ │582 }, │ │583 } │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │585 }; │ │586 } │ │587 │ │588 +fn uploadPackCommand( │ │589 + comptime server_repo_kind: rp.RepoKind, │ │590 + comptime is_ssh: bool, │ │591 + comptime use_serve_command: bool, │ │592 + allocator: std.mem.Allocator, │ │593 + cwd_path: []const u8, │ │594 + comptime port: u16, │ │595 +) ![]const u8 { │ │596 + return switch (server_repo_kind) { │ │597 + .xit => if (is_ssh and use_serve_command) │ │598 + std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy ssh-helper --ssh-connect 127.0.0.1:{} --service upload-pack", .{ cwd_path, port + 1000 }) │ │599 + else │ │600 + std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy upload-pack", .{cwd_path}), │ │601 + .git => allocator.dupe(u8, "git-upload-pack"), │ │602 + }; │ │603 +} │ │604 + │ │605 +fn receivePackCommand( │ │606 + comptime server_repo_kind: rp.RepoKind, │ │607 + comptime is_ssh: bool, │ │608 + comptime use_serve_command: bool, │ │609 + allocator: std.mem.Allocator, │ │610 + cwd_path: []const u8, │ │611 + comptime port: u16, │ │612 +) ![]const u8 { │ │613 + return switch (server_repo_kind) { │ │614 + .xit => if (is_ssh and use_serve_command) │ │615 + std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy ssh-helper --ssh-connect 127.0.0.1:{} --service receive-pack", .{ cwd_path, port + 1000 })│ │616 + else │ │617 + std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy receive-pack", .{cwd_path}), │ │618 + .git => allocator.dupe(u8, "git-receive-pack"), │ │619 + }; │ │620 +} │ │621 + │ │622 fn testFetch( │ │623 comptime repo_kind: rp.RepoKind, │ │624 comptime server_repo_kind: rp.RepoKind, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │727 } else null; │ │728 defer if (ssh_cmd_maybe) |ssh_cmd| allocator.free(ssh_cmd); │ │729 │ │619 - const upload_pack_command = try switch (server_repo_kind) { │ │620 - .xit => std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy upload-pack", .{cwd_path}), │ │621 - .git => allocator.dupe(u8, "git-upload-pack"), │ │622 - }; │ │730 + const upload_pack_command = try uploadPackCommand(server_repo_kind, is_ssh, use_serve_command, allocator, cwd_path, port);│ │731 defer allocator.free(upload_pack_command); │ │732 │ │733 try client_repo.fetch( │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │898 } else null; │ │899 defer if (ssh_cmd_maybe) |ssh_cmd| allocator.free(ssh_cmd); │ │900 │ │793 - const upload_pack_command = try switch (server_repo_kind) { │ │794 - .xit => std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy upload-pack", .{cwd_path}), │ │795 - .git => allocator.dupe(u8, "git-upload-pack"), │ │796 - }; │ │901 + const upload_pack_command = try uploadPackCommand(server_repo_kind, is_ssh, use_serve_command, allocator, cwd_path, port); │ │902 defer allocator.free(upload_pack_command); │ │798 - const receive_pack_command = try switch (server_repo_kind) { │ │799 - .xit => std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy receive-pack", .{cwd_path}), │ │800 - .git => allocator.dupe(u8, "git-receive-pack"), │ │801 - }; │ │903 + const receive_pack_command = try receivePackCommand(server_repo_kind, is_ssh, use_serve_command, allocator, cwd_path, port);│ │904 defer allocator.free(receive_pack_command); │ │905 │ │906 try client_repo.push( │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1172 .wire => |wire_kind| .ssh == wire_kind, │ │1173 }; │ │1174 │ │1073 - const upload_pack_command = try switch (server_repo_kind) { │ │1074 - .xit => std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy upload-pack", .{cwd_path}), │ │1075 - .git => allocator.dupe(u8, "git-upload-pack"), │ │1076 - }; │ │1175 + const upload_pack_command = try uploadPackCommand(server_repo_kind, is_ssh, use_serve_command, allocator, cwd_path, port);│ │1176 defer allocator.free(upload_pack_command); │ │1177 │ │1178 if (shell_out_to_git) { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1476 .wire => |wire_kind| .ssh == wire_kind, │ │1477 }; │ │1478 │ │1380 - const upload_pack_command = try switch (server_repo_kind) { │ │1381 - .xit => std.fmt.allocPrint(allocator, "{s}/zig-out/bin/haxy upload-pack", .{cwd_path}), │ │1382 - .git => allocator.dupe(u8, "git-upload-pack"), │ │1383 - }; │ │1479 + const upload_pack_command = try uploadPackCommand(server_repo_kind, is_ssh, use_serve_command, allocator, cwd_path, port);│ │1480 defer allocator.free(upload_pack_command); │ │1481 │ │1482 if (shell_out_to_git) { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯