• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NVIDIA / nvrc / 20354255911

18 Dec 2025 11:14PM UTC coverage: 28.618% (-4.0%) from 32.588%
20354255911

Pull #83

github

web-flow
Merge d10d69857 into 1bf141c3d
Pull Request #83: Ambush Multiple Agent Code Inspection

71 of 149 new or added lines in 8 files covered. (47.65%)

3 existing lines in 2 files now uncovered.

87 of 304 relevant lines covered (28.62%)

0.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.0
/src/syslog.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright (c) NVIDIA CORPORATION
3

4
//! Minimal syslog sink for ephemeral init environments.
5
//!
6
//! Programs expect /dev/log to exist for logging. As a minimal init we provide
7
//! this socket and forward messages to the kernel log. We don't need severity
8
//! levels since all output goes to trace! anyway.
9

10
use log::trace;
11
use nix::poll::{PollFd, PollFlags, PollTimeout};
12
use once_cell::sync::OnceCell;
13
use std::os::fd::AsFd;
14
use std::os::unix::net::UnixDatagram;
15
use std::path::Path;
16

17
// Ephemeral init only runs once, no need for reset capability
18
static SYSLOG: OnceCell<UnixDatagram> = OnceCell::new();
19

20
/// Exposed for testing with tempdir paths instead of /dev/log
21
pub fn bind(path: &Path) -> std::io::Result<UnixDatagram> {
1✔
22
    UnixDatagram::bind(path)
2✔
23
}
24

25
/// Separated from poll() to enable testing without the global static
26
pub fn poll_socket(sock: &UnixDatagram) -> std::io::Result<Option<String>> {
3✔
27
    let mut fds = [PollFd::new(sock.as_fd(), PollFlags::POLLIN)];
3✔
28
    // Non-blocking - init loop calls this frequently, can't block
29
    let count = nix::poll::poll(&mut fds, PollTimeout::ZERO)
6✔
30
        .map_err(|e| std::io::Error::other(e.to_string()))?;
3✔
31

32
    if count == 0 {
3✔
33
        return Ok(None);
1✔
34
    }
35

36
    let Some(revents) = fds[0].revents() else {
4✔
NEW
37
        return Ok(None);
×
38
    };
39

40
    if !revents.contains(PollFlags::POLLIN) {
2✔
NEW
41
        return Ok(None);
×
42
    }
43

44
    let mut buf = [0u8; 4096];
2✔
45
    let (len, _) = sock.recv_from(&mut buf)?;
2✔
46
    let msg = String::from_utf8_lossy(&buf[..len]);
2✔
47
    Ok(Some(strip_priority(msg.trim_end()).to_string()))
4✔
48
}
49

50
/// Drain one message per call - intentionally limited to prevent a rogue
51
/// process from DoS'ing init by flooding syslog. Caller loops at 2 msg/sec.
NEW
52
pub fn poll() -> std::io::Result<()> {
×
NEW
53
    let sock = SYSLOG.get_or_try_init(|| bind(Path::new("/dev/log")))?;
×
54

NEW
55
    if let Some(msg) = poll_socket(sock)? {
×
NEW
56
        trace!("{}", msg);
×
57
    }
58

59
    Ok(())
×
60
}
61

62
/// Priority prefix is just noise in our logs - we treat all messages equally
63
fn strip_priority(msg: &str) -> &str {
1✔
64
    msg.strip_prefix('<')
1✔
65
        .and_then(|s| s.find('>').map(|i| &s[i + 1..]))
7✔
66
        .unwrap_or(msg)
3✔
67
}
68

69
#[cfg(test)]
70
mod tests {
71
    use super::*;
72
    use tempfile::TempDir;
73

74
    #[test]
75
    fn test_strip_priority() {
76
        assert_eq!(strip_priority("<6>test message"), "test message");
77
        assert_eq!(strip_priority("<13>another msg"), "another msg");
78
        assert_eq!(strip_priority("<191>high pri"), "high pri");
79
        assert_eq!(strip_priority("no prefix"), "no prefix");
80
        assert_eq!(strip_priority("<>empty"), "empty");
81
        assert_eq!(strip_priority("<6>"), "");
82
    }
83

84
    #[test]
85
    fn test_poll_socket_no_data() {
86
        let tmp = TempDir::new().unwrap();
87
        let path = tmp.path().join("test.sock");
88
        let sock = bind(&path).unwrap();
89

90
        let result = poll_socket(&sock).unwrap();
91
        assert_eq!(result, None);
92
    }
93

94
    #[test]
95
    fn test_poll_socket_with_data() {
96
        let tmp = TempDir::new().unwrap();
97
        let path = tmp.path().join("test.sock");
98
        let server = bind(&path).unwrap();
99

100
        let client = UnixDatagram::unbound().unwrap();
101
        client.send_to(b"<6>hello world", &path).unwrap();
102

103
        let result = poll_socket(&server).unwrap();
104
        assert_eq!(result, Some("hello world".to_string()));
105
    }
106

107
    #[test]
108
    fn test_poll_socket_strips_priority() {
109
        let tmp = TempDir::new().unwrap();
110
        let path = tmp.path().join("test.sock");
111
        let server = bind(&path).unwrap();
112

113
        let client = UnixDatagram::unbound().unwrap();
114
        client.send_to(b"<3>error message", &path).unwrap();
115

116
        let result = poll_socket(&server).unwrap();
117
        assert_eq!(result, Some("error message".to_string()));
118
    }
119
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc