diff --git a/test/Makefile b/test/Makefile index 65ed7bc4..f7372e2e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ all: test -test: test_snapshot test_cfg_to_cmd test_pci_addr_conflicts test_qemu_img_convert test_migration test_restore_config +test: test_snapshot test_cfg_to_cmd test_pci_addr_conflicts test_qemu_img_convert test_migration test_restore_config test_parse_config test_snapshot: run_snapshot_tests.pl ./run_snapshot_tests.pl @@ -25,6 +25,9 @@ $(MIGRATION_TEST_TARGETS): test_restore_config: run_qemu_restore_config_tests.pl ./run_qemu_restore_config_tests.pl +test_parse_config: run_parse_config_tests.pl + ./run_parse_config_tests.pl + .PHONY: clean clean: - rm -rf MigrationTest/run + rm -rf MigrationTest/run parse-config-output diff --git a/test/parse-config-expected/verify-snapshot.conf b/test/parse-config-expected/verify-snapshot.conf new file mode 100644 index 00000000..cd503f86 --- /dev/null +++ b/test/parse-config-expected/verify-snapshot.conf @@ -0,0 +1,36 @@ +boot: order=scsi0 +cores: 2 +cpu: x86-64-v2-AES +ide2: lvm:vm-120-cloudinit,media=cdrom +ipconfig0: ip6=dhcp +memory: 4096 +meta: creation-qemu=9.0.2,ctime=1725975013 +name: deb1223 +net0: vmxnet3=BC:24:11:2C:69:EC,bridge=vnet0,firewall=1 +numa: 0 +ostype: l26 +parent: snap +scsi0: nfs:120/vm-120-disk-0.qcow2,iothread=1,size=4G +scsihw: virtio-scsi-single +smbios1: uuid=b3247ab1-1fe6-428e-965b-08a1b64a8746 +sockets: 1 +unused0: rbd:vm-120-disk-0 +vmgenid: 7079e97c-50e3-4079-afe7-23e67566b946 + +[snap] +boot: order=scsi0 +cores: 2 +cpu: x86-64-v2-AES +ide2: lvm:vm-120-cloudinit,media=cdrom +ipconfig0: ip6=dhcp +memory: 4096 +meta: creation-qemu=9.0.2,ctime=1725975013 +name: deb1223 +net0: vmxnet3=BC:24:11:2C:69:EC,bridge=vnet0,firewall=1 +ostype: l26 +scsi0: nfs:120/vm-120-disk-0.qcow2,iothread=1,size=4G +scsihw: virtio-scsi-single +smbios1: uuid=b3247ab1-1fe6-428e-965b-08a1b64a8746 +snaptime: 1737549549 +sockets: 1 +vmgenid: 7079e97c-50e3-4079-afe7-23e67566b946 diff --git a/test/parse-config-expected/verify-snapshot.conf.strict.error b/test/parse-config-expected/verify-snapshot.conf.strict.error new file mode 100644 index 00000000..1a77d4a5 --- /dev/null +++ b/test/parse-config-expected/verify-snapshot.conf.strict.error @@ -0,0 +1 @@ +vm 8006 - unable to parse value of 'numa' - type check ('boolean') failed - got 'verify meee~ :)' diff --git a/test/parse-config-input/locked.conf b/test/parse-config-input/locked.conf new file mode 100644 index 00000000..38b6e36c --- /dev/null +++ b/test/parse-config-input/locked.conf @@ -0,0 +1,16 @@ +# locked +bootdisk: scsi0 +cores: 1 +ide2: none,media=cdrom +lock: backup +memory: 512 +name: apache +net0: virtio=92:38:11:FD:ED:87,bridge=vmbr0,firewall=1 +numa: 0 +ostype: l26 +scsi0: mydir:1422/vm-1422-disk-0.qcow2,size=4G +scsihw: virtio-scsi-pci +smbios1: uuid=ddf91b3f-a597-42be-9a7e-fb6421dcd5cd +sockets: 1 +unused7: mydir:1422/vm-1422-disk-8.qcow2 +vmgenid: 0 diff --git a/test/parse-config-input/plain.conf b/test/parse-config-input/plain.conf new file mode 100644 index 00000000..63449b9e --- /dev/null +++ b/test/parse-config-input/plain.conf @@ -0,0 +1,15 @@ +# plain VM +bootdisk: scsi0 +cores: 1 +ide2: none,media=cdrom +memory: 512 +name: apache +net0: virtio=92:38:11:FD:ED:87,bridge=vmbr0,firewall=1 +numa: 0 +ostype: l26 +scsi0: mydir:142/vm-142-disk-0.qcow2,size=4G +scsihw: virtio-scsi-pci +smbios1: uuid=ddf91b3f-a597-42be-9a7e-fb6421dcd5cd +sockets: 1 +tags: foo bar +vmgenid: 0 diff --git a/test/parse-config-input/regular-vm-efi.conf b/test/parse-config-input/regular-vm-efi.conf new file mode 100644 index 00000000..9d75fff2 --- /dev/null +++ b/test/parse-config-input/regular-vm-efi.conf @@ -0,0 +1,16 @@ +# regular VM with an EFI disk +bios: ovmf +boot: order=scsi0;ide2;net0 +cores: 1 +efidisk0: mydir:139/vm-139-disk-0.qcow2,size=128K +ide2: local:iso/debian-10.6.0-amd64-netinst.iso,media=cdrom +memory: 2048 +name: eficloneclone +net0: virtio=7A:6C:A5:8B:11:93,bridge=vmbr0,firewall=1 +numa: 0 +ostype: l26 +scsi0: rbdkvm:vm-139-disk-1,size=4G +scsihw: virtio-scsi-pci +smbios1: uuid=21a7e7bc-3cd2-4232-a009-a41f4ee992ae +sockets: 1 +vmgenid: 0 diff --git a/test/parse-config-input/sections.conf b/test/parse-config-input/sections.conf new file mode 100644 index 00000000..6329c33a --- /dev/null +++ b/test/parse-config-input/sections.conf @@ -0,0 +1,44 @@ +boot: order=scsi0 +cores: 2 +cpu: x86-64-v2-AES +ide2: lvm:vm-120-cloudinit,media=cdrom +ipconfig0: ip6=dhcp +memory: 4096 +meta: creation-qemu=9.0.2,ctime=1725975013 +name: deb1223 +net0: vmxnet3=BC:24:11:2C:69:EC,bridge=vnet0,firewall=1 +numa: 0 +ostype: l26 +parent: foo +scsi0: nfs:120/vm-120-disk-0.qcow2,iothread=1,size=4G +scsihw: virtio-scsi-single +smbios1: uuid=b3247ab1-1fe6-428e-965b-08a1b64a8746 +sockets: 1 +unused0: rbd:vm-120-disk-0 +vmgenid: 7079e97c-50e3-4079-afe7-23e67566b946 + +[PENDING] +bios: ovmf + +[special:cloudinit] +ipconfig0: ip=dhcp,ip6=dhcp +name: deb122 + +[foo] +boot: order=scsi0 +cores: 2 +cpu: x86-64-v2-AES +ide2: lvm:vm-120-cloudinit,media=cdrom +ipconfig0: ip=dhcp,ip6=dhcp +memory: 4096 +meta: creation-qemu=9.0.2,ctime=1725975013 +name: deb1223 +net0: vmxnet3=BC:24:11:2C:69:EC,bridge=vnet0,firewall=1 +numa: 0 +ostype: l26 +scsi0: nfs:120/vm-120-disk-0.qcow2,iothread=1,size=4G +scsihw: virtio-scsi-single +smbios1: uuid=b3247ab1-1fe6-428e-965b-08a1b64a8746 +snaptime: 1737548747 +sockets: 1 +vmgenid: 7079e97c-50e3-4079-afe7-23e67566b946 diff --git a/test/parse-config-input/snapshots.conf b/test/parse-config-input/snapshots.conf new file mode 100644 index 00000000..4f4f8675 --- /dev/null +++ b/test/parse-config-input/snapshots.conf @@ -0,0 +1,189 @@ +boot: order=scsi1;ide2;net0;ide1 +cores: 4 +cpu: x86-64-v2-AES +ide0: dir:111/vm-111-disk-2.qcow2,size=1G +ide1: sani:iso/virtio-win-0.1.266.iso,media=cdrom,size=707456K +ide2: sani:iso/Win2019-evaluation.iso,media=cdrom,size=4985424K +machine: pc-i440fx-9.1 +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: virtio=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +net1: e1000=BC:24:11:79:D5:65,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +parent: win19_5_2_plus_stuff +scsi0: dir:111/vm-111-disk-1.qcow2,iothread=1,size=1G +scsi1: lvmthinbig:vm-111-disk-0,iothread=1,size=32G +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +sockets: 1 +unused0: rbd:vm-111-disk-0 +vga: qxl +virtio0: dir:111/vm-111-disk-0.qcow2,iothread=1,size=1G +vmgenid: 713da648-38a6-489e-b0b2-dd9cef419f33 + +[machine_version_5_1] +boot: order=ide0;ide2;net0 +cores: 4 +cpu: x86-64-v2-AES +ide0: lvmthinbig:vm-111-disk-0,size=32G +ide2: sani:iso/Win2016-1616-evaluation.ISO,media=cdrom,size=5198078K +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: e1000=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +snaptime: 1736939109 +sockets: 1 +vmgenid: 1f314a76-50a3-4b92-9307-c8c6e313d3ca + +[machine_version_5_1_with_virtio] +boot: order=ide0;ide2;net0;ide1 +cores: 4 +cpu: x86-64-v2-AES +ide0: lvmthinbig:vm-111-disk-0,size=32G +ide1: sani:iso/virtio-win-0.1.266.iso,media=cdrom,size=707456K +ide2: sani:iso/Win2016-1616-evaluation.ISO,media=cdrom,size=5198078K +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: virtio=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +parent: machine_version_5_1 +scsi0: dir:111/vm-111-disk-1.qcow2,iothread=1,size=1G +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +snaptime: 1736940462 +sockets: 1 +virtio0: dir:111/vm-111-disk-0.qcow2,iothread=1,size=1G +vmgenid: 4f602356-cb9c-45ad-a554-d76d95c7c0f8 + +[ovmf_machine_version_5_1] +bios: ovmf +boot: order=ide0;ide2;net0;ide1 +cores: 4 +cpu: x86-64-v2-AES +efidisk0: rbd:vm-111-disk-0,efitype=4m,pre-enrolled-keys=1,size=1M +ide0: lvmthinbig:vm-111-disk-0,size=32G +ide1: sani:iso/virtio-win-0.1.266.iso,media=cdrom,size=707456K +ide2: sani:iso/Win2016-1616-evaluation.ISO,media=cdrom,size=5198078K +machine: pc-q35-5.1 +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: e1000=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +parent: machine_version_5_1_with_virtio +scsi0: dir:111/vm-111-disk-1.qcow2,iothread=1,size=1G +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +snaptime: 1736943308 +sockets: 1 +virtio0: dir:111/vm-111-disk-0.qcow2,iothread=1,size=1G +vmgenid: 4f602356-cb9c-45ad-a554-d76d95c7c0f8 + +[ovmf_machine_version_5_1_virtio] +bios: ovmf +boot: order=ide0;ide2;net0;ide1 +cores: 4 +cpu: x86-64-v2-AES +efidisk0: rbd:vm-111-disk-0,efitype=4m,pre-enrolled-keys=1,size=1M +ide0: lvmthinbig:vm-111-disk-0,size=32G +ide1: sani:iso/virtio-win-0.1.266.iso,media=cdrom,size=707456K +ide2: sani:iso/Win2016-1616-evaluation.ISO,media=cdrom,size=5198078K +machine: pc-q35-5.1 +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: virtio=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +parent: ovmf_machine_version_5_1 +scsi0: dir:111/vm-111-disk-1.qcow2,iothread=1,size=1G +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +snaptime: 1736944525 +sockets: 1 +virtio0: dir:111/vm-111-disk-0.qcow2,iothread=1,size=1G +vmgenid: 00b95468-4f34-4faa-b0af-b214ff5bbcdf + +[static-network] +bios: ovmf +boot: order=ide0;ide2;net0;ide1 +cores: 4 +cpu: x86-64-v2-AES +efidisk0: rbd:vm-111-disk-0,efitype=4m,pre-enrolled-keys=1,size=1M +ide0: lvmthinbig:vm-111-disk-0,size=32G +ide1: sani:iso/virtio-win-0.1.266.iso,media=cdrom,size=707456K +ide2: sani:iso/Win2016-1616-evaluation.ISO,media=cdrom,size=5198078K +machine: pc-q35-5.1 +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: virtio=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +parent: ovmf_machine_version_5_1_virtio +scsi0: dir:111/vm-111-disk-1.qcow2,iothread=1,size=1G +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +snaptime: 1736945713 +sockets: 1 +virtio0: dir:111/vm-111-disk-0.qcow2,iothread=1,size=1G +vmgenid: 5d65fc62-2cb1-4945-9641-631b37c265a5 + +[win19_5_2] +boot: order=scsi1;ide2;net0;ide1 +cores: 4 +cpu: x86-64-v2-AES +ide1: sani:iso/virtio-win-0.1.266.iso,media=cdrom,size=707456K +ide2: sani:iso/Win2019-evaluation.iso,media=cdrom,size=4985424K +machine: pc-i440fx-5.2 +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: virtio=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +net1: e1000=BC:24:11:79:D5:65,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +parent: machine_version_5_1_with_virtio +scsi0: dir:111/vm-111-disk-1.qcow2,iothread=1,size=1G +scsi1: lvmthinbig:vm-111-disk-0,iothread=1,size=32G +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +snaptime: 1736950690 +sockets: 1 +virtio0: dir:111/vm-111-disk-0.qcow2,iothread=1,size=1G +vmgenid: f259de06-fa08-4ff7-8ba9-b1233a726ac4 + +[win19_5_2_plus_stuff] +boot: order=scsi1;ide2;net0;ide1 +cores: 4 +cpu: x86-64-v2-AES +ide0: dir:111/vm-111-disk-2.qcow2,size=1G +ide1: sani:iso/virtio-win-0.1.266.iso,media=cdrom,size=707456K +ide2: sani:iso/Win2019-evaluation.iso,media=cdrom,size=4985424K +machine: pc-i440fx-5.2 +memory: 4096 +meta: creation-qemu=9.1.2,ctime=1736349024 +name: win-machine-ver +net0: virtio=BC:24:11:A3:DA:B1,bridge=vnet0,firewall=1 +net1: e1000=BC:24:11:79:D5:65,bridge=vnet0,firewall=1 +numa: 0 +ostype: win10 +parent: win19_5_2 +scsi0: dir:111/vm-111-disk-1.qcow2,iothread=1,size=1G +scsi1: lvmthinbig:vm-111-disk-0,iothread=1,size=32G +scsihw: virtio-scsi-single +smbios1: uuid=2c4a2cda-712b-44ab-8728-51f5e734b658 +snaptime: 1736951300 +sockets: 1 +vga: qxl +virtio0: dir:111/vm-111-disk-0.qcow2,iothread=1,size=1G +vmgenid: 713da648-38a6-489e-b0b2-dd9cef419f33 diff --git a/test/parse-config-input/verify-snapshot.conf b/test/parse-config-input/verify-snapshot.conf new file mode 100644 index 00000000..5f52272d --- /dev/null +++ b/test/parse-config-input/verify-snapshot.conf @@ -0,0 +1,37 @@ +boot: order=scsi0 +cores: 2 +cpu: x86-64-v2-AES +ide2: lvm:vm-120-cloudinit,media=cdrom +ipconfig0: ip6=dhcp +memory: 4096 +meta: creation-qemu=9.0.2,ctime=1725975013 +name: deb1223 +net0: vmxnet3=BC:24:11:2C:69:EC,bridge=vnet0,firewall=1 +numa: 0 +ostype: l26 +parent: snap +scsi0: nfs:120/vm-120-disk-0.qcow2,iothread=1,size=4G +scsihw: virtio-scsi-single +smbios1: uuid=b3247ab1-1fe6-428e-965b-08a1b64a8746 +sockets: 1 +unused0: rbd:vm-120-disk-0 +vmgenid: 7079e97c-50e3-4079-afe7-23e67566b946 + +[snap] +boot: order=scsi0 +cores: 2 +cpu: x86-64-v2-AES +ide2: lvm:vm-120-cloudinit,media=cdrom +ipconfig0: ip6=dhcp +memory: 4096 +meta: creation-qemu=9.0.2,ctime=1725975013 +name: deb1223 +net0: vmxnet3=BC:24:11:2C:69:EC,bridge=vnet0,firewall=1 +numa: verify meee~ :) +ostype: l26 +scsi0: nfs:120/vm-120-disk-0.qcow2,iothread=1,size=4G +scsihw: virtio-scsi-single +smbios1: uuid=b3247ab1-1fe6-428e-965b-08a1b64a8746 +snaptime: 1737549549 +sockets: 1 +vmgenid: 7079e97c-50e3-4079-afe7-23e67566b946 diff --git a/test/run_parse_config_tests.pl b/test/run_parse_config_tests.pl new file mode 100755 index 00000000..d071f355 --- /dev/null +++ b/test/run_parse_config_tests.pl @@ -0,0 +1,92 @@ +#!/usr/bin/perl + +# Tests parsing and writing VM configuration files. +# The parsing part is already covered by the config2command test too, but that only focuses on the +# main section, not other section types and does not also test parsing in strict mode. +# +# If no expected file exists, the input is assumed to be equal to the expected output. +# If $file.strict.error (respectively $file.non-strict.error) exists, it is assumed to be the +# expected error when parsing the config in strict (respectively non-strict) mode. + +use strict; +use warnings; + +use lib qw(..); + +use File::Path qw(make_path remove_tree); + +use Test::MockModule; +use Test::More; + +use PVE::QemuServer; +use PVE::Tools; + +my $INPUT_DIR = './parse-config-input'; +my $OUTPUT_DIR = './parse-config-output'; +my $EXPECTED_DIR = './parse-config-expected'; + +# NOTE update when you add/remove tests +plan tests => 2 * 6; + +sub run_tests { + my ($strict) = @_; + + PVE::Tools::dir_glob_foreach('./parse-config-input', '.*\.conf', sub { + my ($file) = @_; + + my $strict_mode = $strict ? 'strict' : 'non-strict'; + + my $expected_err_file = "${EXPECTED_DIR}/${file}.${strict_mode}.error"; + my $expected_err; + $expected_err = PVE::Tools::file_get_contents($expected_err_file) if -f $expected_err_file; + + my $fake_config_fn ="$file/qemu-server/8006.conf"; + my $input_file = "${INPUT_DIR}/${file}"; + my $input = PVE::Tools::file_get_contents($input_file); + my $conf = eval { + PVE::QemuServer::parse_vm_config($fake_config_fn, $input, $strict); + }; + if (my $err = $@) { + if ($expected_err) { + is($err, $expected_err, $file); + } else { + note("got unexpected error '$err'"); + fail($file); + } + return; + } + + if ($expected_err) { + note("expected error for strict mode did not occur: '$expected_err'"); + fail($file); + return; + } + + my $output = eval { PVE::QemuServer::write_vm_config($fake_config_fn, $conf); }; + if (my $err = $@) { + note("got unexpected error '$err'"); + fail($file); + return; + } + + my $output_file = "${OUTPUT_DIR}/${file}"; + PVE::Tools::file_set_contents($output_file, $output); + + my $expected_file = "${EXPECTED_DIR}/${file}"; + $expected_file = $input_file if !-f $expected_file; + + my $cmd = ['diff', '-u', $expected_file, $output_file]; + if (system(@$cmd) == 0) { + pass($file); + } else { + fail($file); + } + }); +} + +make_path(${OUTPUT_DIR}); +run_tests(0); +run_tests(1); +remove_tree(${OUTPUT_DIR}) or die "failed to remove output directory\n"; + +done_testing();