Skip to content

Commit b029809

Browse files
authored
quicktest: Add delta tests for VHD/QCOW data integrity suite (#6760)
These generate two different VDIs (base and leaf), export the difference, import the diff file into the base VDI and check if it's the same as the leaf. Refactored the code somewhat to use the same helpers in different places. Tested by running the quicktest suite on a host.
2 parents 8979e27 + 4fe621c commit b029809

File tree

1 file changed

+131
-24
lines changed

1 file changed

+131
-24
lines changed

ocaml/quicktest/quicktest_vdi_ops_data_integrity.ml

Lines changed: 131 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -76,53 +76,107 @@ let check_vdi_unchanged rpc session_id ~vdi_size ~prepare_vdi ~vdi_op sr_info ()
7676
)
7777
)
7878

79+
let check_vdi_delta rpc session_id ~vdi_size ~prepare_vdi ~prepare_vdi_base
80+
~vdi_op sr_info () =
81+
let sR = sr_info.Qt.sr in
82+
Qt.VDI.with_new ~virtual_size:vdi_size rpc session_id sR
83+
@@ fun vdi_original ->
84+
Qt.VDI.with_new ~virtual_size:vdi_size rpc session_id sR @@ fun base_vdi ->
85+
prepare_vdi rpc session_id vdi_original ;
86+
let checksum_original = checksum rpc session_id vdi_original in
87+
prepare_vdi_base rpc session_id base_vdi ;
88+
89+
vdi_op rpc session_id ~vdi:vdi_original ~base_vdi ;
90+
let checksum_copy = checksum rpc session_id base_vdi in
91+
if checksum_copy <> checksum_original then
92+
failwith
93+
(Printf.sprintf
94+
"New VDI (checksum: %s) has different data than original (checksum: \
95+
%s)."
96+
checksum_copy checksum_original
97+
)
98+
7999
let copy_vdi rpc session_id sr vdi =
80100
Client.Client.VDI.copy ~rpc ~session_id ~vdi ~base_vdi:API.Ref.null
81101
~into_vdi:API.Ref.null ~sr
82102

83-
let export_import_vdi rpc session_id ~exportformat sR vdi =
84-
let vdi_uuid = Client.Client.VDI.get_uuid ~rpc ~session_id ~self:vdi in
103+
let export_vdi_to_file ~rpc ~session_id ~exportformat ?base_vdi ~vdi () =
104+
let get_uuid vdi = Client.Client.VDI.get_uuid ~rpc ~session_id ~self:vdi in
105+
let vdi_uuid = get_uuid vdi in
106+
let base_vdi_uuid = Option.map get_uuid base_vdi in
85107
let file = "/tmp/quicktest_export_" ^ vdi_uuid in
108+
Qt.cli_cmd
109+
([
110+
"vdi-export"
111+
; "uuid=" ^ vdi_uuid
112+
; "filename=" ^ file
113+
; "format=" ^ exportformat
114+
]
115+
@ match base_vdi_uuid with None -> [] | Some x -> ["base=" ^ x]
116+
)
117+
|> ignore ;
118+
file
119+
120+
let create_new_vdi ~rpc ~session_id ~sR ~vdi =
121+
let virtual_size =
122+
Client.Client.VDI.get_virtual_size ~rpc ~session_id ~self:vdi
123+
in
124+
let new_vdi =
125+
Client.Client.VDI.create ~rpc ~session_id ~name_label:""
126+
~name_description:"" ~sR ~virtual_size ~_type:`user ~sharable:false
127+
~read_only:false ~other_config:[] ~xenstore_data:[] ~sm_config:[] ~tags:[]
128+
in
129+
let new_vdi_uuid =
130+
Client.Client.VDI.get_uuid ~rpc ~session_id ~self:new_vdi
131+
in
132+
(new_vdi_uuid, new_vdi)
133+
134+
let import_file_into_vdi ~file ~vdi_uuid ~exportformat =
86135
Qt.cli_cmd
87136
[
88-
"vdi-export"
137+
"vdi-import"
89138
; "uuid=" ^ vdi_uuid
90139
; "filename=" ^ file
91140
; "format=" ^ exportformat
92141
]
93-
|> ignore ;
142+
|> ignore
143+
144+
let export_import_vdi rpc session_id ~exportformat sR vdi =
145+
let file = export_vdi_to_file ~rpc ~session_id ~exportformat ~vdi () in
94146
Xapi_stdext_pervasives.Pervasiveext.finally
95147
(fun () ->
96-
let virtual_size =
97-
Client.Client.VDI.get_virtual_size ~rpc ~session_id ~self:vdi
98-
in
99-
let new_vdi =
100-
Client.Client.VDI.create ~rpc ~session_id ~name_label:""
101-
~name_description:"" ~sR ~virtual_size ~_type:`user ~sharable:false
102-
~read_only:false ~other_config:[] ~xenstore_data:[] ~sm_config:[]
103-
~tags:[]
104-
in
105-
let new_vdi_uuid =
106-
Client.Client.VDI.get_uuid ~rpc ~session_id ~self:new_vdi
107-
in
108-
Qt.cli_cmd
109-
[
110-
"vdi-import"
111-
; "uuid=" ^ new_vdi_uuid
112-
; "filename=" ^ file
113-
; "format=" ^ exportformat
114-
]
115-
|> ignore ;
148+
let new_vdi_uuid, new_vdi = create_new_vdi ~rpc ~session_id ~sR ~vdi in
149+
import_file_into_vdi ~file ~vdi_uuid:new_vdi_uuid ~exportformat ;
116150
new_vdi
117151
)
118152
(fun () -> Sys.remove file)
119153

154+
let export_delta_import_vdi rpc session_id ~exportformat ~vdi ~base_vdi =
155+
let file =
156+
export_vdi_to_file ~rpc ~session_id ~exportformat ~vdi ~base_vdi ()
157+
in
158+
Xapi_stdext_pervasives.Pervasiveext.finally
159+
(fun () ->
160+
(* Import delta on top of base_vdi *)
161+
let base_uuid =
162+
Client.Client.VDI.get_uuid ~rpc ~session_id ~self:base_vdi
163+
in
164+
import_file_into_vdi ~file ~vdi_uuid:base_uuid ~exportformat
165+
)
166+
(fun () -> Sys.remove file)
167+
120168
let export_import_raw = export_import_vdi ~exportformat:"raw"
121169

122170
let export_import_vhd = export_import_vdi ~exportformat:"vhd"
123171

124172
let export_import_tar = export_import_vdi ~exportformat:"tar"
125173

174+
let export_import_qcow = export_import_vdi ~exportformat:"qcow2"
175+
176+
let delta_export_import_vhd = export_delta_import_vdi ~exportformat:"vhd"
177+
178+
let delta_export_import_qcow = export_delta_import_vdi ~exportformat:"qcow2"
179+
126180
let data_integrity_tests vdi_op op_name =
127181
[
128182
( op_name ^ ": small empty VDI"
@@ -141,6 +195,47 @@ let data_integrity_tests vdi_op op_name =
141195
)
142196
]
143197

198+
let delta_data_integrity_tests vdi_op op_name =
199+
[
200+
( op_name ^ ": delta between empty & empty VDI"
201+
, `Slow
202+
, check_vdi_delta
203+
~vdi_size:Sizes.(4L ** mib)
204+
~prepare_vdi:noop ~prepare_vdi_base:noop ~vdi_op
205+
)
206+
; ( op_name ^ ": delta between random & empty VDI"
207+
, `Slow
208+
, check_vdi_delta
209+
~vdi_size:Sizes.(4L ** mib)
210+
~prepare_vdi:write_random_data ~prepare_vdi_base:noop ~vdi_op
211+
)
212+
; ( op_name ^ ": delta between random & random VDI"
213+
, `Slow
214+
, check_vdi_delta
215+
~vdi_size:Sizes.(4L ** mib)
216+
~prepare_vdi:write_random_data ~prepare_vdi_base:write_random_data
217+
~vdi_op
218+
)
219+
; ( op_name ^ ": delta between full and empty VDI"
220+
, `Slow
221+
, check_vdi_delta
222+
~vdi_size:Sizes.(4L ** mib)
223+
~prepare_vdi:fill ~prepare_vdi_base:noop ~vdi_op
224+
)
225+
; ( op_name ^ ": delta between full and random VDI"
226+
, `Slow
227+
, check_vdi_delta
228+
~vdi_size:Sizes.(4L ** mib)
229+
~prepare_vdi:fill ~prepare_vdi_base:write_random_data ~vdi_op
230+
)
231+
; ( op_name ^ ": delta between full and full VDI"
232+
, `Slow
233+
, check_vdi_delta
234+
~vdi_size:Sizes.(4L ** mib)
235+
~prepare_vdi:fill ~prepare_vdi_base:fill ~vdi_op
236+
)
237+
]
238+
144239
let large_data_integrity_tests vdi_op op_name =
145240
let b = Random.int64 16L in
146241
[
@@ -179,9 +274,21 @@ let tests () =
179274
@ (data_integrity_tests export_import_vhd "VDI export/import to/from VHD file"
180275
|> supported_srs
181276
)
277+
@ (delta_data_integrity_tests delta_export_import_vhd
278+
"VDI delta export/import to/from VHD file"
279+
|> supported_srs
280+
)
182281
@ (data_integrity_tests export_import_tar "VDI export/import to/from TAR file"
183282
|> supported_srs
184283
)
284+
@ (data_integrity_tests export_import_qcow
285+
"VDI export/import to/from QCOW file"
286+
|> supported_srs
287+
)
288+
@ (delta_data_integrity_tests delta_export_import_qcow
289+
"VDI delta export/import to/from QCOW file"
290+
|> supported_srs
291+
)
185292
@ (large_data_integrity_tests export_import_tar
186293
"VDI export/import to/from TAR file"
187294
|> supported_gfs2_srs

0 commit comments

Comments
 (0)