chore(release): prepare public source release

This commit is contained in:
MercuryToolbox Release
2026-07-18 15:33:01 +08:00
commit 34d6a57f38
510 changed files with 163501 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
//! Integration tests for the `portunlock` command.
use assert_cmd::Command;
use predicates::prelude::*;
use std::io::{BufRead, BufReader};
use std::process::{Child, Command as StdCommand, Stdio};
fn cargo_command() -> Command {
Command::cargo_bin("portunlock").expect("binary")
}
struct Holder {
child: Child,
tcp_port: u16,
udp_port: u16,
}
impl Drop for Holder {
fn drop(&mut self) {
let _ = self.child.kill();
let _ = self.child.wait();
}
}
fn spawn_holder() -> Holder {
let script = "\
$ErrorActionPreference='Stop'; \
$tcp=[System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Loopback,0); \
$tcp.Start(); \
$udp=[System.Net.Sockets.UdpClient]::new(0); \
$tcpPort=([System.Net.IPEndPoint]$tcp.LocalEndpoint).Port; \
$udpPort=([System.Net.IPEndPoint]$udp.Client.LocalEndPoint).Port; \
[Console]::Out.WriteLine(\"$tcpPort,$udpPort\"); \
[Console]::Out.Flush(); \
try { Start-Sleep -Seconds 30 } finally { $tcp.Stop(); $udp.Close() }";
let mut child = StdCommand::new("pwsh")
.args(["-NoProfile", "-Command", script])
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("spawn holder");
let stdout = child.stdout.take().expect("holder stdout");
let mut reader = BufReader::new(stdout);
let mut line = String::new();
let read = reader.read_line(&mut line).expect("holder port line");
if read == 0 {
let status = child.wait().expect("holder exit status");
panic!("holder exited before reporting ports: {status}");
}
let (tcp, udp) = line.trim().split_once(',').expect("tcp,udp port line");
Holder {
child,
tcp_port: tcp.parse().expect("tcp port"),
udp_port: udp.parse().expect("udp port"),
}
}
#[test]
fn reports_port_owners_and_non_force_free_reports_remaining_tcp_owner() {
let holder = spawn_holder();
let tcp_port = holder.tcp_port;
let udp_port = holder.udp_port;
let mut who = cargo_command();
who.args(["who", "--json", "--protocol", "any"])
.arg(tcp_port.to_string())
.arg(udp_port.to_string())
.assert()
.success()
.stdout(predicate::str::contains(format!("\"port\":{tcp_port}")))
.stdout(predicate::str::contains(format!("\"port\":{udp_port}")))
.stdout(predicate::str::contains("\"protocol\":\"tcp\""))
.stdout(predicate::str::contains("\"protocol\":\"udp\""));
let mut free = cargo_command();
free.args(["free", "--json", "--protocol", "tcp"])
.arg(tcp_port.to_string())
.assert()
.code(3)
.stdout(predicate::str::contains(format!("\"port\":{tcp_port}")))
.stdout(predicate::str::contains("\"ok\":false"))
.stdout(predicate::str::contains("owners remain"));
}
#[test]
fn help_includes_port_examples() {
let mut command = cargo_command();
command
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("--protocol"))
.stdout(predicate::str::contains("portunlock who"))
.stdout(predicate::str::contains("ConvertFrom-Json"));
}