1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#![deny(warnings, clippy::all)]
use std::collections::HashMap;
use std::env::VarError;
use std::process::Command;
use pretty_assertions::assert_eq;
use rand::distributions::Alphanumeric;
use rand::Rng;
use libsystemd::logging::*;
fn random_target(prefix: &str) -> String {
format!(
"{}_{}",
prefix,
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(10)
.map(char::from)
.collect::<String>()
)
}
#[derive(Debug, Copy, Clone)]
enum Journal {
User,
System,
}
fn read_from_journal(journal: Journal, target: &str) -> Vec<HashMap<String, String>> {
let stdout = String::from_utf8(
Command::new("journalctl")
.arg(match journal {
Journal::User => "--user",
Journal::System => "--system",
})
.arg("--output=json")
.arg(format!("TARGET={}", target))
.output()
.unwrap()
.stdout,
)
.unwrap();
stdout
.lines()
.map(|l| serde_json::from_str(l).unwrap())
.collect()
}
fn main() {
let env_name = "_TEST_LOG_TARGET";
// On Github Actions use the system instance for this test, because there's
// no user instance running apparently.
let journal_instance = if std::env::var_os("GITHUB_ACTIONS").is_some() {
Journal::System
} else {
Journal::User
};
match std::env::var(env_name) {
Ok(target) => {
journal_send(
Priority::Info,
&format!("connected_to_journal() -> {}", connected_to_journal()),
vec![("TARGET", &target)].into_iter(),
)
.unwrap();
}
Err(VarError::NotUnicode(value)) => {
panic!("Value of ${} not unicode: {:?}", env_name, value);
}
Err(VarError::NotPresent) => {
// Restart this binary under systemd-run and then check the journal for the test result
let exe = std::env::current_exe().unwrap();
let target = random_target("connected_to_journal");
let status = match journal_instance {
Journal::User => {
let mut cmd = Command::new("systemd-run");
cmd.arg("--user");
cmd
}
Journal::System => {
let mut cmd = Command::new("sudo");
cmd.arg("systemd-run");
cmd
}
}
.arg("--description=systemd-journal-logger integration test: journal_stream")
.arg(format!("--setenv={}={}", env_name, target))
// Wait until the process exited and unload the entire unit afterwards to
// leave no state behind
.arg("--wait")
.arg("--collect")
.arg(exe)
.status()
.unwrap();
assert!(status.success());
let entries = read_from_journal(journal_instance, &target);
assert_eq!(entries.len(), 1);
assert_eq!(entries[0]["TARGET"], target);
assert_eq!(entries[0]["MESSAGE"], "connected_to_journal() -> true");
}
}
}
|