Skip to content

Commit 10d6323

Browse files
authored
Merge branch 'main' into unix-socket-mode-test
2 parents d88408a + 7cc9482 commit 10d6323

File tree

5 files changed

+373
-8
lines changed

5 files changed

+373
-8
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# ---------------------------------------------------------------------------- #
2+
# | █████╗ ██╗ ██╗██████╗ █████╗ ███████╗ | #
3+
# | ██╔══██╗██║ ██║██╔══██╗██╔══██╗██╔════╝ | #
4+
# | ███████║██║ ██║██████╔╝███████║█████╗ | #
5+
# | ██╔══██║██║ ██║██╔══██╗██╔══██║██╔══╝ | #
6+
# | ██║ ██║╚██████╔╝██║ ██║██║ ██║███████╗ | #
7+
# | ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ | #
8+
# +--------------------------------------------+ #
9+
# #
10+
# Distributed Systems Runtime #
11+
# ---------------------------------------------------------------------------- #
12+
# Copyright 2022 - 2024, the aurae contributors #
13+
# SPDX-License-Identifier: Apache-2.0 #
14+
# ---------------------------------------------------------------------------- #
15+
#
16+
# Ensure the codebase is formatted. Fails if `cargo fmt` would change files.
17+
#
18+
name: "(000) [ubuntu:latest] cargo fmt --check"
19+
20+
on:
21+
push:
22+
branches: main
23+
pull_request:
24+
branches: main
25+
26+
env:
27+
CARGO_TERM_COLOR: always
28+
29+
jobs:
30+
fmt:
31+
runs-on: ubuntu-latest
32+
steps:
33+
- uses: actions/checkout@v3
34+
- name: Check formatting
35+
run: cargo fmt --all -- --check

auraed/src/init/mod.rs

Lines changed: 123 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ pub async fn init(
8181
socket_address: Option<String>,
8282
) -> (Context, SocketStream) {
8383
let context = Context::get(nested);
84-
let init_result = match context {
85-
Context::Pid1 => Pid1SystemRuntime {}.init(verbose, socket_address),
86-
Context::Cell => CellSystemRuntime {}.init(verbose, socket_address),
87-
Context::Container => {
88-
ContainerSystemRuntime {}.init(verbose, socket_address)
89-
}
90-
Context::Daemon => DaemonSystemRuntime {}.init(verbose, socket_address),
91-
}
84+
let init_result = init_with_runtimes(
85+
context,
86+
verbose,
87+
socket_address,
88+
Pid1SystemRuntime {},
89+
CellSystemRuntime {},
90+
ContainerSystemRuntime {},
91+
DaemonSystemRuntime {},
92+
)
9293
.await;
9394

9495
match init_result {
@@ -97,6 +98,31 @@ pub async fn init(
9798
}
9899
}
99100

101+
async fn init_with_runtimes<RPid1, RCell, RContainer, RDaemon>(
102+
context: Context,
103+
verbose: bool,
104+
socket_address: Option<String>,
105+
pid1_runtime: RPid1,
106+
cell_runtime: RCell,
107+
container_runtime: RContainer,
108+
daemon_runtime: RDaemon,
109+
) -> Result<SocketStream, SystemRuntimeError>
110+
where
111+
RPid1: SystemRuntime,
112+
RCell: SystemRuntime,
113+
RContainer: SystemRuntime,
114+
RDaemon: SystemRuntime,
115+
{
116+
match context {
117+
Context::Pid1 => pid1_runtime.init(verbose, socket_address).await,
118+
Context::Cell => cell_runtime.init(verbose, socket_address).await,
119+
Context::Container => {
120+
container_runtime.init(verbose, socket_address).await
121+
}
122+
Context::Daemon => daemon_runtime.init(verbose, socket_address).await,
123+
}
124+
}
125+
100126
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
101127
pub enum Context {
102128
/// auraed is running as true PID 1
@@ -215,6 +241,16 @@ fn in_new_cgroup_namespace() -> bool {
215241
#[cfg(test)]
216242
mod tests {
217243
use super::*;
244+
use crate::init::system_runtimes::{
245+
SocketStream, SystemRuntime, SystemRuntimeError,
246+
};
247+
use anyhow::anyhow;
248+
use std::sync::{
249+
Arc,
250+
atomic::{AtomicUsize, Ordering},
251+
};
252+
use tokio::runtime::Runtime;
253+
use tonic::async_trait;
218254

219255
fn pid_one() -> u32 {
220256
1
@@ -282,4 +318,83 @@ mod tests {
282318
Context::Cell
283319
);
284320
}
321+
322+
#[derive(Clone)]
323+
struct MockRuntime {
324+
calls: Arc<AtomicUsize>,
325+
label: &'static str,
326+
}
327+
328+
impl MockRuntime {
329+
fn new(label: &'static str) -> Self {
330+
Self { calls: Arc::new(AtomicUsize::new(0)), label }
331+
}
332+
}
333+
334+
#[async_trait]
335+
impl SystemRuntime for Arc<MockRuntime> {
336+
async fn init(
337+
self,
338+
_verbose: bool,
339+
_socket_address: Option<String>,
340+
) -> Result<SocketStream, SystemRuntimeError> {
341+
let _ = self.calls.fetch_add(1, Ordering::SeqCst);
342+
Err(SystemRuntimeError::Other(anyhow!(self.label)))
343+
}
344+
}
345+
346+
fn assert_called_once(mock: &Arc<MockRuntime>) {
347+
assert_eq!(
348+
mock.calls.load(Ordering::SeqCst),
349+
1,
350+
"expected {} to be called once",
351+
mock.label
352+
);
353+
}
354+
355+
#[test]
356+
fn init_should_call_matching_system_runtime() {
357+
// This test ensures the `init` dispatcher chooses the correct runtime
358+
// implementation for each Context. We avoid spinning up real runtimes
359+
// by injecting cheap mocks that count how many times they're called.
360+
let rt = Runtime::new().expect("tokio runtime");
361+
362+
let pid1 = Arc::new(MockRuntime::new("pid1"));
363+
let cell = Arc::new(MockRuntime::new("cell"));
364+
let container = Arc::new(MockRuntime::new("container"));
365+
let daemon = Arc::new(MockRuntime::new("daemon"));
366+
367+
rt.block_on(async {
368+
// Each tuple represents (nested flag, pid, in_cgroup_namespace).
369+
// We exercise the four Context variants the same way Context::get does.
370+
let runtimes = [
371+
(false, 1, false),
372+
(true, 1, false),
373+
(false, 42, true),
374+
(false, 42, false),
375+
];
376+
377+
for (nested, pid, in_cgroup) in runtimes {
378+
let ctx = derive_context(nested, pid, in_cgroup);
379+
380+
// Call the same routing code init() uses, but with our mocks.
381+
let _ = init_with_runtimes(
382+
ctx,
383+
false,
384+
None,
385+
pid1.clone(),
386+
cell.clone(),
387+
container.clone(),
388+
daemon.clone(),
389+
)
390+
.await;
391+
}
392+
});
393+
394+
// Each mock should have been called exactly once by its matching Context.
395+
assert_called_once(&pid1);
396+
assert_called_once(&cell);
397+
assert_called_once(&container);
398+
assert_called_once(&daemon);
399+
}
285400
}

auraed/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,25 @@ pub fn prep_oci_spec_for_spawn(output: &str) -> Result<(), anyhow::Error> {
355355
.map_err(|e| anyhow!("building default oci spec: {e}"))?;
356356
spawn_auraed_oci_to(PathBuf::from(output), spec)
357357
}
358+
359+
#[cfg(test)]
360+
mod tests {
361+
use super::*;
362+
363+
#[test]
364+
fn auraed_runtime_default_socket_address_should_use_runtime_dir() {
365+
let default_runtime = AuraedRuntime::default();
366+
assert_eq!(
367+
default_runtime.default_socket_address(),
368+
PathBuf::from("/var/run/aurae/aurae.sock")
369+
);
370+
371+
let custom_runtime_dir = PathBuf::from("/tmp/aurae-test-runtime");
372+
let mut runtime = AuraedRuntime::default();
373+
runtime.runtime_dir = custom_runtime_dir.clone();
374+
assert_eq!(
375+
runtime.default_socket_address(),
376+
custom_runtime_dir.join("aurae.sock")
377+
);
378+
}
379+
}

auraed/tests/common/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ macro_rules! retry {
7575
}};
7676
}
7777

78+
#[allow(dead_code)]
7879
static RT: Lazy<tokio::runtime::Runtime> =
7980
Lazy::new(|| tokio::runtime::Runtime::new().unwrap());
8081

82+
#[allow(dead_code)]
8183
pub fn test<F>(f: F) -> F::Output
8284
where
8385
F: Future + Send + 'static,

0 commit comments

Comments
 (0)