1313 *)
1414
1515open Client (* import module *)
16+ open Client (* import namespace for convenience, Client.VDI.func -> VDI.func *)
1617open Quicktest_common
18+
19+ (* Throw this exception within assertion helpers when assertion fails, instead of
20+ * actually failing the test within a helper called from the main test body *)
1721exception Test_failed of string
18- open Client (* import namespace, don't have to type Client.VDI.function each time *)
1922
20- (* Helper for test failure due to unexpected error *)
23+ (* Helper for test failure due to unexpected error
24+ * Can fail test here as this is called outside test body *)
2125let report_failure error test =
22- failed test (Printf. sprintf " %s failed: %s" test.name
23- (ExnHelper. string_of_exn error))
26+ failed test (Printf. sprintf " %s failed: %s" test.name (ExnHelper. string_of_exn error))
27+
28+ let get_cbt_status ~session_id ~vDI = VDI. get_cbt_enabled ~session_id ~rpc: ! rpc ~self: vDI
2429
25- (* Define exception so that if test fails, exception is passed to try-with statement and fails there
26- * so that the test only fails once and doesn't erroneously assume the test never started *)
2730let test_assert ~test op ~msg =
2831 if not op then raise (Test_failed msg)
2932
30- let get_cbt_status ~session_id ~vDI = VDI. get_cbt_enabled ~session_id ~rpc: ! rpc ~self: vDI
33+ let test_compare ~test left_op right_op ~msg =
34+ let op = (left_op = right_op) in test_assert ~test op ~msg
3135
36+ (* This naming is used to identify VDIs to destroy later on *)
37+ let name_label = " qt-cbt"
3238let name_description = " VDI for CBT quicktest"
33- let make_vdi_from ~session_id ~sR = (* SR has VDI.create as allowed *)
39+ (* This is only called on VDI-create capable SRs *)
40+ let make_vdi_from ~session_id ~sR =
3441 VDI. create
3542 ~s R
3643 ~session_id
3744 ~rpc: ! rpc
38- ~name_label: " qt-cbt "
45+ ~name_label
3946 ~name_description
4047 ~_type:`user
4148 ~sharable: false
@@ -47,61 +54,106 @@ let make_vdi_from ~session_id ~sR = (* SR has VDI.create as allowed *)
4754 ~sm_config: []
4855
4956
50- (* *** Test declarations ****)
57+ (* ******************
58+ * Test declarations
59+ * ******************)
5160
52- (* Test enable/disable CBT, test cbt_enabled:false for new VDI *)
53- let enable_disable_cbt_test ~session_id ~vDI =
54- let enable_cbt_test = make_test " Testing VDI.enable/disable_CBT" 4 in
61+ (* Note that tests including expensive VDI operations (snapshot, clone, copy etc)
62+ * output debug info at most steps to justify waiting time to user *)
63+
64+ (* Test enable/disable_cbt, data_destroy, and snapshot update the necessary fields *)
65+ let vdi_data_destroy_test ~session_id ~vDI =
66+ let test = make_test " Testing VDI.{enable/disable_cbt, data_destroy, snapshot}" 4 in
5567 try
56- start enable_cbt_test;
57- test_assert ~test: enable_cbt_test
58- (not (get_cbt_status ~session_id ~v DI))
59- ~msg: " VDI.cbt_enabled field should be set to false for new VDIs" ;
68+ start test;
69+ let debug_test = debug test in
70+ debug_test " Enabling CBT on original VDI" ;
6071 VDI. enable_cbt ~session_id ~rpc: ! rpc ~self: vDI;
61- test_assert ~test: enable_cbt_test
72+ test_assert ~test
6273 (get_cbt_status ~session_id ~v DI)
6374 ~msg: " VDI.enable_cbt failed" ;
75+
76+ debug_test " Snapshotting original VDI with CBT enabled" ;
77+ let snapshot = VDI. snapshot ~session_id ~rpc: ! rpc ~vdi: vDI ~driver_params: [] in
78+ test_assert ~test
79+ (get_cbt_status ~session_id ~v DI:snapshot)
80+ ~msg: " VDI.snapshot failed, cbt_enabled field didn't carry over" ;
81+
82+ debug_test " Disabling CBT on original VDI" ;
6483 VDI. disable_cbt ~session_id ~rpc: ! rpc ~self: vDI;
65- test_assert ~test: enable_cbt_test
66- (not (get_cbt_status ~session_id ~v DI)) (* disable_cbt fails *)
67- ~msg: " VDI.disable_CBT failed" ;
68- success enable_cbt_test
84+ test_assert ~test
85+ (not (get_cbt_status ~session_id ~v DI))
86+ ~msg: " VDI.disable_cbt failed" ;
87+
88+ debug_test " Snapshotting original VDI with CBT disabled" ;
89+ let snapshot_no_cbt = VDI. snapshot ~session_id ~rpc: ! rpc ~vdi: vDI ~driver_params: [] in
90+ test_assert ~test
91+ (not (get_cbt_status ~session_id ~v DI:snapshot_no_cbt))
92+ ~msg: " VDI.snapshot failed, cbt_enabled field didn't carry over" ;
93+
94+ debug_test " Destroying snapshot VDI data" ;
95+ VDI. data_destroy ~session_id ~rpc: ! rpc ~self: snapshot;
96+ test_compare ~test
97+ (VDI. get_type ~session_id ~rpc: ! rpc ~self: snapshot)
98+ `cbt_metadata
99+ ~msg: " VDI.data_destroy failed to update VDI.type" ;
100+ test_assert ~test
101+ (get_cbt_status ~session_id ~v DI:snapshot)
102+ ~msg: " VDI snapshot cbt_enabled field erroneously set to false" ;
103+
104+ let content_id_str = " /No content: this is a cbt_metadata VDI/" in
105+ test_compare ~test
106+ (VDI. get_other_config ~session_id ~rpc: ! rpc ~self: snapshot |> List. assoc " content_id" )
107+ content_id_str
108+ ~msg: (Printf. sprintf " VDI.data_destroy failed to update VDI.content_id to \" %s\" " content_id_str);
109+
110+ success test
69111 with
70- | Test_failed msg -> failed enable_cbt_test msg
71- | e -> report_failure e enable_cbt_test
112+ | Test_failed msg -> failed test msg
113+ | e -> report_failure e test
114+
72115
116+ (* ****************
117+ * Test execution
118+ * ****************)
73119
74120(* Overall test executes individual unit tests *)
75121let test ~session_id =
76- let cbt_test = make_test " Testing changed block tracking" 2 in
122+ let cbt_test = make_test " Testing changed block tracking\n " 2 in
77123 try
78124 start cbt_test;
79125
80126 (* For each test, check the given sR is capable of the associated operations
81- * If not, skip that test, otherwise run it *)
82- let run_test_suite ~session_id ~sR ~ vDI =
127+ * Then create a VDI that will be destroyed at the end of test suite *)
128+ let run_test_suite ~session_id ~sR =
83129 let sr_ops = (SR. get_allowed_operations ~session_id ~rpc: ! rpc ~self: sR) in
84- [ (fun () -> enable_disable_cbt_test ~session_id ~v DI) ,
85- [ `vdi_enable_cbt ; `vdi_disable_cbt ]
130+ [
131+ (fun ~vDI -> vdi_data_destroy_test ~session_id ~v DI) ,
132+ [ `vdi_enable_cbt ; `vdi_disable_cbt ; `vdi_data_destroy ; `vdi_snapshot ]
86133 ]
87134 |> List. iter
88- (fun (test , list_vdi_ops ) ->
135+ (fun (test , list_vdi_ops ) ->
89136 if List. for_all (fun vdi_op -> List. mem vdi_op sr_ops) list_vdi_ops
90- then test ()
137+ then begin
138+ debug cbt_test " Creating VDI. . ." ;
139+ let vDI = make_vdi_from ~s R ~session_id in
140+ test ~v DI end
91141 else debug cbt_test " SR lacks capabilities for this test, skipping"
92142 ) in
93143
94- (* Try running test suite, definitively destroy all VDIs created, regardless of success or errors *)
95- let handle_storage_objects ~session_id ~sR ~ vDI =
144+ (* Try running test suite, clean up newly-created VDIs regardless of exceptions thrown in test suite *)
145+ let handle_storage_objects ~session_id ~sR =
96146 Xapi_stdext_pervasives.Pervasiveext. finally
97- (fun () -> run_test_suite ~session_id ~s R ~v DI) (* try running test suite *)
98- (fun () -> (* no matter what, destroy all VDIs created during test *)
147+ (fun () -> run_test_suite ~session_id ~s R) (* try running test suite *)
148+ (fun () -> (* destroy all new VDIs no matter what *)
149+ debug cbt_test " Destroying VDIs created in test. . ." ;
99150 (VDI. get_all ~session_id ~rpc: ! rpc)
100151 |> List. filter
101- (fun vdi -> (VDI. get_name_label ~session_id ~rpc: ! rpc ~self: vdi = " qt-cbt " )
152+ (fun vdi -> (VDI. get_name_label ~session_id ~rpc: ! rpc ~self: vdi = name_label )
102153 && (VDI. get_name_description ~session_id ~rpc: ! rpc ~self: vdi = name_description)
103154 )
104- |> List. iter (fun vdi -> VDI. destroy ~session_id ~rpc: ! rpc ~self: vdi)
155+ |> List. iter (fun vdi -> VDI. destroy ~session_id ~rpc: ! rpc ~self: vdi);
156+ debug cbt_test " Successfully destroyed all VDIs created for CBT test\n "
105157 ) in
106158
107159 (* Obtain list of SRs capable of creating VDIs, and run them all through test suite *)
@@ -112,9 +164,8 @@ let test ~session_id =
112164 )
113165 |> List. iter
114166 (fun sR ->
115- debug cbt_test (Printf. sprintf " Testing SR: \" %s\" " (SR. get_name_label ~session_id ~rpc: ! rpc ~self: sR));
116- let vDI = make_vdi_from ~session_id ~s R in
117- handle_storage_objects ~session_id ~s R ~v DI
167+ debug cbt_test (Printf. sprintf " Testing SR: \" %s\"\n " (SR. get_name_label ~session_id ~rpc: ! rpc ~self: sR));
168+ handle_storage_objects ~session_id ~s R
118169 );
119170
120171 (* Overall test will fail if VDI.destroy messes up, or any other exception is thrown *)
0 commit comments