mirror of
https://github.com/joleuger/vuinputd.git
synced 2026-07-17 16:36:03 +00:00
Wrote integration test to test --placement on-host to fix #1. Looks good so far.
This commit is contained in:
parent
fd55bffddb
commit
6e23a02e3f
8 changed files with 80 additions and 27 deletions
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
## Integration tests
|
||||
|
||||
Ensure, you have a `/run/vuinputd/vuinput-test`-folder that allows the usage of character devices:
|
||||
```
|
||||
mkdir -p /run/vuinputd/vuinput-test
|
||||
mount -t tmpfs -o mode=755,size=1M tmpfs /run/vuinputd/vuinput-test
|
||||
mkdir -p /run/vuinputd/vuinput-test/dev
|
||||
mkdir -p /run/vuinputd/vuinput-test/dev-input
|
||||
mkdir -p /run/vuinputd/vuinput-test/udev
|
||||
```
|
||||
|
||||
### With bubblewrap
|
||||
|
||||
Install bubblewrap:
|
||||
|
|
|
|||
|
|
@ -58,8 +58,11 @@ impl BwrapBuilder {
|
|||
// So, we mount a temporary directory that does not have this restrictions.
|
||||
self.args.extend([
|
||||
"--dev-bind".into(),
|
||||
"/dev/tmp/vuinputd-test".into(),
|
||||
"/run/vuinputd/vuinput-test/dev".into(),
|
||||
"/dev".into(),
|
||||
"--dev-bind".into(),
|
||||
"/run/vuinputd/vuinput-test/dev-input".into(),
|
||||
"/dev/input".into(),
|
||||
]);
|
||||
self
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
use std::{
|
||||
os::unix::process::CommandExt,
|
||||
process::{Child, Command},
|
||||
sync::OnceLock,
|
||||
sync::Mutex,
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
|
@ -14,33 +14,37 @@ use nix::sys::signal::{self, Signal};
|
|||
use nix::unistd::Pid;
|
||||
|
||||
/// Global singleton
|
||||
static VUINPUTD: OnceLock<VuinputdGuard> = OnceLock::new();
|
||||
static VUINPUTD_LOCK: Mutex<()> = Mutex::new(());
|
||||
|
||||
pub fn ensure_vuinputd_running() {
|
||||
VUINPUTD.get_or_init(|| VuinputdGuard::start());
|
||||
pub fn ensure_vuinputd_running(args: &[&str]) -> VuinputdGuard {
|
||||
VuinputdGuard::start(args)
|
||||
}
|
||||
|
||||
struct VuinputdGuard {
|
||||
pub struct VuinputdGuard {
|
||||
child: Child,
|
||||
}
|
||||
|
||||
impl VuinputdGuard {
|
||||
fn start() -> Self {
|
||||
fn start(args: &[&str]) -> Self {
|
||||
println!("Acquiring lock to ensure only one vuinputd test instance is running");
|
||||
let _mutex = VUINPUTD_LOCK.lock().unwrap();
|
||||
println!("Executing vuinputd located via cargo run");
|
||||
let mut concat_args = vec![
|
||||
"run",
|
||||
"-p",
|
||||
"vuinputd",
|
||||
"--",
|
||||
"--major",
|
||||
"120",
|
||||
"--minor",
|
||||
"414796",
|
||||
"--devname",
|
||||
"vuinput-test",
|
||||
];
|
||||
concat_args.extend(args);
|
||||
let child = unsafe {
|
||||
Command::new("cargo")
|
||||
.args([
|
||||
"run",
|
||||
"-p",
|
||||
"vuinputd",
|
||||
"--",
|
||||
"--major",
|
||||
"120",
|
||||
"--minor",
|
||||
"414796",
|
||||
"--devname",
|
||||
"vuinputd-test",
|
||||
])
|
||||
.args(concat_args)
|
||||
.pre_exec(|| {
|
||||
// Last resort, if the parent just is killed.
|
||||
libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL);
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ fn test_keyboard_in_container_with_uinput() {
|
|||
feature = "requires-bwrap"
|
||||
))]
|
||||
#[test]
|
||||
fn test_keyboard_in_container_with_vuinput() {
|
||||
run_vuinputd::ensure_vuinputd_running();
|
||||
fn test_keyboard_in_container_with_vuinput_placement_in_container() {
|
||||
let _guard: run_vuinputd::VuinputdGuard=run_vuinputd::ensure_vuinputd_running(&[]);
|
||||
|
||||
let test_keyboard = env!("CARGO_BIN_EXE_test-keyboard");
|
||||
|
||||
|
|
@ -156,3 +156,40 @@ fn test_keyboard_in_container_with_vuinput() {
|
|||
|
||||
assert!(out.status.success());
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
feature = "requires-privileges",
|
||||
feature = "requires-uinput",
|
||||
feature = "requires-bwrap"
|
||||
))]
|
||||
#[test]
|
||||
fn test_keyboard_in_container_with_vuinput_placement_on_host() {
|
||||
let _guard=run_vuinputd::ensure_vuinputd_running(&["--placement","on-host"]);
|
||||
|
||||
let test_keyboard = env!("CARGO_BIN_EXE_test-keyboard");
|
||||
|
||||
let (builder, _ipc) = bwrap::BwrapBuilder::new()
|
||||
.unshare_net()
|
||||
.ro_bind("/", "/")
|
||||
.tmpfs("/tmp")
|
||||
// dev needs to be writable for the new devices
|
||||
.dev()
|
||||
// run needs to be writable for the udev devices
|
||||
.tmpfs("/run")
|
||||
.bind("/run/vuinputd/vuinput-test/udev", "/run/udev")
|
||||
.dev_bind("/dev/vuinput-test", "/dev/uinput")
|
||||
.die_with_parent()
|
||||
.with_ipc()
|
||||
.expect("failed to create IPC");
|
||||
|
||||
let out = builder
|
||||
.command(test_keyboard, &["--ipc"])
|
||||
.run()
|
||||
.unwrap_or_else(|e| panic!("failed to run bwrap!: {e}"));
|
||||
|
||||
println!("Output");
|
||||
println!("stdout: {}", str::from_utf8(&out.stdout).unwrap());
|
||||
println!("stderr: {}", str::from_utf8(&out.stderr).unwrap());
|
||||
|
||||
assert!(out.status.success());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use std::{process::Command, time::Duration};
|
||||
use std::time::Duration;
|
||||
use vuinputd_tests::podman;
|
||||
use vuinputd_tests::run_vuinputd;
|
||||
|
||||
|
|
@ -66,9 +66,9 @@ fn test_podman_ipc() {
|
|||
))]
|
||||
#[test]
|
||||
fn test_keyboard_in_container_with_vuinput() {
|
||||
run_vuinputd::ensure_vuinputd_running();
|
||||
let _guard=run_vuinputd::ensure_vuinputd_running(&[]);
|
||||
|
||||
let (builder, ipc) = podman::PodmanBuilder::new()
|
||||
let (builder, _ipc) = podman::PodmanBuilder::new()
|
||||
.run_cmd()
|
||||
.rm()
|
||||
.with_ipc()
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ impl EmitUdevEventJob {
|
|||
|
||||
impl Job for EmitUdevEventJob {
|
||||
fn desc(&self) -> &str {
|
||||
"emit udev event into container"
|
||||
"emit udev event"
|
||||
}
|
||||
|
||||
fn execute_after_cancellation(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ impl MknodDeviceJob {
|
|||
|
||||
impl Job for MknodDeviceJob {
|
||||
fn desc(&self) -> &str {
|
||||
"mknod input device in container"
|
||||
"mknod input device"
|
||||
}
|
||||
|
||||
fn execute_after_cancellation(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl RemoveDeviceJob {
|
|||
|
||||
impl Job for RemoveDeviceJob {
|
||||
fn desc(&self) -> &str {
|
||||
"Remove input device from container"
|
||||
"Remove input device"
|
||||
}
|
||||
|
||||
fn execute_after_cancellation(&self) -> bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue