@@ -386,31 +386,8 @@ mod tests {
386386 use std:: fmt:: { Debug , Formatter } ;
387387 use test_case:: test_case;
388388
389- #[ test]
390- fn test_fail_to_create_kvm_driver_if_kvmi_init_returns_error ( ) {
391- let mut kvmi_mock = MockKVMi :: default ( ) ;
392- kvmi_mock. expect_init ( ) . returning ( |_| {
393- Err ( std:: io:: Error :: new (
394- std:: io:: ErrorKind :: Other ,
395- "something went wrong" ,
396- ) )
397- } ) ;
398-
399- let result = Kvm :: new (
400- "some_vm" ,
401- kvmi_mock,
402- Some ( DriverInitParam :: KVMiSocket ( "/tmp/introspector" . to_string ( ) ) ) ,
403- ) ;
404-
405- assert ! ( result. is_err( ) , "Expected error, got ok instead!" ) ;
406- }
407-
408- #[ test_case( 1 ; "single vcpu" ) ]
409- #[ test_case( 2 ; "two vcpus" ) ]
410- #[ test_case( 16 ; "sixteen vcpus" ) ]
411- fn test_create_kvm_driver_if_guest_domain_is_valid ( vcpu_count : u32 ) {
412- let mut kvmi_mock = MockKVMi :: default ( ) ;
413- kvmi_mock. expect_init ( ) . returning ( |_| Ok ( ( ) ) ) ;
389+ fn setup_mock ( kvmi_mock : & mut MockKVMi , vcpu_count : u32 ) {
390+ kvmi_mock. expect_init ( ) . times ( 1 ) . returning ( |_| Ok ( ( ) ) ) ;
414391 kvmi_mock
415392 . expect_get_vcpu_count ( )
416393 . returning ( move || Ok ( vcpu_count) ) ;
@@ -488,16 +465,166 @@ mod tests {
488465 . times ( 1 )
489466 . returning ( |_, _, _| Ok ( ( ) ) ) ;
490467 }
468+ }
469+
470+ #[ test]
471+ fn test_fail_to_create_kvm_driver_if_kvmi_init_returns_error ( ) {
472+ let mut kvmi_mock = MockKVMi :: default ( ) ;
473+ kvmi_mock. expect_init ( ) . returning ( |_| {
474+ Err ( std:: io:: Error :: new (
475+ std:: io:: ErrorKind :: Other ,
476+ "something went wrong" ,
477+ ) )
478+ } ) ;
491479
492480 let result = Kvm :: new (
493481 "some_vm" ,
494482 kvmi_mock,
495483 Some ( DriverInitParam :: KVMiSocket ( "/tmp/introspector" . to_string ( ) ) ) ,
496484 ) ;
497485
486+ assert ! ( result. is_err( ) , "Expected error, got ok instead!" ) ;
487+ }
488+
489+ #[ test_case( 1 ; "single vcpu" ) ]
490+ #[ test_case( 2 ; "two vcpus" ) ]
491+ #[ test_case( 16 ; "sixteen vcpus" ) ]
492+ fn test_create_kvm_driver_if_guest_domain_is_valid ( vcpu_count : u32 ) {
493+ let mut kvmi_mock = MockKVMi :: default ( ) ;
494+ setup_mock ( & mut kvmi_mock, vcpu_count) ;
495+ let result = Kvm :: new (
496+ "some_vm" ,
497+ kvmi_mock,
498+ Some ( DriverInitParam :: KVMiSocket ( "/tmp/introspector" . to_string ( ) ) ) ,
499+ ) ;
500+
501+ assert ! ( result. is_ok( ) , "Expected ok, got error instead!" ) ;
502+ }
503+
504+ #[ test_case( 1 ; "single vcpu" ) ]
505+ fn test_pause_vcpu ( vcpu_count : u32 ) {
506+ let mut kvmi_mock = MockKVMi :: default ( ) ;
507+ setup_mock ( & mut kvmi_mock, vcpu_count) ;
508+ kvmi_mock. expect_pause ( ) . times ( 1 ) . returning ( || Ok ( ( ) ) ) ;
509+ let mut kvm = Kvm :: new (
510+ "some_vm" ,
511+ kvmi_mock,
512+ Some ( DriverInitParam :: KVMiSocket ( "/tmp/introspector" . to_string ( ) ) ) ,
513+ )
514+ . expect ( "Failed to create driver" ) ;
515+ let result = Kvm :: pause ( & mut kvm) ;
498516 assert ! ( result. is_ok( ) , "Expected ok, got error instead!" ) ;
499517 }
500518
519+ #[ test_case( 1 ; "single vcpu" ) ]
520+ fn test_resume_vcpu ( vcpu_count : u32 ) {
521+ let mut kvmi_mock = MockKVMi :: default ( ) ;
522+ setup_mock ( & mut kvmi_mock, vcpu_count) ;
523+ kvmi_mock
524+ . expect_wait_and_pop_event ( )
525+ . times ( 5 )
526+ . returning ( |_| {
527+ Ok ( Some ( KVMiEvent {
528+ vcpu : 0 ,
529+ ev_type : KVMiEventType :: PauseVCPU ,
530+ ffi_event : std:: ptr:: null_mut ( ) ,
531+ } ) )
532+ } ) ;
533+ kvmi_mock. expect_reply ( ) . times ( 5 ) . returning ( |_, _| Ok ( ( ) ) ) ;
534+ let mut kvm = Kvm :: new (
535+ "some_vm" ,
536+ kvmi_mock,
537+ Some ( DriverInitParam :: KVMiSocket ( "/tmp/introspector" . to_string ( ) ) ) ,
538+ )
539+ . expect ( "Failed to create driver" ) ;
540+ kvm. expect_pause_ev = 5 ;
541+ let result = Kvm :: resume ( & mut kvm) ;
542+ assert ! ( result. is_ok( ) , "Expected ok, got error instead!" ) ;
543+ }
544+
545+ #[ test_case( 1 ; "single vcpu" ) ]
546+ fn test_read_and_write_physical ( vcpu_count : u32 ) {
547+ let mut kvmi_mock = MockKVMi :: default ( ) ;
548+ setup_mock ( & mut kvmi_mock, vcpu_count) ;
549+ kvmi_mock
550+ . expect_read_physical ( )
551+ . times ( 1 )
552+ . returning ( |_, _| Ok ( ( ) ) ) ;
553+ kvmi_mock
554+ . expect_write_physical ( )
555+ . times ( 1 )
556+ . returning ( |_, _| Ok ( ( ) ) ) ;
557+ let mut kvm = Kvm :: new (
558+ "some_vm" ,
559+ kvmi_mock,
560+ Some ( DriverInitParam :: KVMiSocket ( "/tmp/introspector" . to_string ( ) ) ) ,
561+ )
562+ . expect ( "Failed to create driver" ) ;
563+ let mut paddr: u64 = 0 ;
564+ let mut buffer: [ u8 ; 4096 ] = [ 0 ; 4096 ] ;
565+ let result_read = Kvm :: read_physical ( & mut kvm, paddr, & mut buffer) ;
566+ paddr = 0 ;
567+ buffer = [ 0 ; 4096 ] ;
568+ let result_write = Kvm :: write_physical ( & mut kvm, paddr, & mut buffer) ;
569+ assert ! ( result_read. is_ok( ) , "Expected ok, got error instead!" ) ;
570+ assert ! ( result_write. is_ok( ) , "Expected ok, got error instead!" ) ;
571+ }
572+
573+ #[ test_case( 1 ; "single vcpu" ) ]
574+ fn test_toggle_intercept ( vcpu_count : u32 ) {
575+ let mut kvmi_mock = MockKVMi :: default ( ) ;
576+ kvmi_mock
577+ . expect_control_cr ( )
578+ . with ( eq ( 0 ) , function ( |x| matches ! ( x, KVMiCr :: Cr3 ) ) , eq ( true ) )
579+ . times ( 1 )
580+ . returning ( |_, _, _| Ok ( ( ) ) ) ;
581+ kvmi_mock
582+ . expect_control_msr ( )
583+ . times ( 0 )
584+ . returning ( |_, _, _| Ok ( ( ) ) ) ;
585+ kvmi_mock
586+ . expect_control_events ( )
587+ . with (
588+ eq ( 1 ) ,
589+ function ( |x| matches ! ( x, KVMiInterceptType :: Breakpoint ) ) ,
590+ eq ( true ) ,
591+ )
592+ . times ( 1 )
593+ . returning ( |_, _, _| Ok ( ( ) ) ) ;
594+ kvmi_mock
595+ . expect_control_events ( )
596+ . with (
597+ eq ( 1 ) ,
598+ function ( |x| matches ! ( x, KVMiInterceptType :: Pagefault ) ) ,
599+ eq ( true ) ,
600+ )
601+ . times ( 1 )
602+ . returning ( |_, _, _| Ok ( ( ) ) ) ;
603+
604+ setup_mock ( & mut kvmi_mock, vcpu_count) ;
605+ let mut kvm = Kvm :: new (
606+ "some_vm" ,
607+ kvmi_mock,
608+ Some ( DriverInitParam :: KVMiSocket ( "/tmp/introspector" . to_string ( ) ) ) ,
609+ )
610+ . expect ( "Failed to create driver" ) ;
611+ let mut vcpu: u16 = 0 ;
612+ let mut intercept_type = InterceptType :: Cr ( CrType :: Cr3 ) ;
613+ let mut enabled: bool = true ;
614+ let result_cr = Kvm :: toggle_intercept ( & mut kvm, vcpu, intercept_type, enabled) ;
615+ vcpu = 1 ;
616+ intercept_type = InterceptType :: Breakpoint ;
617+ enabled = true ;
618+ let result_breakpoint = Kvm :: toggle_intercept ( & mut kvm, vcpu, intercept_type, enabled) ;
619+ vcpu = 1 ;
620+ intercept_type = InterceptType :: Pagefault ;
621+ enabled = true ;
622+ let result_pagefault = Kvm :: toggle_intercept ( & mut kvm, vcpu, intercept_type, enabled) ;
623+ assert ! ( result_cr. is_ok( ) , "Expected ok, got error instead!" ) ;
624+ assert ! ( result_breakpoint. is_ok( ) , "Expected ok, got error instead!" ) ;
625+ assert ! ( result_pagefault. is_ok( ) , "Expected ok, got error instead!" ) ;
626+ }
627+
501628 mock ! {
502629 KVMi { }
503630 trait Debug {
0 commit comments