@@ -219,36 +219,54 @@ def coalesce_integrity(vm: VM, vdi: VDI, vdi_op: CoalesceOperation, defer: Defer
219219
220220XVACompression = Literal ['none' , 'gzip' , 'zstd' ]
221221
222- def xva_export_import (vm : VM , compression : XVACompression , defer : Defer ):
223- vm .vdis [0 ].resize (config .volume_size )
222+ def xva_export_import (vm : VM , compression : XVACompression , temp_large_dir : str , defer : Defer ):
223+ # we can't shrink a volume
224+ volume_size = max (vm .vdis [0 ].get_virtual_size (), config .volume_size )
225+ vm .vdis [0 ].resize (volume_size )
224226 # The tests using this function are using specific fixtures to create the VM on the expected SR
225227 # In consequence, we can't use the storage_test_vm, so we have to start the VM explicitly and install randstream
226228 vm .start ()
227229 vm .wait_for_vm_running_and_ssh_up ()
228230 install_randstream (vm )
229231
230- # 500MiB, so we have some data to check and some empty spaces in the exported image
231- # TODO: resize the vm partitions and write more data in the disk (like 1/2 of the disk size)
232- # to ensure we can export and import large xva images
233- randstream (vm , 'generate --size 500MiB /root/data' )
234- randstream (vm , 'validate --expected-checksum 24e905d6 /root/data' )
232+ is_alpine = vm .ssh_with_result ('apk --version' ).returncode == 0
233+ if is_alpine :
234+ # growpart is not available in alpine 3.12
235+ # vm.ssh('apk add cloud-utils-growpart e2fsprogs-extra')
236+ vm .ssh ('apk add gawk util-linux e2fsprogs-extra' )
237+ vm .ssh ('wget https://raw.githubusercontent.com/canonical/cloud-utils/main/bin/growpart -O /usr/bin/growpart' )
238+ vm .ssh ('chmod +x /usr/bin/growpart' )
239+ # TODO: maybe use `findmnt -no SOURCE /` from util-linux to get the blockdevice mounted on /
240+ growpart_returncode = vm .ssh_with_result ('growpart /dev/xvda 3' ).returncode
241+ assert growpart_returncode in [0 , 1 ] # growpart returns 1 if the size is already the expected one
242+ vm .ssh ('resize2fs /dev/xvda3' )
243+ stream_size = volume_size // 2
244+ else :
245+ stream_size = 500 * MiB
246+
247+ checksum = randstream (vm , f'generate --size { stream_size } /root/data' )
248+ randstream (vm , f'validate --expected-checksum { checksum } /root/data' )
235249 vm .shutdown (verify = True )
236250
237- xva_path = f'/tmp /{ vm .uuid } .xva'
251+ xva_path = f'{ temp_large_dir } /{ vm .uuid } .xva'
238252 defer (lambda : vm .host .ssh (f'rm -f { xva_path } ' ))
239253 vm .export (xva_path , compression )
240254 # check that the zero blocks are not part of the result. Most of the data is from the random stream, so
241- # compression has little effect. We just check the result is between 500 and 700 MiB
255+ # compression has little effect. We just take into account the system sie
242256 size_mb = int (vm .host .ssh (f'du -sm --apparent-size { xva_path } ' ).split ()[0 ])
243- assert 500 < size_mb < 700 , f"unexpected xva size: { size_mb } "
257+ min_size = stream_size / MiB
258+ max_size = stream_size * 1.1 / MiB + 200
259+ assert min_size < size_mb < max_size , (
260+ f"unexpected xva size { size_mb } MiB, was expected to be between { min_size } MiB and { max_size } MiB"
261+ )
244262
245263 imported_vm = vm .host .import_vm (xva_path , vm .vdis [0 ].sr .uuid )
246264 defer (lambda : imported_vm .destroy ())
247- assert vm .vdis [0 ].get_virtual_size () == config . volume_size
265+ assert vm .vdis [0 ].get_virtual_size () == volume_size
248266
249267 imported_vm .start ()
250268 imported_vm .wait_for_vm_running_and_ssh_up ()
251- randstream (imported_vm , 'validate --expected-checksum 24e905d6 /root/data' )
269+ randstream (imported_vm , f 'validate --expected-checksum { checksum } /root/data' )
252270
253271def vdi_export_import (vm : VM , sr : SR , image_format : ImageFormat , temp_large_dir : str , defer : Defer ):
254272 vdi_src = sr .create_vdi (image_format = image_format , virtual_size = config .volume_size )
0 commit comments