File: connected_to_journal.rs

package info (click to toggle)
rust-libsystemd 0.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 420 kB
  • sloc: makefile: 2
file content (110 lines) | stat: -rw-r--r-- 3,256 bytes parent folder | download | duplicates (2)
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");
        }
    }
}