diff --git a/Cargo.lock b/Cargo.lock index dd1862d..482217a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.15" @@ -60,6 +75,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + [[package]] name = "bitflags" version = "1.3.2" @@ -72,6 +93,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytecount" version = "0.6.8" @@ -84,6 +111,15 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -96,6 +132,20 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + [[package]] name = "clap" version = "4.5.21" @@ -270,6 +320,29 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -293,6 +366,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.167" @@ -311,6 +393,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + [[package]] name = "memchr" version = "2.7.4" @@ -344,6 +432,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_threads" version = "0.1.7" @@ -671,6 +768,12 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "siphasher" version = "0.3.11" @@ -903,6 +1006,7 @@ dependencies = [ name = "uu_dmesg" version = "0.0.1" dependencies = [ + "chrono", "clap", "regex", "serde", @@ -1013,6 +1117,61 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.82", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + [[package]] name = "wild" version = "2.2.1" @@ -1050,7 +1209,16 @@ version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" dependencies = [ - "windows-core", + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ "windows-targets 0.52.6", ] diff --git a/Cargo.toml b/Cargo.toml index 88c5e32..6d61165 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,8 @@ tempfile = { workspace = true } libc = { workspace = true } rand = { workspace = true } uucore = { workspace = true, features = ["entries", "process", "signals"] } +# dmesg test require fixed-boot-time feature turned on. +dmesg = { version = "0.0.1", package = "uu_dmesg", path = "src/uu/dmesg", features = ["fixed-boot-time"] } [target.'cfg(unix)'.dev-dependencies] xattr = { workspace = true } diff --git a/src/uu/dmesg/Cargo.toml b/src/uu/dmesg/Cargo.toml index 96df1cc..c6a8870 100644 --- a/src/uu/dmesg/Cargo.toml +++ b/src/uu/dmesg/Cargo.toml @@ -16,3 +16,7 @@ uucore = { workspace = true } regex = { workspace = true } serde_json = { workspace = true } serde = { workspace = true } +chrono = "0.4.38" + +[features] +fixed-boot-time = [] diff --git a/src/uu/dmesg/src/dmesg.rs b/src/uu/dmesg/src/dmesg.rs index 8fb64f7..75bfe8f 100644 --- a/src/uu/dmesg/src/dmesg.rs +++ b/src/uu/dmesg/src/dmesg.rs @@ -12,6 +12,7 @@ use uucore::{ }; mod json; +mod time_formatter; const ABOUT: &str = help_about!("dmesg.md"); const USAGE: &str = help_usage!("dmesg.md"); @@ -26,6 +27,22 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if matches.get_flag(options::JSON) { dmesg.output_format = OutputFormat::Json; } + if let Some(time_format) = matches.get_one::(options::TIME_FORMAT) { + dmesg.time_format = match &time_format[..] { + "delta" => TimeFormat::Delta, + "reltime" => TimeFormat::Reltime, + "ctime" => TimeFormat::Ctime, + "notime" => TimeFormat::Notime, + "iso" => TimeFormat::Iso, + "raw" => TimeFormat::Raw, + _ => { + return Err(USimpleError::new( + 1, + format!("unknown time format: {time_format}"), + )) + } + }; + } dmesg.parse()?.print(); Ok(()) } @@ -49,16 +66,27 @@ pub fn uu_app() -> Command { .help("use JSON output format") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::TIME_FORMAT) + .long("time-format") + .help( + "show timestamp using the given format:\n".to_string() + + " [delta|reltime|ctime|notime|iso|raw]", + ) + .action(ArgAction::Set), + ) } mod options { pub const KMSG_FILE: &str = "kmsg-file"; pub const JSON: &str = "json"; + pub const TIME_FORMAT: &str = "time-format"; } struct Dmesg<'a> { kmsg_file: &'a str, output_format: OutputFormat, + time_format: TimeFormat, records: Option>, } @@ -67,6 +95,7 @@ impl Dmesg<'_> { Dmesg { kmsg_file: "/dev/kmsg", output_format: OutputFormat::Normal, + time_format: TimeFormat::Raw, records: None, } } @@ -112,7 +141,7 @@ impl Dmesg<'_> { fn print(&self) { match self.output_format { OutputFormat::Json => self.print_json(), - OutputFormat::Normal => unimplemented!(), + OutputFormat::Normal => self.print_normal(), } } @@ -121,6 +150,34 @@ impl Dmesg<'_> { println!("{}", json::serialize_records(records)); } } + + fn print_normal(&self) { + if let Some(records) = &self.records { + let mut reltime_formatter = time_formatter::ReltimeFormatter::new(); + let mut delta_formatter = time_formatter::DeltaFormatter::new(); + for record in records { + match self.time_format { + TimeFormat::Delta => { + print!("[{}] ", delta_formatter.format(record.timestamp_us)) + } + TimeFormat::Reltime => { + print!("[{}] ", reltime_formatter.format(record.timestamp_us)) + } + TimeFormat::Ctime => { + print!("[{}] ", time_formatter::ctime(record.timestamp_us)) + } + TimeFormat::Iso => { + print!("{} ", time_formatter::iso(record.timestamp_us)) + } + TimeFormat::Raw => { + print!("[{}] ", time_formatter::raw(record.timestamp_us)) + } + TimeFormat::Notime => (), + } + println!("{}", record.message); + } + } + } } enum OutputFormat { @@ -128,10 +185,19 @@ enum OutputFormat { Json, } +enum TimeFormat { + Delta, + Reltime, + Ctime, + Notime, + Iso, + Raw, +} + struct Record { priority_facility: u32, _sequence: u64, - timestamp_us: u64, + timestamp_us: i64, message: String, } diff --git a/src/uu/dmesg/src/json.rs b/src/uu/dmesg/src/json.rs index 672d515..7549328 100644 --- a/src/uu/dmesg/src/json.rs +++ b/src/uu/dmesg/src/json.rs @@ -23,7 +23,7 @@ struct Dmesg<'a> { #[derive(serde::Serialize)] struct Record<'a> { pri: u32, - time: u64, + time: i64, msg: &'a str, } @@ -129,11 +129,11 @@ impl serde_json::ser::Formatter for DmesgFormatter { } } - fn write_u64(&mut self, writer: &mut W, value: u64) -> io::Result<()> + fn write_i64(&mut self, writer: &mut W, value: i64) -> io::Result<()> where W: ?Sized + io::Write, { - // The only u64 field in Dmesg is time, which requires a specific format + // The only i64 field in Dmesg is time, which requires a specific format let seconds = value / 1000000; let sub_seconds = value % 1000000; let repr = format!("{:>5}.{:0>6}", seconds, sub_seconds); diff --git a/src/uu/dmesg/src/time_formatter.rs b/src/uu/dmesg/src/time_formatter.rs new file mode 100644 index 0000000..198431f --- /dev/null +++ b/src/uu/dmesg/src/time_formatter.rs @@ -0,0 +1,170 @@ +// This file is part of the uutils util-linux package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use chrono::{DateTime, FixedOffset, TimeDelta}; +#[cfg(feature = "fixed-boot-time")] +use chrono::{NaiveDate, NaiveTime}; +use std::sync::OnceLock; + +pub fn raw(timestamp_us: i64) -> String { + let seconds = timestamp_us / 1000000; + let sub_seconds = timestamp_us % 1000000; + format!("{:>5}.{:0>6}", seconds, sub_seconds) +} + +pub fn ctime(timestamp_us: i64) -> String { + let date_time = boot_time() + .checked_add_signed(TimeDelta::microseconds(timestamp_us)) + .unwrap(); + date_time.format("%a %b %d %H:%M:%S %Y").to_string() +} + +pub fn iso(timestamp_us: i64) -> String { + let date_time = boot_time() + .checked_add_signed(TimeDelta::microseconds(timestamp_us)) + .unwrap(); + date_time.format("%Y-%m-%dT%H:%M:%S,%6f%:z").to_string() +} + +pub struct ReltimeFormatter { + state: State, + prev_timestamp_us: i64, + previous_unix_timestamp: i64, +} + +pub struct DeltaFormatter { + state: State, + prev_timestamp_us: i64, +} + +pub enum State { + Initial, + AfterBoot, + Delta, +} + +impl ReltimeFormatter { + pub fn new() -> Self { + ReltimeFormatter { + state: State::Initial, + prev_timestamp_us: 0, + previous_unix_timestamp: 0, + } + } + + pub fn format(&mut self, timestamp_us: i64) -> String { + let date_time = boot_time() + .checked_add_signed(TimeDelta::microseconds(timestamp_us)) + .unwrap(); + let unix_timestamp = date_time.timestamp(); + let minute_changes = (unix_timestamp / 60) != (self.previous_unix_timestamp / 60); + let format_res = match self.state { + State::Initial => date_time.format("%b%d %H:%M").to_string(), + _ if minute_changes => date_time.format("%b%d %H:%M").to_string(), + State::AfterBoot => Self::delta(0), + State::Delta => Self::delta(timestamp_us - self.prev_timestamp_us), + }; + self.prev_timestamp_us = timestamp_us; + self.previous_unix_timestamp = unix_timestamp; + self.state = match self.state { + State::Initial if timestamp_us == 0 => State::AfterBoot, + _ => State::Delta, + }; + format_res + } + + fn delta(delta_us: i64) -> String { + let seconds = i64::abs(delta_us / 1000000); + let sub_seconds = i64::abs(delta_us % 1000000); + let sign = if delta_us >= 0 { '+' } else { '-' }; + let res = format!("{}{}.{:0>6}", sign, seconds, sub_seconds); + format!("{:>11}", res) + } +} + +impl DeltaFormatter { + pub fn new() -> Self { + DeltaFormatter { + state: State::Initial, + prev_timestamp_us: 0, + } + } + + pub fn format(&mut self, timestamp_us: i64) -> String { + let format_res = match self.state { + State::Delta => Self::delta(timestamp_us - self.prev_timestamp_us), + _ => Self::delta(0), + }; + self.prev_timestamp_us = timestamp_us; + self.state = match self.state { + State::Initial if timestamp_us == 0 => State::AfterBoot, + _ => State::Delta, + }; + format_res + } + + fn delta(delta_us: i64) -> String { + let seconds = i64::abs(delta_us / 1000000); + let sub_seconds = i64::abs(delta_us % 1000000); + let mut res = format!("{}.{:0>6}", seconds, sub_seconds); + if delta_us < 0 { + res.insert(0, '-'); + } + format!("<{:>12}>", res) + } +} + +static BOOT_TIME: OnceLock> = OnceLock::new(); + +#[cfg(feature = "fixed-boot-time")] +fn boot_time() -> DateTime { + *BOOT_TIME.get_or_init(|| { + let date = NaiveDate::from_ymd_opt(2024, 11, 18).unwrap(); + let time = NaiveTime::from_hms_micro_opt(19, 34, 12, 866807).unwrap(); + let tz = FixedOffset::east_opt(7 * 3600).unwrap(); + chrono::NaiveDateTime::new(date, time) + .and_local_timezone(tz) + .unwrap() + }) +} + +#[cfg(not(feature = "fixed-boot-time"))] +#[cfg(unix)] +#[cfg(not(target_os = "openbsd"))] +fn boot_time() -> DateTime { + *BOOT_TIME.get_or_init(|| boot_time_from_utmpx().unwrap()) +} + +#[cfg(not(feature = "fixed-boot-time"))] +#[cfg(windows)] +fn boot_time() -> DateTime { + // TODO: get windows boot time + *BOOT_TIME.get_or_init(|| chrono::DateTime::from_timestamp(0, 0).unwrap().into()) +} + +#[cfg(not(feature = "fixed-boot-time"))] +#[cfg(target_os = "openbsd")] +fn boot_time() -> DateTime { + // TODO: get openbsd boot time + *BOOT_TIME.get_or_init(|| chrono::DateTime::from_timestamp(0, 0).unwrap().into()) +} + +#[cfg(not(feature = "fixed-boot-time"))] +#[cfg(unix)] +#[cfg(not(target_os = "openbsd"))] +fn boot_time_from_utmpx() -> Option> { + for record in uucore::utmpx::Utmpx::iter_all_records() { + if record.record_type() == uucore::utmpx::BOOT_TIME { + let t = record.login_time(); + return Some( + chrono::DateTime::from_timestamp(t.unix_timestamp(), t.nanosecond()) + .unwrap() + .with_timezone(&chrono::Local) + .into(), + ); + } + } + None +} diff --git a/tests/by-util/test_dmesg.rs b/tests/by-util/test_dmesg.rs index 08e398a..b811584 100644 --- a/tests/by-util/test_dmesg.rs +++ b/tests/by-util/test_dmesg.rs @@ -30,3 +30,54 @@ fn test_kmsg_json() { .no_stderr() .stdout_is_templated_fixture("test_kmsg_json.expected", &[("\r\n", "\n")]); } + +#[test] +fn test_kmsg_time_format_delta() { + test_kmsg_time_format("delta"); +} + +#[test] +fn test_kmsg_time_format_reltime() { + test_kmsg_time_format("reltime"); +} + +#[test] +fn test_kmsg_time_format_ctime() { + test_kmsg_time_format("ctime"); +} + +#[test] +fn test_kmsg_time_format_notime() { + test_kmsg_time_format("notime"); +} + +#[test] +fn test_kmsg_time_format_iso() { + test_kmsg_time_format("iso"); +} + +#[test] +fn test_kmsg_time_format_raw() { + test_kmsg_time_format("raw"); +} + +fn test_kmsg_time_format(format: &str) { + let time_format_arg = format!("--time-format={format}"); + let expected_output = format!("test_kmsg_time_format_{format}.expected"); + new_ucmd!() + .arg("--kmsg-file") + .arg("kmsg.input.1") + .arg(time_format_arg) + .succeeds() + .no_stderr() + .stdout_is_templated_fixture(expected_output, &[("\r\n", "\n")]); +} + +#[test] +fn test_invalid_time_format() { + new_ucmd!() + .arg("--time-format=definitely-invalid") + .fails() + .code_is(1) + .stderr_only("dmesg: unknown time format: definitely-invalid\n"); +} diff --git a/tests/fixtures/dmesg/kmsg.input.1 b/tests/fixtures/dmesg/kmsg.input.1 new file mode 100644 index 0000000..8c2a5cb Binary files /dev/null and b/tests/fixtures/dmesg/kmsg.input.1 differ diff --git a/tests/fixtures/dmesg/test_kmsg_time_format_ctime.expected b/tests/fixtures/dmesg/test_kmsg_time_format_ctime.expected new file mode 100644 index 0000000..559346d --- /dev/null +++ b/tests/fixtures/dmesg/test_kmsg_time_format_ctime.expected @@ -0,0 +1,5 @@ +[Mon Nov 18 19:34:12 2024] LOG_EMERG LOG_AUTH +[Mon Nov 18 19:34:13 2024] LOG_EMERG LOG_AUTHPRIV +[Mon Nov 18 19:34:13 2024] LOG_EMERG LOG_CRON +[Mon Nov 18 19:34:13 2024] LOG_EMERG LOG_DAEMON +[Mon Nov 18 19:35:00 2024] LOG_EMERG LOG_FTP diff --git a/tests/fixtures/dmesg/test_kmsg_time_format_delta.expected b/tests/fixtures/dmesg/test_kmsg_time_format_delta.expected new file mode 100644 index 0000000..81b8aad --- /dev/null +++ b/tests/fixtures/dmesg/test_kmsg_time_format_delta.expected @@ -0,0 +1,5 @@ +[< 0.000000>] LOG_EMERG LOG_AUTH +[< 0.000000>] LOG_EMERG LOG_AUTHPRIV +[< -0.166667>] LOG_EMERG LOG_CRON +[< 0.666667>] LOG_EMERG LOG_DAEMON +[< 47.000000>] LOG_EMERG LOG_FTP diff --git a/tests/fixtures/dmesg/test_kmsg_time_format_iso.expected b/tests/fixtures/dmesg/test_kmsg_time_format_iso.expected new file mode 100644 index 0000000..199ef99 --- /dev/null +++ b/tests/fixtures/dmesg/test_kmsg_time_format_iso.expected @@ -0,0 +1,5 @@ +2024-11-18T19:34:12,866807+07:00 LOG_EMERG LOG_AUTH +2024-11-18T19:34:13,366807+07:00 LOG_EMERG LOG_AUTHPRIV +2024-11-18T19:34:13,200140+07:00 LOG_EMERG LOG_CRON +2024-11-18T19:34:13,866807+07:00 LOG_EMERG LOG_DAEMON +2024-11-18T19:35:00,866807+07:00 LOG_EMERG LOG_FTP diff --git a/tests/fixtures/dmesg/test_kmsg_time_format_notime.expected b/tests/fixtures/dmesg/test_kmsg_time_format_notime.expected new file mode 100644 index 0000000..e16d233 --- /dev/null +++ b/tests/fixtures/dmesg/test_kmsg_time_format_notime.expected @@ -0,0 +1,5 @@ +LOG_EMERG LOG_AUTH +LOG_EMERG LOG_AUTHPRIV +LOG_EMERG LOG_CRON +LOG_EMERG LOG_DAEMON +LOG_EMERG LOG_FTP diff --git a/tests/fixtures/dmesg/test_kmsg_time_format_raw.expected b/tests/fixtures/dmesg/test_kmsg_time_format_raw.expected new file mode 100644 index 0000000..df70bd8 --- /dev/null +++ b/tests/fixtures/dmesg/test_kmsg_time_format_raw.expected @@ -0,0 +1,5 @@ +[ 0.000000] LOG_EMERG LOG_AUTH +[ 0.500000] LOG_EMERG LOG_AUTHPRIV +[ 0.333333] LOG_EMERG LOG_CRON +[ 1.000000] LOG_EMERG LOG_DAEMON +[ 48.000000] LOG_EMERG LOG_FTP diff --git a/tests/fixtures/dmesg/test_kmsg_time_format_reltime.expected b/tests/fixtures/dmesg/test_kmsg_time_format_reltime.expected new file mode 100644 index 0000000..6cebd19 --- /dev/null +++ b/tests/fixtures/dmesg/test_kmsg_time_format_reltime.expected @@ -0,0 +1,5 @@ +[Nov18 19:34] LOG_EMERG LOG_AUTH +[ +0.000000] LOG_EMERG LOG_AUTHPRIV +[ -0.166667] LOG_EMERG LOG_CRON +[ +0.666667] LOG_EMERG LOG_DAEMON +[Nov18 19:35] LOG_EMERG LOG_FTP