mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-01 09:42:45 +00:00
runtime-rs: Add test for container devices with CDI.
Fixes #10145 Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
parent
63b25e8cb0
commit
b8ba346e98
@ -42,7 +42,7 @@ pub struct StringUser {
|
|||||||
pub additional_gids: Vec<String>,
|
pub additional_gids: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default)]
|
#[derive(PartialEq, Clone, Debug, Default)]
|
||||||
pub struct Device {
|
pub struct Device {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub field_type: String,
|
pub field_type: String,
|
||||||
|
@ -106,3 +106,370 @@ pub fn annotate_container_devices(
|
|||||||
|
|
||||||
Ok(devices_agent)
|
Ok(devices_agent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use crate::cdi_devices::DeviceInfo;
|
||||||
|
use agent::types::Device;
|
||||||
|
use oci_spec::runtime::SpecBuilder;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sort_devices_by_guest_pcipath() {
|
||||||
|
let mut devices = vec![
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0xffff".to_string(),
|
||||||
|
class_id: "0x030x".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device3"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
options: vec!["pci_host_path03=BB:DD03.F03".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0xffff".to_string(),
|
||||||
|
class_id: "0x030x".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device1"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
options: vec!["pci_host_path01=BB:DD01.F01".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0xffff".to_string(),
|
||||||
|
class_id: "0x030x".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device2"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
options: vec!["pci_host_path02=BB:DD02.F02".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
sort_devices_by_guest_pcipath(&mut devices);
|
||||||
|
|
||||||
|
let expected_devices_order = vec![
|
||||||
|
"/dev/device1".to_string(),
|
||||||
|
"/dev/device2".to_string(),
|
||||||
|
"/dev/device3".to_string(),
|
||||||
|
];
|
||||||
|
let actual_devices_order: Vec<String> = devices
|
||||||
|
.iter()
|
||||||
|
.map(|cd| {
|
||||||
|
cd.device_info
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.host_path
|
||||||
|
.display()
|
||||||
|
.to_string()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(actual_devices_order, expected_devices_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sort_devices_with_empty_options() {
|
||||||
|
let mut devices = vec![
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0xffff".to_string(),
|
||||||
|
class_id: "0x030x".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device1"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
options: vec![], // empty
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0xffff".to_string(),
|
||||||
|
class_id: "0x030x".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device2"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
options: vec!["pci_host_path02=BB:DD02.F02".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
sort_devices_by_guest_pcipath(&mut devices);
|
||||||
|
|
||||||
|
// As the first device has no options, ignore it.
|
||||||
|
let expected_devices_order = vec!["BB:DD02.F02".to_string()];
|
||||||
|
|
||||||
|
let actual_devices_order: Vec<String> = devices
|
||||||
|
.iter()
|
||||||
|
.filter_map(|d| d.device.options.first())
|
||||||
|
.map(|option| option.split('=').nth(1).unwrap_or("").to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(actual_devices_order, expected_devices_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_annotate_container_devices() {
|
||||||
|
let devices = vec![
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: None,
|
||||||
|
device: Device {
|
||||||
|
id: "test0000x".to_string(),
|
||||||
|
container_path: "/dev/xvdx".to_string(),
|
||||||
|
field_type: "virtio-blk".to_string(),
|
||||||
|
vm_path: "/dev/vdx".to_string(),
|
||||||
|
options: vec![],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0x1002".to_string(),
|
||||||
|
class_id: "0x0302".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device2"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
container_path: "/dev/device2".to_string(),
|
||||||
|
options: vec!["pci_host_path02=BB:DD02.F02".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0x1002".to_string(),
|
||||||
|
class_id: "0x0302".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device3"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
container_path: "/dev/device3".to_string(),
|
||||||
|
options: vec!["pci_host_path03=BB:DD03.F03".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0x1002".to_string(),
|
||||||
|
class_id: "0x0302".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device1"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
container_path: "/dev/device1".to_string(),
|
||||||
|
options: vec!["pci_host_path01=BB:DD01.F01".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: None,
|
||||||
|
device: Device {
|
||||||
|
id: "test0000yx".to_string(),
|
||||||
|
container_path: "/dev/xvdyx".to_string(),
|
||||||
|
field_type: "virtio-blk".to_string(),
|
||||||
|
vm_path: "/dev/vdyx".to_string(),
|
||||||
|
options: vec![],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let annotations = HashMap::new();
|
||||||
|
let mut spec = SpecBuilder::default()
|
||||||
|
.annotations(annotations)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// do annotate container devices
|
||||||
|
let _devices = annotate_container_devices(&mut spec, devices);
|
||||||
|
|
||||||
|
let expected_annotations: HashMap<String, String> = vec![
|
||||||
|
(
|
||||||
|
"cdi.k8s.io/vfiodevice3.0".to_owned(),
|
||||||
|
"amd.com/gpu=2".to_owned(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"cdi.k8s.io/vfiodevice1.0".to_owned(),
|
||||||
|
"amd.com/gpu=0".to_owned(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"cdi.k8s.io/vfiodevice2.0".to_owned(),
|
||||||
|
"amd.com/gpu=1".to_owned(),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(Some(expected_annotations), spec.annotations().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_annotate_container_multi_vendor_devices() {
|
||||||
|
let devices = vec![
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: None,
|
||||||
|
device: Device {
|
||||||
|
id: "test0000x".to_string(),
|
||||||
|
container_path: "/dev/xvdx".to_string(),
|
||||||
|
field_type: "virtio-blk".to_string(),
|
||||||
|
vm_path: "/dev/vdx".to_string(),
|
||||||
|
options: vec![],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0x10de".to_string(),
|
||||||
|
class_id: "0x0302".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device2"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
container_path: "/dev/device2".to_string(),
|
||||||
|
options: vec!["pci_host_path02=BB:DD02.F02".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0x10de".to_string(),
|
||||||
|
class_id: "0x0302".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device3"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
container_path: "/dev/device3".to_string(),
|
||||||
|
options: vec!["pci_host_path03=BB:DD03.F03".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0x8086".to_string(),
|
||||||
|
class_id: "0x0302".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device1"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
container_path: "/dev/device1".to_string(),
|
||||||
|
options: vec!["pci_host_path01=BB:DD01.F01".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: Some(DeviceInfo {
|
||||||
|
vendor_id: "0x8086".to_string(),
|
||||||
|
class_id: "0x0302".to_string(),
|
||||||
|
host_path: PathBuf::from("/dev/device4"),
|
||||||
|
}),
|
||||||
|
device: Device {
|
||||||
|
container_path: "/dev/device4".to_string(),
|
||||||
|
options: vec!["pci_host_path04=BB:DD01.F04".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: None,
|
||||||
|
device: Device {
|
||||||
|
id: "test0000yx".to_string(),
|
||||||
|
container_path: "/dev/xvdyx".to_string(),
|
||||||
|
field_type: "virtio-blk".to_string(),
|
||||||
|
vm_path: "/dev/vdyx".to_string(),
|
||||||
|
options: vec![],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let annotations = HashMap::new();
|
||||||
|
let mut spec = SpecBuilder::default()
|
||||||
|
.annotations(annotations)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let _devices = annotate_container_devices(&mut spec, devices);
|
||||||
|
|
||||||
|
let expected_annotations: HashMap<String, String> = vec![
|
||||||
|
(
|
||||||
|
"cdi.k8s.io/vfiodevice1.0".to_owned(),
|
||||||
|
"intel.com/gpu=0".to_owned(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"cdi.k8s.io/vfiodevice2.0".to_owned(),
|
||||||
|
"nvidia.com/gpu=0".to_owned(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"cdi.k8s.io/vfiodevice3.0".to_owned(),
|
||||||
|
"nvidia.com/gpu=1".to_owned(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"cdi.k8s.io/vfiodevice4.0".to_owned(),
|
||||||
|
"intel.com/gpu=1".to_owned(),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(Some(expected_annotations), spec.annotations().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_annotate_container_without_vfio_devices() {
|
||||||
|
let devices = vec![
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: None,
|
||||||
|
device: Device {
|
||||||
|
id: "test0000x".to_string(),
|
||||||
|
container_path: "/dev/xvdx".to_string(),
|
||||||
|
field_type: "virtio-blk".to_string(),
|
||||||
|
vm_path: "/dev/vdx".to_string(),
|
||||||
|
options: vec![],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: None,
|
||||||
|
device: Device {
|
||||||
|
id: "test0000y".to_string(),
|
||||||
|
container_path: "/dev/yvdy".to_string(),
|
||||||
|
field_type: "virtio-blk".to_string(),
|
||||||
|
vm_path: "/dev/vdy".to_string(),
|
||||||
|
options: vec![],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ContainerDevice {
|
||||||
|
device_info: None,
|
||||||
|
device: Device {
|
||||||
|
id: "test0000z".to_string(),
|
||||||
|
container_path: "/dev/zvdz".to_string(),
|
||||||
|
field_type: "virtio-blk".to_string(),
|
||||||
|
vm_path: "/dev/zvdz".to_string(),
|
||||||
|
options: vec![],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let annotations = HashMap::from([(
|
||||||
|
"cdi.k8s.io/vfiodeviceX".to_owned(),
|
||||||
|
"katacontainer.com/device=Y".to_owned(),
|
||||||
|
)]);
|
||||||
|
let mut spec = SpecBuilder::default()
|
||||||
|
.annotations(annotations)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// do annotate container devices
|
||||||
|
let annotated_devices = annotate_container_devices(&mut spec, devices.clone()).unwrap();
|
||||||
|
|
||||||
|
let actual_devices = devices
|
||||||
|
.iter()
|
||||||
|
.map(|d| d.device.clone())
|
||||||
|
.collect::<Vec<Device>>();
|
||||||
|
let expected_annotations: HashMap<String, String> = HashMap::from([(
|
||||||
|
"cdi.k8s.io/vfiodeviceX".to_owned(),
|
||||||
|
"katacontainer.com/device=Y".to_owned(),
|
||||||
|
)]);
|
||||||
|
|
||||||
|
assert_eq!(Some(expected_annotations), spec.annotations().clone());
|
||||||
|
assert_eq!(annotated_devices, actual_devices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user