Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ repository = "https://github.com/basil/ptools"
license = "Apache-2.0"
keywords = ["linux", "process", "procfs", "debugging", "cli"]
categories = ["command-line-utilities", "development-tools::debugging"]
exclude = ["src/bin/test_*.rs"]

[lints.clippy]
uninlined_format_args = "warn"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ use std::thread;
use std::time::Duration;

fn find_exec(name: &str) -> std::path::PathBuf {
let env_var = format!("CARGO_BIN_EXE_{name}");
if let Some(p) = std::env::var_os(&env_var) {
return p.into();
}

let this_exec = std::env::current_exe().expect("current exe");
let exec_dir = this_exec
.parent()
Expand Down Expand Up @@ -52,7 +57,7 @@ fn parent_main() {
let ready_path =
env::var("PTOOLS_TEST_READY_FILE").expect("PTOOLS_TEST_READY_FILE must be set");

let mut child = Command::new(find_exec("examples/pfiles_sockopts_parent"))
let mut child = Command::new(find_exec("test_pfiles_sockopts_parent"))
.arg("--child")
.env("PTOOLS_TEST_READY_FILE", &ready_path)
.stdin(Stdio::null())
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 10 additions & 4 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,19 @@ use std::time::Duration;
use std::time::SystemTime;
use std::time::UNIX_EPOCH;

// Find an executable produced by the Cargo build
// Find an executable produced by the Cargo build.
//
// Cargo >=1.94 exposes `CARGO_BIN_EXE_<name>` to integration tests, which
// works regardless of `build.build-dir` or layout changes. Older Cargo
// versions fall back to locating the binary relative to the test executable.
pub fn find_exec(name: &str) -> PathBuf {
// Find the path where Cargo has placed the executables by looking at this test process's
// executable, which was also built by Cargo.
let env_var = format!("CARGO_BIN_EXE_{name}");
if let Some(p) = std::env::var_os(&env_var) {
return p.into();
}

let this_exec = std::env::current_exe().unwrap();
let exec_dir = this_exec.parent().unwrap().parent().unwrap();

exec_dir.join(name)
}

Expand Down
38 changes: 11 additions & 27 deletions tests/pargs_penv_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,7 @@ fn pargs_matches_started_process_arguments() {
"tabs\tinside",
];

let output = common::run_ptool(
"pargs",
&[],
"examples/pargs_penv",
&expected_args,
&[],
false,
);
let output = common::run_ptool("pargs", &[], "test_pargs_penv", &expected_args, &[], false);
let stdout = common::assert_success_and_get_stdout(output);

for arg in expected_args {
Expand Down Expand Up @@ -79,7 +72,7 @@ fn pargs_l_matches_started_process_arguments_as_shell_command_line() {
let output = common::run_ptool(
"pargs",
&["-l"],
"examples/pargs_penv",
"test_pargs_penv",
&expected_args,
&[],
false,
Expand All @@ -96,9 +89,7 @@ fn pargs_l_matches_started_process_arguments_as_shell_command_line() {

// pargs -l resolves argv[0] to the real executable path via /proc/[pid]/exe,
// so the first token should be the canonical path to the example binary.
let exe_path = common::find_exec("examples/pargs_penv")
.canonicalize()
.unwrap();
let exe_path = common::find_exec("test_pargs_penv").canonicalize().unwrap();
let expected_line = std::iter::once(exe_path.to_str().unwrap())
.chain(expected_args.iter().copied())
.map(shell_quote)
Expand All @@ -116,14 +107,7 @@ fn penv_matches_started_process_environment() {
("PTOOLS_TEST_UNICODE", "✓"),
];

let output = common::run_ptool(
"penv",
&[],
"examples/pargs_penv",
&[],
&expected_env,
false,
);
let output = common::run_ptool("penv", &[], "test_pargs_penv", &[], &expected_env, false);
let stdout = common::assert_success_and_get_stdout_allow_warnings(output);

for (key, value) in expected_env {
Expand All @@ -148,7 +132,7 @@ fn pargs_e_alias_matches_started_process_environment() {
let output = common::run_ptool(
"pargs",
&["-e"],
"examples/pargs_penv",
"test_pargs_penv",
&[],
&expected_env,
false,
Expand All @@ -167,7 +151,7 @@ fn pargs_e_alias_matches_started_process_environment() {

#[test]
fn pauxv_prints_auxv_entries() {
let output = common::run_ptool("pauxv", &[], "examples/pargs_penv", &[], &[], false);
let output = common::run_ptool("pauxv", &[], "test_pargs_penv", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

assert!(
Expand Down Expand Up @@ -249,10 +233,10 @@ fn pauxv_prints_auxv_entries() {

#[test]
fn pargs_x_alias_matches_pauxv_output() {
let pauxv_output = common::run_ptool("pauxv", &[], "examples/pargs_penv", &[], &[], false);
let pauxv_output = common::run_ptool("pauxv", &[], "test_pargs_penv", &[], &[], false);
let pauxv_stdout = common::assert_success_and_get_stdout(pauxv_output);

let pargs_output = common::run_ptool("pargs", &["-x"], "examples/pargs_penv", &[], &[], false);
let pargs_output = common::run_ptool("pargs", &["-x"], "test_pargs_penv", &[], &[], false);
let pargs_stdout = common::assert_success_and_get_stdout(pargs_output);

// Both should contain AT_PAGESZ
Expand Down Expand Up @@ -287,7 +271,7 @@ fn penv_reflects_runtime_setenv() {
let output = common::run_ptool(
"penv",
&[],
"examples/penv_setenv",
"test_penv_setenv",
&[],
&[("PTOOLS_TEST_OVERWRITE_VAR", "before")],
false,
Expand Down Expand Up @@ -318,7 +302,7 @@ fn pargs_e_reflects_runtime_setenv() {
let output = common::run_ptool(
"pargs",
&["-e"],
"examples/penv_setenv",
"test_penv_setenv",
&[],
&[("PTOOLS_TEST_OVERWRITE_VAR", "before")],
false,
Expand All @@ -342,7 +326,7 @@ fn pargs_e_reflects_runtime_setenv() {

#[test]
fn pargs_x_prints_auxv_entries() {
let output = common::run_ptool("pargs", &["-x"], "examples/pargs_penv", &[], &[], false);
let output = common::run_ptool("pargs", &["-x"], "test_pargs_penv", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

assert!(
Expand Down
6 changes: 3 additions & 3 deletions tests/pcred_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod common;

#[test]
fn pcred_reports_condensed_credentials() {
let output = common::run_ptool("pcred", &[], "examples/pcred_process", &[], &[], false);
let output = common::run_ptool("pcred", &[], "test_pcred_process", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

let mut lines = stdout.lines();
Expand All @@ -39,7 +39,7 @@ fn pcred_reports_condensed_credentials() {

#[test]
fn pcred_all_flag_shows_separate_credentials() {
let output = common::run_ptool("pcred", &["-a"], "examples/pcred_process", &[], &[], false);
let output = common::run_ptool("pcred", &["-a"], "test_pcred_process", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

let mut lines = stdout.lines();
Expand Down Expand Up @@ -90,7 +90,7 @@ fn pcred_reports_groups_when_supplementary_groups_exist() {

// The default mode may suppress the groups line if there is only one group
// matching rgid, so verify with -a which shows groups unconditionally.
let output = common::run_ptool("pcred", &["-a"], "examples/pcred_process", &[], &[], false);
let output = common::run_ptool("pcred", &["-a"], "test_pcred_process", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

assert!(
Expand Down
33 changes: 13 additions & 20 deletions tests/pfiles_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ fn pfiles_prints_header_lines() {
let output = common::run_ptool(
"pfiles",
&[],
"examples/pargs_penv",
"test_pargs_penv",
&[],
&[
("PTOOLS_TEST_SET_RLIMIT_NOFILE_SOFT", "123"),
Expand Down Expand Up @@ -534,7 +534,7 @@ fn pfiles_prints_header_lines() {

#[test]
fn pfiles_reports_epoll_anon_inode() {
let output = common::run_ptool("pfiles", &[], "examples/pfiles_epoll", &[], &[], false);
let output = common::run_ptool("pfiles", &[], "test_pfiles_epoll", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

let fd_map = parse_fd_map(&stdout);
Expand All @@ -553,7 +553,7 @@ fn pfiles_reports_epoll_anon_inode() {

#[test]
fn pfiles_non_verbose_mode_prints_fstat_only_descriptor_lines() {
let output = common::run_ptool("pfiles", &["-n"], "examples/pfiles_epoll", &[], &[], false);
let output = common::run_ptool("pfiles", &["-n"], "test_pfiles_epoll", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

let fd_map = parse_fd_map(&stdout);
Expand Down Expand Up @@ -585,7 +585,7 @@ fn pfiles_non_verbose_mode_prints_fstat_only_descriptor_lines() {
fn pfiles_resolves_socket_metadata_for_target_net_namespace() {
let ready = common::ReadySignal::new(false);

let example = common::find_exec("examples/pfiles_netlink");
let example = common::find_exec("test_pfiles_netlink");
let mut unshare_cmd = Command::new("unshare");
unshare_cmd
.arg("--net")
Expand Down Expand Up @@ -652,7 +652,7 @@ fn pfiles_resolves_socket_metadata_for_target_net_namespace() {

#[test]
fn pfiles_reports_netlink_socket() {
let output = common::run_ptool("pfiles", &[], "examples/pfiles_netlink", &[], &[], false);
let output = common::run_ptool("pfiles", &[], "test_pfiles_netlink", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

let fd_map = parse_fd_map(&stdout);
Expand Down Expand Up @@ -693,7 +693,7 @@ fn pfiles_falls_back_to_sockprotoname_xattr_for_unknown_socket_family() {
let output = common::run_ptool(
"pfiles",
&[],
"examples/pfiles_af_alg",
"test_pfiles_af_alg",
&[&status_path],
&[],
false,
Expand Down Expand Up @@ -728,7 +728,7 @@ fn pfiles_falls_back_to_sockprotoname_xattr_for_unknown_socket_family() {

#[test]
fn pfiles_matrix_covers_file_types_and_socket_families() {
let output = common::run_ptool("pfiles", &[], "examples/pfiles_matrix", &[], &[], false);
let output = common::run_ptool("pfiles", &[], "test_pfiles_matrix", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

let fd_map = parse_fd_map(&stdout);
Expand Down Expand Up @@ -860,7 +860,7 @@ fn pfiles_matrix_covers_file_types_and_socket_families() {
"expected exactly one IPv4 listening socket block"
);

let inet_peer_expected = "S_IFSOCK mode:0777 dev:<dynamic> ino:<dynamic> uid:<dynamic> gid:<dynamic> size:<dynamic>\n O_RDWR|O_CLOEXEC\n SOCK_STREAM\n SO_SNDBUF(<dynamic>),SO_RCVBUF(<dynamic>)\n sockname: AF_INET 127.0.0.1 port: <dynamic>\n peer: pfiles_matrix[<dynamic>]\n peername: AF_INET 127.0.0.1 port: <dynamic>\n state: TCP_ESTABLISHED";
let inet_peer_expected = "S_IFSOCK mode:0777 dev:<dynamic> ino:<dynamic> uid:<dynamic> gid:<dynamic> size:<dynamic>\n O_RDWR|O_CLOEXEC\n SOCK_STREAM\n SO_SNDBUF(<dynamic>),SO_RCVBUF(<dynamic>)\n sockname: AF_INET 127.0.0.1 port: <dynamic>\n peer: test_pfiles_mat[<dynamic>]\n peername: AF_INET 127.0.0.1 port: <dynamic>\n state: TCP_ESTABLISHED";
assert!(
count_normalized_blocks_ignoring_tcp_details(&fd_map, inet_peer_expected) >= 1,
"expected at least one IPv4 established socket block"
Expand All @@ -875,7 +875,7 @@ fn pfiles_matrix_covers_file_types_and_socket_families() {
"expected exactly one IPv6 listening socket block"
);

let inet6_peer_expected = "S_IFSOCK mode:0777 dev:<dynamic> ino:<dynamic> uid:<dynamic> gid:<dynamic> size:<dynamic>\n O_RDWR|O_CLOEXEC\n SOCK_STREAM\n SO_SNDBUF(<dynamic>),SO_RCVBUF(<dynamic>)\n sockname: AF_INET6 ::1 port: <dynamic>\n peer: pfiles_matrix[<dynamic>]\n peername: AF_INET6 ::1 port: <dynamic>\n state: TCP_ESTABLISHED";
let inet6_peer_expected = "S_IFSOCK mode:0777 dev:<dynamic> ino:<dynamic> uid:<dynamic> gid:<dynamic> size:<dynamic>\n O_RDWR|O_CLOEXEC\n SOCK_STREAM\n SO_SNDBUF(<dynamic>),SO_RCVBUF(<dynamic>)\n sockname: AF_INET6 ::1 port: <dynamic>\n peer: test_pfiles_mat[<dynamic>]\n peername: AF_INET6 ::1 port: <dynamic>\n state: TCP_ESTABLISHED";
assert!(
count_normalized_blocks_ignoring_tcp_details(&fd_map, inet6_peer_expected) >= 1,
"expected at least one IPv6 established socket block"
Expand All @@ -901,7 +901,7 @@ fn pfiles_matrix_unix_socket() {
let output = common::run_ptool(
"pfiles",
&[],
"examples/pfiles_matrix_unix_socket",
"test_pfiles_matrix_unix_socket",
&[],
&[],
false,
Expand Down Expand Up @@ -939,7 +939,7 @@ fn pfiles_matrix_file_and_symlink_paths() {
let output = common::run_ptool(
"pfiles",
&[],
"examples/pfiles_matrix_file_link",
"test_pfiles_matrix_file_link",
&[matrix_file_path.as_str(), matrix_link_path.as_str()],
&[],
false,
Expand Down Expand Up @@ -996,7 +996,7 @@ fn pfiles_reports_socket_options_when_target_is_child_of_inspector() {
let output = common::run_ptool(
"pfiles",
&[],
"examples/pfiles_sockopts_parent",
"test_pfiles_sockopts_parent",
&["--child"],
&[],
false,
Expand Down Expand Up @@ -1049,14 +1049,7 @@ fn pfiles_reports_socket_options_when_target_is_child_of_inspector() {

#[test]
fn pfiles_exits_nonzero_when_any_pid_fails() {
let output = common::run_ptool(
"pfiles",
&["999999999"],
"examples/pargs_penv",
&[],
&[],
false,
);
let output = common::run_ptool("pfiles", &["999999999"], "test_pargs_penv", &[], &[], false);

assert!(!output.status.success());
let stderr = String::from_utf8_lossy(&output.stderr);
Expand Down
8 changes: 4 additions & 4 deletions tests/plgrp_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod common;

#[test]
fn plgrp_shows_home_node_for_all_threads() {
let output = common::run_ptool("plgrp", &[], "examples/plgrp_process", &[], &[], false);
let output = common::run_ptool("plgrp", &[], "test_plgrp_process", &[], &[], false);
let stdout = common::assert_success_and_get_stdout(output);

// Header line should contain NODE.
Expand Down Expand Up @@ -52,7 +52,7 @@ fn plgrp_shows_single_thread_with_tid() {
use std::process::Stdio;

let ready = common::ReadySignal::new(false);
let mut example_cmd = Command::new(common::find_exec("examples/plgrp_process"));
let mut example_cmd = Command::new(common::find_exec("test_plgrp_process"));
example_cmd
.stdin(Stdio::null())
.stderr(Stdio::inherit())
Expand Down Expand Up @@ -88,7 +88,7 @@ fn plgrp_affinity_flag_shows_affinity_column() {
let output = common::run_ptool(
"plgrp",
&["-a", "all"],
"examples/plgrp_process",
"test_plgrp_process",
&[],
&[],
false,
Expand All @@ -115,7 +115,7 @@ fn plgrp_error_for_nonexistent_pid() {
let output = common::run_ptool(
"plgrp",
&["999999999", "__NO_PID__"],
"examples/plgrp_process",
"test_plgrp_process",
&[],
&[],
false,
Expand Down
Loading
Loading