Skip to content

Commit 5452cbc

Browse files
acatangiualxiord
authored andcommitted
vmm: add error conversion unit tests
Signed-off-by: Adrian Catangiu <[email protected]>
1 parent 6ecd60a commit 5452cbc

File tree

3 files changed

+267
-4
lines changed

3 files changed

+267
-4
lines changed

api_server/src/request/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl GenerateHyperResponse for VmmActionError {
6666
fn generate_response(&self) -> hyper::Response {
6767
use self::ErrorKind::*;
6868

69-
let status_code = match self.get_kind() {
69+
let status_code = match self.kind() {
7070
User => StatusCode::BadRequest,
7171
Internal => StatusCode::InternalServerError,
7272
};

tests/integration_tests/build/test_coverage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import host_tools.cargo_build as host # pylint: disable=import-error
2020

21-
COVERAGE_TARGET_PCT = 83.7
21+
COVERAGE_TARGET_PCT = 83.9
2222
COVERAGE_MAX_DELTA = 0.01
2323

2424
CARGO_KCOV_REL_PATH = os.path.join(host.CARGO_BUILD_REL_PATH, 'kcov')

vmm/src/lib.rs

Lines changed: 265 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ impl std::fmt::Debug for Error {
173173
}
174174

175175
/// Types of errors associated with vmm actions.
176-
#[derive(Debug)]
176+
#[derive(Clone, Debug)]
177177
pub enum ErrorKind {
178178
/// User Errors describe bad configuration (user input).
179179
User,
@@ -182,6 +182,16 @@ pub enum ErrorKind {
182182
Internal,
183183
}
184184

185+
impl PartialEq for ErrorKind {
186+
fn eq(&self, other: &ErrorKind) -> bool {
187+
match (self, other) {
188+
(&ErrorKind::User, &ErrorKind::User) => true,
189+
(&ErrorKind::Internal, &ErrorKind::Internal) => true,
190+
_ => false,
191+
}
192+
}
193+
}
194+
185195
/// Wrapper for all errors associated with VMM actions.
186196
#[derive(Debug)]
187197
pub enum VmmActionError {
@@ -316,7 +326,7 @@ impl std::convert::From<StartMicrovmError> for VmmActionError {
316326

317327
impl VmmActionError {
318328
/// Returns the error type.
319-
pub fn get_kind(&self) -> &ErrorKind {
329+
pub fn kind(&self) -> &ErrorKind {
320330
use self::VmmActionError::*;
321331

322332
match *self {
@@ -3203,6 +3213,259 @@ mod tests {
32033213
stdin_handle.lock().set_canon_mode().unwrap();
32043214
}
32053215

3216+
// Helper function to get ErrorKind of error.
3217+
fn error_kind<T: std::convert::Into<VmmActionError>>(err: T) -> ErrorKind {
3218+
let err: VmmActionError = err.into();
3219+
err.kind().clone()
3220+
}
3221+
3222+
#[test]
3223+
fn test_error_conversion() {
3224+
// Test `DriveError` conversion
3225+
assert_eq!(
3226+
error_kind(DriveError::CannotOpenBlockDevice),
3227+
ErrorKind::User
3228+
);
3229+
assert_eq!(
3230+
error_kind(DriveError::InvalidBlockDevicePath),
3231+
ErrorKind::User
3232+
);
3233+
assert_eq!(
3234+
error_kind(DriveError::BlockDevicePathAlreadyExists),
3235+
ErrorKind::User
3236+
);
3237+
assert_eq!(
3238+
error_kind(DriveError::BlockDeviceUpdateFailed),
3239+
ErrorKind::User
3240+
);
3241+
assert_eq!(
3242+
error_kind(DriveError::OperationNotAllowedPreBoot),
3243+
ErrorKind::User
3244+
);
3245+
assert_eq!(
3246+
error_kind(DriveError::UpdateNotAllowedPostBoot),
3247+
ErrorKind::User
3248+
);
3249+
assert_eq!(
3250+
error_kind(DriveError::RootBlockDeviceAlreadyAdded),
3251+
ErrorKind::User
3252+
);
3253+
3254+
// Test `VmConfigError` conversion
3255+
assert_eq!(error_kind(VmConfigError::InvalidVcpuCount), ErrorKind::User);
3256+
assert_eq!(
3257+
error_kind(VmConfigError::InvalidMemorySize),
3258+
ErrorKind::User
3259+
);
3260+
assert_eq!(
3261+
error_kind(VmConfigError::UpdateNotAllowedPostBoot),
3262+
ErrorKind::User
3263+
);
3264+
3265+
// Test `NetworkInterfaceError` conversion
3266+
assert_eq!(
3267+
error_kind(NetworkInterfaceError::GuestMacAddressInUse(String::new())),
3268+
ErrorKind::User
3269+
);
3270+
assert_eq!(
3271+
error_kind(NetworkInterfaceError::EpollHandlerNotFound(
3272+
Error::DeviceEventHandlerNotFound
3273+
)),
3274+
ErrorKind::Internal
3275+
);
3276+
assert_eq!(
3277+
error_kind(NetworkInterfaceError::HostDeviceNameInUse(String::new())),
3278+
ErrorKind::User
3279+
);
3280+
assert_eq!(
3281+
error_kind(NetworkInterfaceError::DeviceIdNotFound),
3282+
ErrorKind::User
3283+
);
3284+
// NetworkInterfaceError::OpenTap can be of multiple kinds.
3285+
{
3286+
assert_eq!(
3287+
error_kind(NetworkInterfaceError::OpenTap(TapError::OpenTun(
3288+
io::Error::from_raw_os_error(0)
3289+
))),
3290+
ErrorKind::User
3291+
);
3292+
assert_eq!(
3293+
error_kind(NetworkInterfaceError::OpenTap(TapError::CreateTap(
3294+
io::Error::from_raw_os_error(0)
3295+
))),
3296+
ErrorKind::User
3297+
);
3298+
assert_eq!(
3299+
error_kind(NetworkInterfaceError::OpenTap(TapError::IoctlError(
3300+
io::Error::from_raw_os_error(0)
3301+
))),
3302+
ErrorKind::Internal
3303+
);
3304+
assert_eq!(
3305+
error_kind(NetworkInterfaceError::OpenTap(TapError::NetUtil(
3306+
net_util::Error::CreateSocket(io::Error::from_raw_os_error(0))
3307+
))),
3308+
ErrorKind::Internal
3309+
);
3310+
assert_eq!(
3311+
error_kind(NetworkInterfaceError::OpenTap(TapError::InvalidIfname)),
3312+
ErrorKind::User
3313+
);
3314+
}
3315+
assert_eq!(
3316+
error_kind(NetworkInterfaceError::RateLimiterUpdateFailed(
3317+
devices::Error::FailedReadTap
3318+
)),
3319+
ErrorKind::Internal
3320+
);
3321+
assert_eq!(
3322+
error_kind(NetworkInterfaceError::UpdateNotAllowedPostBoot),
3323+
ErrorKind::User
3324+
);
3325+
3326+
// Test `StartMicrovmError` conversion
3327+
#[cfg(target_arch = "x86_64")]
3328+
assert_eq!(
3329+
error_kind(StartMicrovmError::ConfigureSystem(
3330+
arch::Error::X86_64Setup(arch::x86_64::Error::ZeroPageSetup)
3331+
)),
3332+
ErrorKind::Internal
3333+
);
3334+
assert_eq!(
3335+
error_kind(StartMicrovmError::ConfigureVm(
3336+
vstate::Error::NotEnoughMemorySlots
3337+
)),
3338+
ErrorKind::Internal
3339+
);
3340+
assert_eq!(
3341+
error_kind(StartMicrovmError::CreateBlockDevice(
3342+
io::Error::from_raw_os_error(0)
3343+
)),
3344+
ErrorKind::User
3345+
);
3346+
assert_eq!(
3347+
error_kind(StartMicrovmError::CreateNetDevice(
3348+
devices::virtio::Error::TapOpen(TapError::CreateTap(io::Error::from_raw_os_error(
3349+
0
3350+
)))
3351+
)),
3352+
ErrorKind::User
3353+
);
3354+
assert_eq!(
3355+
error_kind(StartMicrovmError::CreateRateLimiter(
3356+
io::Error::from_raw_os_error(0)
3357+
)),
3358+
ErrorKind::Internal
3359+
);
3360+
#[cfg(feature = "vsock")]
3361+
assert_eq!(
3362+
error_kind(StartMicrovmError::CreateVsockDevice(
3363+
devices::virtio::vhost::Error::PollError(io::Error::from_raw_os_error(0))
3364+
)),
3365+
ErrorKind::User
3366+
);
3367+
assert_eq!(
3368+
error_kind(StartMicrovmError::DeviceManager),
3369+
ErrorKind::Internal
3370+
);
3371+
assert_eq!(error_kind(StartMicrovmError::EventFd), ErrorKind::Internal);
3372+
assert_eq!(
3373+
error_kind(StartMicrovmError::GuestMemory(
3374+
memory_model::GuestMemoryError::NoMemoryRegions
3375+
)),
3376+
ErrorKind::Internal
3377+
);
3378+
assert_eq!(
3379+
error_kind(StartMicrovmError::KernelCmdline(String::new())),
3380+
ErrorKind::User
3381+
);
3382+
assert_eq!(
3383+
error_kind(StartMicrovmError::KernelLoader(
3384+
kernel_loader::Error::CommandLineOverflow
3385+
)),
3386+
ErrorKind::User
3387+
);
3388+
assert_eq!(
3389+
error_kind(StartMicrovmError::LegacyIOBus(
3390+
device_manager::legacy::Error::EventFd(io::Error::from_raw_os_error(0))
3391+
)),
3392+
ErrorKind::Internal
3393+
);
3394+
assert_eq!(
3395+
error_kind(StartMicrovmError::LoadCommandline(
3396+
kernel_loader::Error::CommandLineOverflow
3397+
)),
3398+
ErrorKind::User
3399+
);
3400+
assert_eq!(
3401+
error_kind(StartMicrovmError::MicroVMAlreadyRunning),
3402+
ErrorKind::User
3403+
);
3404+
assert_eq!(
3405+
error_kind(StartMicrovmError::MissingKernelConfig),
3406+
ErrorKind::User
3407+
);
3408+
assert_eq!(
3409+
error_kind(StartMicrovmError::NetDeviceNotConfigured),
3410+
ErrorKind::User
3411+
);
3412+
assert_eq!(
3413+
error_kind(StartMicrovmError::OpenBlockDevice(
3414+
io::Error::from_raw_os_error(0)
3415+
)),
3416+
ErrorKind::User
3417+
);
3418+
assert_eq!(
3419+
error_kind(StartMicrovmError::RegisterBlockDevice(
3420+
device_manager::mmio::Error::IrqsExhausted
3421+
)),
3422+
ErrorKind::Internal
3423+
);
3424+
assert_eq!(
3425+
error_kind(StartMicrovmError::RegisterEvent),
3426+
ErrorKind::Internal
3427+
);
3428+
assert_eq!(
3429+
error_kind(StartMicrovmError::RegisterNetDevice(
3430+
device_manager::mmio::Error::IrqsExhausted
3431+
)),
3432+
ErrorKind::Internal
3433+
);
3434+
#[cfg(feature = "vsock")]
3435+
assert_eq!(
3436+
error_kind(StartMicrovmError::RegisterVsockDevice(
3437+
device_manager::mmio::Error::IrqsExhausted
3438+
)),
3439+
ErrorKind::Internal
3440+
);
3441+
assert_eq!(
3442+
error_kind(StartMicrovmError::SeccompFilters(
3443+
seccomp::Error::InvalidArgumentNumber
3444+
)),
3445+
ErrorKind::Internal
3446+
);
3447+
assert_eq!(
3448+
error_kind(StartMicrovmError::Vcpu(vstate::Error::VcpuUnhandledKvmExit)),
3449+
ErrorKind::Internal
3450+
);
3451+
assert_eq!(
3452+
error_kind(StartMicrovmError::VcpuConfigure(
3453+
vstate::Error::SetSupportedCpusFailed(io::Error::from_raw_os_error(0))
3454+
)),
3455+
ErrorKind::Internal
3456+
);
3457+
assert_eq!(
3458+
error_kind(StartMicrovmError::VcpusNotConfigured),
3459+
ErrorKind::User
3460+
);
3461+
assert_eq!(
3462+
error_kind(StartMicrovmError::VcpuSpawn(io::Error::from_raw_os_error(
3463+
0
3464+
))),
3465+
ErrorKind::Internal
3466+
);
3467+
}
3468+
32063469
#[test]
32073470
fn test_error_messages() {
32083471
// Enum `Error`

0 commit comments

Comments
 (0)