forked from Crockan/MercuryToolbox
chore(release): prepare public source release
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "portunlock"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
readme.workspace = true
|
||||
publish.workspace = true
|
||||
description = "Inspect and free local TCP or UDP port owners on Windows."
|
||||
keywords.workspace = true
|
||||
categories.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
common = { path = "../common", default-features = false }
|
||||
humantime.workspace = true
|
||||
lexopt.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
windowsupport = { path = "../windowsupport" }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd.workspace = true
|
||||
predicates.workspace = true
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
//! Binary entry point for `portunlock`.
|
||||
#![allow(clippy::multiple_crate_versions)]
|
||||
|
||||
fn main() {
|
||||
std::process::exit(portunlock::main_entry());
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
Reference in New Issue
Block a user