Skip to content

Commit 5c9c052

Browse files
committed
CA-271857: Add a (failing) test for this issue
Signed-off-by: Jon Ludlam <[email protected]>
1 parent a40a75e commit 5c9c052

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

ocaml/xapi/test_common.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ let make_localhost ~__context ?(features=Features.all_features) () =
4444
linux_verstring = "something";
4545
hostname = "localhost";
4646
uuid = Xapi_inventory.lookup Xapi_inventory._installation_uuid;
47-
dom0_uuid = "dom0-uuid";
47+
dom0_uuid = Xapi_inventory.lookup Xapi_inventory._control_domain_uuid;
4848
oem_manufacturer = None;
4949
oem_model = None;
5050
oem_build_number = None;
@@ -73,6 +73,7 @@ let make_localhost ~__context ?(features=Features.all_features) () =
7373
(** Make a simple in-memory database containing a single host and dom0 VM record. *)
7474
let make_test_database ?(conn=Mock.Database.conn) ?(reuse=false) ?features () =
7575
let __context = Mock.make_context_with_new_db ~conn ~reuse "mock" in
76+
Helpers.domain_zero_ref_cache := None;
7677
make_localhost ~__context ?features ();
7778
__context
7879

ocaml/xapi/test_xapi_xenops.ml

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ let unsetup_simulator () =
5353
Xcp_client.use_switch := false;
5454
end
5555

56-
let test_xapi_restart () =
56+
57+
let test_xapi_restart_inner () =
58+
Debug.log_to_stdout ();
5759
let __context = make_test_database () in
5860
setup_simulator ();
59-
Debug.log_to_stdout ();
6061
Helpers.test_mode := true;
6162
let open Xenops_interface in
6263
let open Xapi_xenops_queue in
@@ -72,11 +73,14 @@ let test_xapi_restart () =
7273
| Api_errors.Server_error (x,[]) when x = Api_errors.task_cancelled -> ()
7374
| e -> raise e) () in
7475
(cancel,th) in
76+
let vm0 = Helpers.get_domain_zero ~__context in
7577
let vm1 = make_vm ~__context ~name_label:"vm1" () in
7678
let vm2 = make_vm ~__context ~name_label:"vm2" () in
7779
let vm3 = make_vm ~__context ~name_label:"vm3" () in
7880
let vm4 = make_vm ~__context ~name_label:"vm4" () in
7981
let vm5 = make_vm ~__context ~name_label:"vm5" () in
82+
let vm6 = make_vm ~__context ~name_label:"vm6" () in
83+
let vm7 = make_vm ~__context ~name_label:"vm7" () in
8084
let host2 = make_host ~__context ~name_label:"host2" ~hostname:"localhost2" () in
8185
let flags = [
8286
Xapi_globs.cpu_info_vendor_key, "AuthenticAMD";
@@ -86,39 +90,69 @@ let test_xapi_restart () =
8690
Db.VM.set_last_boot_CPU_flags ~__context ~self:vm ~value:flags;
8791
Db.VM.add_to_other_config ~__context ~self:vm ~key:"xenops" ~value:"simulator"
8892
in
89-
List.iter add_flags [vm1; vm2; vm3; vm4; vm5];
93+
List.iter add_flags [vm1; vm2; vm3; vm4; vm5; vm6; vm7];
9094

9195
try
92-
(* Start all 4 VMs *)
96+
(* Domain zero is running but not in xenopsd *)
97+
Db.VM.set_is_control_domain ~__context ~self:vm0 ~value:true;
98+
Db.VM.set_resident_on ~__context ~self:vm0 ~value:(Helpers.get_localhost ~__context);
99+
Db.VM.set_power_state ~__context ~self:vm0 ~value:(`Running);
100+
101+
(* Start all 7 VMs *)
93102
Xapi_xenops.start ~__context ~self:vm1 false false;
94103
Xapi_xenops.start ~__context ~self:vm2 false false;
95104
Xapi_xenops.start ~__context ~self:vm3 false false;
96105
Xapi_xenops.start ~__context ~self:vm4 false false;
97106
Xapi_xenops.start ~__context ~self:vm5 false false;
107+
Xapi_xenops.start ~__context ~self:vm6 false false;
108+
Xapi_xenops.start ~__context ~self:vm7 false false;
109+
110+
(* vm6 is a ntnx CVM *)
111+
Db.VM.set_is_control_domain ~__context ~self:vm6 ~value:true;
98112

99-
(* Kill the event thread *)
113+
(* Kill the event thread *)
100114
cancel := true;
101115
Client.UPDATES.inject_barrier "dbg" (Xapi_xenops.id_of_vm ~__context ~self:vm1) 0;
102116
let before = Unix.gettimeofday () in
103117
Thread.join th;
104118
let after = Unix.gettimeofday () in
105119
debug "Elapsed time for thread death: %f\n%!" (after -. before);
106-
(* Check they're running *)
120+
(* Check they're running *)
107121
let is_resident vm =
108122
Db.VM.get_resident_on ~__context ~self:vm = Helpers.get_localhost ~__context
109123
in
110-
assert_bool "Running here" (is_resident vm1);
111-
assert_bool "Running here" (is_resident vm2);
112-
assert_bool "Running here" (is_resident vm3);
113-
assert_bool "Running here" (is_resident vm4);
114-
assert_bool "Running here" (is_resident vm5);
124+
let is_running_in_xenopsd vm =
125+
try
126+
let (_,stat) = Client.VM.stat "dbg" (Xapi_xenops.id_of_vm ~__context ~self:vm) in
127+
stat.Vm.power_state = Running
128+
with (Does_not_exist _) ->
129+
false
130+
in
131+
let assert_correct_state (vm, running) =
132+
let name = Db.VM.get_name_label ~__context ~self:vm in
133+
assert_bool
134+
(Printf.sprintf "State is correct in xapi (%s)" name)
135+
(running = (is_resident vm));
136+
assert_bool
137+
(Printf.sprintf "State is correct in xenopsd (%s)" name)
138+
(running = (is_running_in_xenopsd vm))
139+
in
115140

116-
(* Simulate various out-of-band VM operations by resetting the xapi state to halted, and stop one that was running *)
141+
List.iter (fun vm -> assert_correct_state (vm, true)) [vm1; vm2; vm3; vm4; vm5; vm6; vm7];
142+
143+
(* Simulate various out-of-band VM operations by resetting the xapi state to halted, and stop one that was running *)
117144
Db.VM.set_resident_on ~__context ~self:vm1 ~value:(Ref.null);
145+
Db.VM.set_name_label ~__context ~self:vm1 ~value:"vm1: resident-on set to null";
118146
Xapi_vm_lifecycle.force_state_reset ~__context ~self:vm2 ~value:`Halted;
147+
Db.VM.set_name_label ~__context ~self:vm2 ~value:"vm2: force_state_reset to halted";
119148
ignore(Client.VM.shutdown "dbg" (Xapi_xenops.id_of_vm ~__context ~self:vm3) None);
149+
Db.VM.set_name_label ~__context ~self:vm3 ~value:"vm3: shutdown in xenopsd while xapi was off";
120150
Db.VM.set_resident_on ~__context ~self:vm4 ~value:host2;
151+
Db.VM.set_name_label ~__context ~self:vm4 ~value:"vm4: xapi thinks it's running somewhere else";
121152
Db.VM.destroy ~__context ~self:vm5;
153+
Db.VM.set_name_label ~__context ~self:vm6 ~value:"vm6: is_control_domain=true";
154+
ignore(Client.VM.shutdown "dbg" (Xapi_xenops.id_of_vm ~__context ~self:vm7) None);
155+
Db.VM.set_name_label ~__context ~self:vm7 ~value:"vm7: shutdown in xenopsd while xapi was off (and is_control_domain)";
122156

123157
(* Now run the on_xapi_restart logic *)
124158
debug "Resync resident on";
@@ -144,17 +178,18 @@ let test_xapi_restart () =
144178
debug "Elapsed time for thread death: %f\n%!" (after -. before);
145179

146180
(* And check that the right thing has happened *)
147-
assert_bool "Running here" (is_resident vm1);
148-
assert_bool "Running here" (is_resident vm2);
149-
assert_bool "Not running here" (not (is_resident vm3));
150-
assert_bool "Not running here" (not (is_resident vm4));
181+
List.iter assert_correct_state
182+
[vm1, true; vm2, true; vm3, false; vm4, false; vm6, true; vm7, false];
151183

152-
unsetup_simulator ()
153184
with e ->
154185
Printf.printf "Caught: %s\n" (Printexc.to_string e);
155186
Printf.printf "Backtrace: %s\n%!" (Backtrace.to_string_hum (Backtrace.get e));
156-
raise e
187+
raise e
157188

189+
let test_xapi_restart () =
190+
Stdext.Pervasiveext.finally
191+
test_xapi_restart_inner
192+
unsetup_simulator
158193

159194
let test_nested_virt_licensing () =
160195
let __context = make_test_database () in

0 commit comments

Comments
 (0)