diff --git a/0001-v2v-test-harness-Measure-similarity-between-images-w.patch b/0001-v2v-test-harness-Measure-similarity-between-images-w.patch new file mode 100644 index 0000000..fb8e091 --- /dev/null +++ b/0001-v2v-test-harness-Measure-similarity-between-images-w.patch @@ -0,0 +1,60 @@ +From a3beda8b77363e13f652104b06efaee33ecfe67c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 11 Mar 2015 15:02:58 +0000 +Subject: [PATCH 1/2] v2v: test-harness: Measure similarity between images when + comparing screenshots. + +Since wallclock time differs between boots, we cannot just compare two +screenshots by checking if they are identical -- if the screenshot +contains any time information, then that will be different, and it +turns out that VMs print the current time at boot. + +Therefore parse out and use the "similarity" metric printed by the +ImageMagick "compare" command when it compares the screenshots, and +allow a small epsilon for the case where a few oixels are different. +--- + v2v/test-harness/v2v_test_harness.ml | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +diff --git a/v2v/test-harness/v2v_test_harness.ml b/v2v/test-harness/v2v_test_harness.ml +index cd08cd0..998903a 100644 +--- a/v2v/test-harness/v2v_test_harness.ml ++++ b/v2v/test-harness/v2v_test_harness.ml +@@ -196,13 +196,29 @@ let run ~test ?input_disk ?input_xml ?(test_plan = default_plan) () = + + let display_matches_screenshot screenshot1 screenshot2 = + let cmd = +- sprintf "compare -metric MAE %s %s null:" ++ (* Grrr compare sends its normal output to stderr. *) ++ sprintf "compare -metric MAE %s %s null: 2>&1" + (quote screenshot1) (quote screenshot2) in + printf "%s\n%!" cmd; +- let r = Sys.command cmd in +- if r < 0 || r > 1 then +- failwith "compare command failed"; +- r = 0 ++ let chan = Unix.open_process_in cmd in ++ let lines = ref [] in ++ (try while true do lines := input_line chan :: !lines done ++ with End_of_file -> ()); ++ let lines = List.rev !lines in ++ let stat = Unix.close_process_in chan in ++ let similarity = ++ match stat with ++ | Unix.WEXITED 0 -> 0.0 (* exact match *) ++ | Unix.WEXITED 1 -> ++ Scanf.sscanf (List.hd lines) "%f" (fun f -> f) ++ | Unix.WEXITED i -> ++ failwithf "external command '%s' exited with error %d" cmd i ++ | Unix.WSIGNALED i -> ++ failwithf "external command '%s' killed by signal %d" cmd i ++ | Unix.WSTOPPED i -> ++ failwithf "external command '%s' stopped by signal %d" cmd i in ++ printf "%s %s have similarity %f\n" screenshot1 screenshot2 similarity; ++ similarity <= 60.0 + in + + let dom_is_alive () = +-- +2.3.1 + diff --git a/0002-v2v-test-harness-Fix-boot-loop-so-it-detects-disk-in.patch b/0002-v2v-test-harness-Fix-boot-loop-so-it-detects-disk-in.patch new file mode 100644 index 0000000..fabc5b4 --- /dev/null +++ b/0002-v2v-test-harness-Fix-boot-loop-so-it-detects-disk-in.patch @@ -0,0 +1,75 @@ +From 0827b006e4943a670dbe193dd8b522d7cc3b4bf5 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 11 Mar 2015 15:05:13 +0000 +Subject: [PATCH 2/2] v2v: test-harness: Fix boot loop so it detects disk + inactivity properly. + +--- + v2v/test-harness/v2v_test_harness.ml | 50 +++++++++++++++++++----------------- + 1 file changed, 27 insertions(+), 23 deletions(-) + +diff --git a/v2v/test-harness/v2v_test_harness.ml b/v2v/test-harness/v2v_test_harness.ml +index 998903a..fe09d6f 100644 +--- a/v2v/test-harness/v2v_test_harness.ml ++++ b/v2v/test-harness/v2v_test_harness.ml +@@ -280,30 +280,34 @@ let run ~test ?input_disk ?input_xml ?(test_plan = default_plan) () = + if active then ( + printf "%s: disk activity detected\n" (timestamp t); + loop start t stats +- ) else if t -. last_activity <= float test_plan.boot_idle_time then ( +- let screenshot = take_screenshot t in +- (* Reached the final screenshot? *) +- let done_ = +- match test_plan.boot_plan with +- | Boot_to_screenshot final_screenshot -> +- if display_matches_screenshot screenshot final_screenshot then ( +- printf "%s: guest reached final screenshot\n" (timestamp t); +- true +- ) else false +- | _ -> false in +- if not done_ then ( +- (* A screenshot matching one of the screenshots in the set +- * resets the timeout. +- *) +- let waiting_in_known_good_state = +- List.exists (display_matches_screenshot screenshot) +- test_plan.boot_known_good_screenshots in +- if waiting_in_known_good_state then ( +- printf "%s: guest at known-good screenshot\n" (timestamp t); +- loop t last_activity stats +- ) else +- loop start last_activity stats ++ ) else ( ++ if t -. last_activity <= float test_plan.boot_idle_time then ( ++ let screenshot = take_screenshot t in ++ (* Reached the final screenshot? *) ++ let done_ = ++ match test_plan.boot_plan with ++ | Boot_to_screenshot final_screenshot -> ++ if display_matches_screenshot screenshot final_screenshot then ( ++ printf "%s: guest reached final screenshot\n" (timestamp t); ++ true ++ ) else false ++ | _ -> false in ++ if not done_ then ( ++ (* A screenshot matching one of the screenshots in the set ++ * resets the timeouts. ++ *) ++ let waiting_in_known_good_state = ++ List.exists (display_matches_screenshot screenshot) ++ test_plan.boot_known_good_screenshots in ++ if waiting_in_known_good_state then ( ++ printf "%s: guest at known-good screenshot\n" (timestamp t); ++ loop t t stats ++ ) else ++ loop start last_activity stats ++ ) + ) ++ else ++ bootfail t "guest timed out with no disk activity before reaching final state" + ) + in + loop start last_activity stats; +-- +2.3.1 + diff --git a/libguestfs.spec b/libguestfs.spec index be1454a..4750170 100644 --- a/libguestfs.spec +++ b/libguestfs.spec @@ -25,13 +25,16 @@ Summary: Access and modify virtual machine disk images Name: libguestfs Epoch: 1 Version: 1.29.30 -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv2+ # Source and patches. URL: http://libguestfs.org/ Source0: http://libguestfs.org/download/1.29-development/%{name}-%{version}.tar.gz +Patch1: 0001-v2v-test-harness-Measure-similarity-between-images-w.patch +Patch2: 0002-v2v-test-harness-Fix-boot-loop-so-it-detects-disk-in.patch + # Basic build requirements: BuildRequires: perl(Pod::Simple) BuildRequires: perl(Pod::Man) @@ -66,6 +69,7 @@ BuildRequires: ocaml BuildRequires: ocaml-findlib-devel BuildRequires: ocaml-gettext-devel BuildRequires: ocaml-ounit-devel +BuildRequires: ocaml-libvirt-devel >= 0.6.1.4-5 BuildRequires: systemd-units BuildRequires: netpbm-progs BuildRequires: icoutils @@ -189,6 +193,12 @@ Provides: bundled(gnulib) # Fedora, which breaks everything. Thus: Conflicts: libguestfs-winsupport +# virt-v2v-test-harness uses an internal module called 'Xml' which +# conflicts with an OCaml module of the same name. Ignore the +# internal module when generating requires & provides. +%global __ocaml_requires_opts -i Xml +%global __ocaml_provides_opts -i Xml + %description Libguestfs is a library for accessing and modifying virtual machine @@ -525,6 +535,37 @@ Virt-v2v and virt-p2v are tools that convert virtual machines from non-KVM hypervisors, or physical machines, to run under KVM. +%package -n virt-v2v-test-harness +Summary: Library used to write test cases for virt-v2v +License: LGPLv2+ + +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: virt-v2v = %{epoch}:%{version}-%{release} +Requires: ocaml-libguestfs-devel = %{epoch}:%{version}-%{release} + +Requires: ocaml-libvirt-devel >= 0.6.1.4-5 +Requires: /usr/bin/virsh +Requires: /usr/bin/compare +Requires: /usr/bin/unxz + + +%description -n virt-v2v-test-harness +Virt-v2v-test-harness is a small library (module name: V2v_test_harness) +used to run virt-v2v against a set of test cases consisting of real +virtual machines. + +It acts as a test harness, taking a test case, running virt-v2v on it, +then test-booting the result. It can ensure that the test case +converts successfully, boots successfully, and reaches a milestone +(such as a particular screenshot). It can also test that the +conversion created, modified or deleted the expected files from within +the guest. + +Note that this package includes only the test harness and not the test +cases, which are distributed separately. See the +virt-v2v-test-harness(1) manual page for details. + + %package bash-completion Summary: Bash tab-completion scripts for %{name} tools BuildArch: noarch @@ -768,6 +809,10 @@ for %{name}. %prep %setup -q +# Apply patches, if any, here. +%patch1 -p1 +%patch2 -p1 + # For Python 3 we must build libguestfs twice. This creates: # %{name}-%{version}/ # %{name}-%{version}/python3/ @@ -1171,6 +1216,14 @@ popd %{_datadir}/virt-tools +%files -n virt-v2v-test-harness +%doc COPYING.LIB +%{_mandir}/man1/virt-v2v-test-harness.1* +%{_libdir}/ocaml/v2v_test_harness +%{_libdir}/ocaml/stublibs/dllv2v_test_harness.so +%{_libdir}/ocaml/stublibs/dllv2v_test_harness.so.owner + + %files bash-completion %dir %{_datadir}/bash-completion/completions %{_datadir}/bash-completion/completions/guestfish @@ -1193,8 +1246,8 @@ popd %exclude %{_libdir}/ocaml/guestfs/*.cmxa %exclude %{_libdir}/ocaml/guestfs/*.cmx %exclude %{_libdir}/ocaml/guestfs/*.mli -%{_libdir}/ocaml/stublibs/*.so -%{_libdir}/ocaml/stublibs/*.so.owner +%{_libdir}/ocaml/stublibs/dllmlguestfs.so +%{_libdir}/ocaml/stublibs/dllmlguestfs.so.owner %files -n ocaml-%{name}-devel @@ -1317,6 +1370,10 @@ popd %changelog +* Thu Mar 12 2015 Richard W.M. Jones - 1:1.29.30-2 +- Add virt-v2v-test-harness subpackage. +- Add a couple of upstream patches to fix the virt-v2v test harness. + * Wed Mar 11 2015 Richard W.M. Jones - 1:1.29.30-1 - New upstream version 1.29.30.