162 lines
4.4 KiB
Rust
162 lines
4.4 KiB
Rust
//! Integration tests for the `logshape` command.
|
|
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
|
|
use assert_cmd::Command;
|
|
use predicates::prelude::*;
|
|
use tempfile::tempdir;
|
|
|
|
fn cargo_command() -> Command {
|
|
Command::cargo_bin("logshape").expect("binary")
|
|
}
|
|
|
|
fn workspace_root() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
.join("..")
|
|
.join("..")
|
|
.canonicalize()
|
|
.expect("workspace root")
|
|
}
|
|
|
|
fn fixture_relative(path: &str) -> PathBuf {
|
|
PathBuf::from("fixtures").join(path)
|
|
}
|
|
|
|
fn fixture(path: &str) -> PathBuf {
|
|
workspace_root().join(fixture_relative(path))
|
|
}
|
|
|
|
fn relative_to_workspace(path: &str) -> String {
|
|
fixture_relative(path).display().to_string()
|
|
}
|
|
|
|
fn pwsh_command(script: impl AsRef<str>) -> Command {
|
|
let mut command = Command::new("pwsh");
|
|
command
|
|
.arg("-NoProfile")
|
|
.arg("-Command")
|
|
.arg(script.as_ref());
|
|
command
|
|
}
|
|
|
|
#[test]
|
|
fn groups_repetitive_logs_in_text_mode() {
|
|
let mut command = cargo_command();
|
|
command
|
|
.arg(fixture("logs/repetitive.log"))
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("count=2"))
|
|
.stdout(predicate::str::contains(
|
|
"connected to tcp://127.0.0.1:<num>",
|
|
))
|
|
.stdout(predicate::str::contains(
|
|
"failed request id=<num> path=<path>",
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn emits_json_groups_with_limits() {
|
|
let mut command = cargo_command();
|
|
command
|
|
.arg("--json")
|
|
.arg("--top")
|
|
.arg("2")
|
|
.arg("--min-count")
|
|
.arg("2")
|
|
.arg(fixture("logs/repetitive.log"))
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("\"count\":2"))
|
|
.stdout(predicate::str::contains("\"pattern\""))
|
|
.stdout(predicate::str::contains("\"sample\""))
|
|
.stdout(predicate::str::contains("retry in").not());
|
|
}
|
|
|
|
#[test]
|
|
fn supports_powershell_pipeline_input() {
|
|
let binary = assert_cmd::cargo::cargo_bin("logshape");
|
|
let input = relative_to_workspace("logs/repetitive.log");
|
|
let script = format!(
|
|
"[System.IO.File]::ReadLines('{}') | & '{}' --json --top 1",
|
|
input,
|
|
binary.display()
|
|
);
|
|
|
|
let mut command = pwsh_command(script);
|
|
command
|
|
.current_dir(workspace_root())
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("\"count\":2"))
|
|
.stdout(predicate::str::contains("\"first_line\":1"));
|
|
}
|
|
|
|
#[test]
|
|
fn utf8_bom_stdin_groups_first_line_with_following_lines() {
|
|
let mut command = cargo_command();
|
|
command
|
|
.args(["--json", "--min-count", "2"])
|
|
.write_stdin(
|
|
"\u{feff}INFO connected to tcp://127.0.0.1:5000\nINFO connected to tcp://127.0.0.1:5001\n",
|
|
)
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("\"count\":2"))
|
|
.stdout(predicate::str::contains("\"first_line\":1"));
|
|
}
|
|
|
|
#[test]
|
|
fn utf8_bom_log_file_groups_first_line_with_following_lines() {
|
|
let root = tempdir().expect("tempdir");
|
|
let log_path = root.path().join("bom.log");
|
|
fs::write(
|
|
&log_path,
|
|
"\u{feff}INFO connected to tcp://127.0.0.1:5000\nINFO connected to tcp://127.0.0.1:5001\n",
|
|
)
|
|
.expect("bom log");
|
|
|
|
let mut command = cargo_command();
|
|
command
|
|
.arg("--json")
|
|
.arg("--min-count")
|
|
.arg("2")
|
|
.arg(&log_path)
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("\"count\":2"))
|
|
.stdout(predicate::str::contains(
|
|
"connected to tcp://127.0.0.1:<num>",
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_utf8_log_file_reports_read_error_instead_of_grouping() {
|
|
let root = tempdir().expect("tempdir");
|
|
let log_path = root.path().join("invalid.log");
|
|
fs::write(&log_path, b"INFO ok\n\xff\xfe\xfd\n").expect("invalid log");
|
|
|
|
let mut command = cargo_command();
|
|
command
|
|
.arg(&log_path)
|
|
.assert()
|
|
.failure()
|
|
.stderr(predicate::str::contains("failed to read"))
|
|
.stderr(predicate::str::contains("valid UTF-8"));
|
|
}
|
|
|
|
#[test]
|
|
fn help_includes_grouping_examples() {
|
|
let mut command = cargo_command();
|
|
command
|
|
.arg("--help")
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("--min-count"))
|
|
.stdout(predicate::str::contains("ConvertFrom-Json"))
|
|
.stdout(predicate::str::contains(
|
|
"logshape .\\fixtures\\logs\\repetitive.log",
|
|
));
|
|
}
|