Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2019
- 82 participants
- 1927 messages
[PATCH] testbot/BackupVM: A script for backing up a Libvirt/QEmu VM.
by Francois Gouget
The script supports backing up to either a borg repository, possibly
remote, the deduplication makes this ideal for backups; or tar files,
which is more suited for archival.
By default the script will refuse to perform the backup if it foundi
no snapshots. If that's expected pass the --no-snapshot option.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/scripts/BackupVM | 362 +++++++++++++++++++++++++++++++++++++++
1 file changed, 362 insertions(+)
create mode 100755 testbot/scripts/BackupVM
diff --git a/testbot/scripts/BackupVM b/testbot/scripts/BackupVM
new file mode 100755
index 00000000..2cf3320d
--- /dev/null
+++ b/testbot/scripts/BackupVM
@@ -0,0 +1,362 @@
+#!/bin/sh
+#
+# Creates a backup of a QEMU/LibVirt VM.
+#
+# Copyright 2013-2019 Francois Gouget
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+name0=`basename "$0"`
+
+etcdir="etc/libvirt/qemu"
+snapdir="var/lib/libvirt/qemu/snapshot"
+
+
+#
+# Generic helpers
+#
+
+error()
+{
+ echo "$name0:error:" "$@" >&2
+}
+
+warning()
+{
+ echo "$name0:warning:" "$@" >&2
+}
+
+opt_dry_run=""
+opt_verbose=""
+dry_run()
+{
+ [ -n "$opt_verbose$opt_dry_run" ] && echo "$@"
+ if [ -z "$opt_dry_run" ]
+ then
+ "$@"
+ fi
+}
+
+
+#
+# Process the command line
+#
+
+check_opt_val()
+{
+ option="$1"
+ var="$2"
+ argc="$3"
+
+ if [ -n "$var" ]
+ then
+ error "$option can only be specified once"
+ usage=2 # but continue processing options
+ fi
+ if [ $argc -eq 0 ]
+ then
+ error "missing value for $option"
+ usage=2
+ return 1
+ fi
+ return 0
+}
+
+opt_vm=""
+opt_suffix=""
+opt_snapshot="1"
+opt_borg=""
+opt_connect=""
+usage=""
+while [ $# -gt 0 ]
+do
+ arg="$1"
+ shift
+ case "$arg" in
+ --borg)
+ if check_opt_val "$arg" "$opt_borg" $#
+ then
+ opt_borg="$1"
+ shift
+ fi
+ ;;
+ --snapshot)
+ opt_snapshot="1"
+ ;;
+ --no-snapshot)
+ opt_snapshot=""
+ ;;
+ --connect)
+ if check_opt_val "$arg" "$opt_connect" $#
+ then
+ opt_connect="$1"
+ shift
+ fi
+ ;;
+ --verbose)
+ opt_verbose="1"
+ ;;
+ --dry-run)
+ opt_dry_run="1"
+ ;;
+ -\?|-h|--help)
+ usage=0
+ ;;
+ -*)
+ error "unknown option '$arg'"
+ usage=2
+ break
+ ;;
+ *)
+ if [ -z "$opt_vm" ]
+ then
+ opt_vm="$arg"
+ elif [ -z "$opt_suffix" ]
+ then
+ opt_suffix="$arg"
+ else
+ error "only one VM and suffix can be specified."
+ usage=2
+ fi
+ ;;
+ esac
+done
+
+if [ -z "$usage" ]
+then
+ if [ -z "$opt_vm" ]
+ then
+ error "you must specify the name of the VM to backup."
+ usage=2
+ fi
+ [ -n "$opt_connect" ] || opt_connect="qemu:///system"
+fi
+
+if [ -n "$usage" ]
+then
+ if [ "$usage" != "0" ]
+ then
+ error "try '$name0 --help' for more information"
+ exit $usage
+ fi
+ cat <<EOF
+Usage: $name0 [--no-snapshot] [--verbose] [--dry-run] [--help] [--borg REPO]
+ [--connect URI] VMNAME [SUFFIX]
+
+Creates a backup of the specified VM.
+This must be run as root on the VM host.
+
+Where:
+ VMNAME The name of the VM to backup.
+ SUFFIX A (short) string to add to the backup name. This can help
+ provide an indication of what features were added to this
+ backup.
+ --borg REPO The borg repository to backup to.
+ --no-snapshot It is ok for the VM to have no snapshot.
+ --connect URI Connect to the specified Libvirt server.
+ --verbose Show all the commands as they are being run.
+ --dry-run Show what would happen but do not extract or change anything.
+ --help, -h Shows this help message.
+EOF
+ exit 0
+fi
+
+
+#
+# Prepare the backup
+#
+
+get_vm_disk_images()
+{
+ _root="$1"
+ _vm="$2"
+ sed -e "s~^ *<source file='\([^']*\)' */> *\$~\\1~" -e t -e d "$_root$etcdir/$_vm.xml" "$_root$snapdir/$_vm"/*.xml | sort | uniq
+}
+
+get_symlink_closure()
+{
+ while read file
+ do
+ echo "$file"
+ while [ -h "$file" ]
+ do
+ target=`readlink "$file"`
+ case "$target" in
+ /*) file="$target" ;;
+ *) file=`dirname "$file"`"/$target" ;;
+ esac
+ echo "$file"
+ done
+ done
+}
+
+if [ ! -r "/$etcdir/$opt_vm.xml" ]
+then
+ error "the '/$etcdir/$opt_vm.xml' configuration file is not readable"
+ exit 2
+fi
+
+snapshots=`echo "/$snapdir/$opt_vm"/*.xml`
+if [ -n "$opt_snapshot" -a "$snapshots" = "/$snapdir/$opt_vm/*.xml" ]
+then
+ error "the '$opt_vm' VM does not seem to have snapshots! Use --no-snapshot if this is expected."
+ exit 2
+fi
+
+# Backup the symbolic links but also their targets!
+disks=`get_vm_disk_images "/" "$opt_vm" 2>/dev/null | get_symlink_closure | sort | uniq`
+if [ -z "$disks" ]
+then
+ error "could not find the disk images."
+ exit 2
+fi
+
+confs=`for file in "/$etcdir/$opt_vm.xml" $snapshots; do echo $file; done | get_symlink_closure`
+
+errors=""
+all_paths=""
+echo "$opt_vm uses the following files and directories:"
+for file in $confs $disks
+do
+ all_paths="$all_paths $file"
+ echo " $file"
+ if [ ! -r "$file" ]
+ then
+ error "'$file' is not readable."
+ errors=1
+ fi
+done
+[ -z "$errors" ] || exit 1
+echo
+
+
+#
+# Wait for the VM
+#
+
+fatal()
+{
+ error "$@"
+ exit 1
+}
+
+wait_for_vm()
+{
+ _vm="$1"
+ _timeout="$2"
+
+ while true
+ do
+ _state=`(virsh --connect "$opt_connect" list --all 2>/dev/null || echo " $_vm error") | sed -e "s/^.* $_vm *//" -e t -e d`
+ [ -z "$opt_dry_run" ] || _state="shut off"
+ case "$_state" in
+ "error")
+ echo "nolibvirt"
+ return
+ ;;
+ "")
+ echo "novm"
+ return
+ ;;
+ "shut off")
+ echo "off"
+ return
+ ;;
+ esac
+
+ echo "$_vm is not powered off ($_state). Waiting for up to ${_timeout}s..." >&2
+ _timeout=`expr $_timeout - 10`
+ if [ $_timeout -le 0 ]
+ then
+ echo "running"
+ return
+ fi
+ sleep 10
+ done
+}
+
+# Note that we don't actually care whether libvirt knows about the VM since
+# we know which files to backup anyway.
+case `wait_for_vm "$opt_vm" 120` in
+nolibvirt)
+ warning "Could not connect to libvirt. Assuming $opt_vm is not running."
+ ;;
+running)
+ fatal "$opt_vm is running. Try again when it has been powered off."
+ ;;
+esac
+
+
+#
+# Do the backup
+#
+
+nice=""
+which ionice >/dev/null && nice="ionice"
+which nice >/dev/null && nice="nice $nice"
+
+backup="libvirt-$opt_vm-`date +%Y%m%d`"
+[ -n "$opt_suffix" ] && backup="$backup-$opt_suffix"
+
+if [ -n "$opt_borg" ]
+then
+ borg_opts=""
+ [ -n "$opt_verbose" ] && borg_opts="$borg_opts --verbose"
+ dry_run $nice borg create --progress --stats -C lzma,9 \
+ "$opt_borg::$backup" $all_paths
+ rc_borg=$?
+ if [ $rc_borg -ne 0 ]
+ then
+ fatal "an error occurred while saving the VM (borg=$rc_borg)"
+ fi
+ echo "Saved $opt_vm to '$opt_borg::$backup'"
+
+else
+ zipcmd=pbzip2
+ which pbzip2 >/dev/null || zipcmd=bzip2
+
+ tar_opts=""
+ [ -n "$opt_verbose" ] && tar_opts="-v"
+ if [ -n "$opt_verbose$opt_dry_run" ]
+ then
+ echo "$nice tar cf - $tar_opts $all_paths | $nice $zipcmd -9 | $nice split -d -b 2146435072 - '$backup.tar.bz2.'"
+ fi
+
+ if [ -n "$opt_dry_run" ]
+ then
+ rc_tar=0
+ rc_zip=0
+ rc_split=0
+ else
+ ($nice tar cf - $tar_opts $all_paths; echo $? >"rc_tar" ) | \
+ ($nice $zipcmd -9; echo $? >"rc_zip") | \
+ $nice split -d -b 2146435072 - "$backup.tar.bz2."
+ rc_split=$?
+ rc_zip=`cat "rc_zip"`
+ rc_tar=`cat "rc_tar"`
+ rm -f "rc_tar" "rc_zip"
+ fi
+ if [ "$rc_tar" != "0" -o "$rc_zip" != "0" -o "$rc_split" != "0" ]
+ then
+ fatal "an error occurred while saving the VM (tar=$rc_tar zip=$rc_zip split=$rc_split)"
+ fi
+ echo "Saved $opt_vm to '$backup.tar.bz2.*'"
+fi
+
+case `wait_for_vm "$opt_vm" 0` in
+running)
+ fatal "$opt_vm is running. The backup may be bad."
+ ;;
+esac
--
2.20.1
April 1, 2019
[PATCH] testbot: Document the Net::OpenSSH dependency.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/doc/INSTALL.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/doc/INSTALL.txt b/testbot/doc/INSTALL.txt
index bae1e825..456ffe69 100644
--- a/testbot/doc/INSTALL.txt
+++ b/testbot/doc/INSTALL.txt
@@ -9,7 +9,7 @@ Dependencies:
- Sys::Virt (libsys-virt-perl, see http://libvirt.org/)
- Image::Magick (perlmagick)
- Optional: IO::Socket::IP (for IPv6, libio-socket-ip-perl)
-- Optional: Net::SSH2 (for SSH tunneling, libnet-ssh2-perl)
+- Optional: Net::OpenSSH (for SSH tunneling, libnet-openssh-perl)
MySQL setup:
- Create a new 'winetestbot' database and its tables using the
--
2.20.1
April 1, 2019
[PATCH 5/5] quartz/tests: Add some tests for video renderer pin interfaces.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/videorenderer.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index 3d3d939cdb..c7f0df4d16 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -58,6 +58,7 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO
static void test_interfaces(void)
{
IBaseFilter *filter = create_video_renderer();
+ IPin *pin;
check_interface(filter, &IID_IBaseFilter, TRUE);
check_interface(filter, &IID_IBasicVideo, TRUE);
@@ -81,6 +82,20 @@ static void test_interfaces(void)
check_interface(filter, &IID_IPin, FALSE);
check_interface(filter, &IID_IReferenceClock, FALSE);
+ IBaseFilter_FindPin(filter, sink_id, &pin);
+
+ check_interface(pin, &IID_IMemInputPin, TRUE);
+ todo_wine check_interface(pin, &IID_IOverlay, TRUE);
+ check_interface(pin, &IID_IPin, TRUE);
+ todo_wine check_interface(pin, &IID_IPinConnection, TRUE);
+ todo_wine check_interface(pin, &IID_IQualityControl, TRUE);
+ check_interface(pin, &IID_IUnknown, TRUE);
+
+ check_interface(pin, &IID_IAsyncReader, FALSE);
+ check_interface(pin, &IID_IMediaPosition, FALSE);
+ todo_wine check_interface(pin, &IID_IMediaSeeking, FALSE);
+
+ IPin_Release(pin);
IBaseFilter_Release(filter);
}
--
2.20.1
April 1, 2019
[PATCH 4/5] quartz/tests: Add some tests for querying video renderer pin information.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/videorenderer.c | 48 +++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index 7315d8d0e2..3d3d939cdb 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -207,6 +207,53 @@ static void test_find_pin(void)
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
+static void test_pin_info(void)
+{
+ static const WCHAR sink_name[] = {'I','n','p','u','t',0};
+ IBaseFilter *filter = create_video_renderer();
+ PIN_DIRECTION dir;
+ PIN_INFO info;
+ HRESULT hr;
+ WCHAR *id;
+ ULONG ref;
+ IPin *pin;
+
+ hr = IBaseFilter_FindPin(filter, sink_id, &pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ref = get_refcount(filter);
+ todo_wine ok(ref == 2, "Got unexpected refcount %d.\n", ref);
+ ref = get_refcount(pin);
+ ok(ref == 2, "Got unexpected refcount %d.\n", ref);
+
+ hr = IPin_QueryPinInfo(pin, &info);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
+ ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
+todo_wine
+ ok(!lstrcmpW(info.achName, sink_name), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ ref = get_refcount(filter);
+ todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref);
+ ref = get_refcount(pin);
+ todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref);
+ IBaseFilter_Release(info.pFilter);
+
+ hr = IPin_QueryDirection(pin, &dir);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
+
+ hr = IPin_QueryId(pin, &id);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
+ CoTaskMemFree(id);
+
+ hr = IPin_QueryInternalConnections(pin, NULL, NULL);
+ ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
+
+ IPin_Release(pin);
+ ref = IBaseFilter_Release(filter);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
+
static void test_pin(IPin *pin)
{
IMemInputPin *mpin = NULL;
@@ -270,6 +317,7 @@ START_TEST(videorenderer)
test_interfaces();
test_enum_pins();
test_find_pin();
+ test_pin_info();
test_basefilter();
CoUninitialize();
--
2.20.1
April 1, 2019
[PATCH 3/5] quartz/tests: Add some tests for IBaseFilter_FindPin() on the video renderer.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/videorenderer.c | 32 +++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index c4e64ec6b5..7315d8d0e2 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -22,6 +22,8 @@
#include "dshow.h"
#include "wine/test.h"
+static const WCHAR sink_id[] = {'I','n',0};
+
static IBaseFilter *create_video_renderer(void)
{
IBaseFilter *filter = NULL;
@@ -176,6 +178,35 @@ todo_wine
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
+static void test_find_pin(void)
+{
+ static const WCHAR input_pinW[] = {'i','n','p','u','t',' ','p','i','n',0};
+ IBaseFilter *filter = create_video_renderer();
+ IEnumPins *enum_pins;
+ IPin *pin, *pin2;
+ HRESULT hr;
+ ULONG ref;
+
+ hr = IBaseFilter_FindPin(filter, input_pinW, &pin);
+ ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr);
+
+ hr = IBaseFilter_FindPin(filter, sink_id, &pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IBaseFilter_EnumPins(filter, &enum_pins);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(pin == pin2, "Expected pin %p, got %p.\n", pin2, pin);
+ IPin_Release(pin);
+ IPin_Release(pin2);
+
+ IEnumPins_Release(enum_pins);
+ ref = IBaseFilter_Release(filter);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
+
static void test_pin(IPin *pin)
{
IMemInputPin *mpin = NULL;
@@ -238,6 +269,7 @@ START_TEST(videorenderer)
test_interfaces();
test_enum_pins();
+ test_find_pin();
test_basefilter();
CoUninitialize();
--
2.20.1
April 1, 2019
[PATCH 2/5] quartz/tests: Add some tests for IBaseFilter_EnumPins() on the video renderer.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/videorenderer.c | 102 ++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index e487e65ef6..c4e64ec6b5 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -31,6 +31,13 @@ static IBaseFilter *create_video_renderer(void)
return filter;
}
+static ULONG get_refcount(void *iface)
+{
+ IUnknown *unknown = iface;
+ IUnknown_AddRef(unknown);
+ return IUnknown_Release(unknown);
+}
+
#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
{
@@ -75,6 +82,100 @@ static void test_interfaces(void)
IBaseFilter_Release(filter);
}
+
+static void test_enum_pins(void)
+{
+ IBaseFilter *filter = create_video_renderer();
+ IEnumPins *enum1, *enum2;
+ IPin *pins[2];
+ ULONG count;
+ HRESULT hr;
+ ULONG ref;
+
+ ref = get_refcount(filter);
+ ok(ref == 1, "Got unexpected refcount %d.\n", ref);
+
+ hr = IBaseFilter_EnumPins(filter, NULL);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+
+ hr = IBaseFilter_EnumPins(filter, &enum1);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ref = get_refcount(filter);
+ ok(ref == 2, "Got unexpected refcount %d.\n", ref);
+ ref = get_refcount(enum1);
+ ok(ref == 1, "Got unexpected refcount %d.\n", ref);
+
+ hr = IEnumPins_Next(enum1, 1, NULL, NULL);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Next(enum1, 1, pins, NULL);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ref = get_refcount(filter);
+todo_wine
+ ok(ref == 3, "Got unexpected refcount %d.\n", ref);
+ ref = get_refcount(pins[0]);
+todo_wine
+ ok(ref == 3, "Got unexpected refcount %d.\n", ref);
+ ref = get_refcount(enum1);
+ ok(ref == 1, "Got unexpected refcount %d.\n", ref);
+ IPin_Release(pins[0]);
+ ref = get_refcount(filter);
+ ok(ref == 2, "Got unexpected refcount %d.\n", ref);
+
+ hr = IEnumPins_Next(enum1, 1, pins, NULL);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Reset(enum1);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Next(enum1, 1, pins, &count);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(count == 1, "Got count %u.\n", count);
+ IPin_Release(pins[0]);
+
+ hr = IEnumPins_Next(enum1, 1, pins, &count);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+ ok(!count, "Got count %u.\n", count);
+
+ hr = IEnumPins_Reset(enum1);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Next(enum1, 2, pins, NULL);
+ ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Next(enum1, 2, pins, &count);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+ ok(count == 1, "Got count %u.\n", count);
+ IPin_Release(pins[0]);
+
+ hr = IEnumPins_Reset(enum1);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Clone(enum1, &enum2);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Skip(enum1, 2);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Skip(enum1, 1);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Skip(enum1, 1);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Next(enum1, 1, pins, NULL);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+
+ hr = IEnumPins_Next(enum2, 1, pins, NULL);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ IPin_Release(pins[0]);
+
+ IEnumPins_Release(enum2);
+ IEnumPins_Release(enum1);
+ ref = IBaseFilter_Release(filter);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
+
static void test_pin(IPin *pin)
{
IMemInputPin *mpin = NULL;
@@ -136,6 +237,7 @@ START_TEST(videorenderer)
CoInitialize(NULL);
test_interfaces();
+ test_enum_pins();
test_basefilter();
CoUninitialize();
--
2.20.1
April 1, 2019
[PATCH 1/5] quartz/tests: Clean up tests for video renderer filter interfaces.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/videorenderer.c | 115 ++++++++++++------------------
1 file changed, 46 insertions(+), 69 deletions(-)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index 35e6f10185..e487e65ef6 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -19,71 +19,60 @@
*/
#define COBJMACROS
-
-#include "wine/test.h"
#include "dshow.h"
+#include "wine/test.h"
-#define QI_SUCCEED(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \
- ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); \
- ok(ppv != NULL, "Pointer is NULL\n");
-
-#define RELEASE_EXPECT(iface, num) if (iface) { \
- hr = IUnknown_Release((IUnknown*)iface); \
- ok(hr == num, "IUnknown_Release should return %d, got %d\n", num, hr); \
-}
-
-static IUnknown *pVideoRenderer = NULL;
-
-static int create_video_renderer(void)
+static IBaseFilter *create_video_renderer(void)
{
- HRESULT hr;
-
- hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
- &IID_IUnknown, (LPVOID*)&pVideoRenderer);
- return (hr == S_OK && pVideoRenderer != NULL);
+ IBaseFilter *filter = NULL;
+ HRESULT hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IBaseFilter, (void **)&filter);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ return filter;
}
-static void release_video_renderer(void)
+#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
+static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
{
- HRESULT hr;
+ IUnknown *iface = iface_ptr;
+ HRESULT hr, expected_hr;
+ IUnknown *unk;
+
+ expected_hr = supported ? S_OK : E_NOINTERFACE;
- hr = IUnknown_Release(pVideoRenderer);
- ok(hr == 0, "IUnknown_Release failed with %x\n", hr);
+ hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
+ ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
+ if (SUCCEEDED(hr))
+ IUnknown_Release(unk);
}
-static void test_query_interface(void)
+static void test_interfaces(void)
{
- HRESULT hr;
- IBaseFilter *pBaseFilter = NULL;
- IBasicVideo *pBasicVideo = NULL;
- IDirectDrawVideo *pDirectDrawVideo = NULL;
- IKsPropertySet *pKsPropertySet = NULL;
- IMediaPosition *pMediaPosition = NULL;
- IMediaSeeking *pMediaSeeking = NULL;
- IQualityControl *pQualityControl = NULL;
- IQualProp *pQualProp = NULL;
- IVideoWindow *pVideoWindow = NULL;
-
- QI_SUCCEED(pVideoRenderer, IID_IBaseFilter, pBaseFilter);
- RELEASE_EXPECT(pBaseFilter, 1);
- QI_SUCCEED(pVideoRenderer, IID_IBasicVideo, pBasicVideo);
- RELEASE_EXPECT(pBasicVideo, 1);
- QI_SUCCEED(pVideoRenderer, IID_IMediaSeeking, pMediaSeeking);
- RELEASE_EXPECT(pMediaSeeking, 1);
- QI_SUCCEED(pVideoRenderer, IID_IQualityControl, pQualityControl);
- RELEASE_EXPECT(pQualityControl, 1);
- todo_wine {
- QI_SUCCEED(pVideoRenderer, IID_IDirectDrawVideo, pDirectDrawVideo);
- RELEASE_EXPECT(pDirectDrawVideo, 1);
- QI_SUCCEED(pVideoRenderer, IID_IKsPropertySet, pKsPropertySet);
- RELEASE_EXPECT(pKsPropertySet, 1);
- QI_SUCCEED(pVideoRenderer, IID_IQualProp, pQualProp);
- RELEASE_EXPECT(pQualProp, 1);
- }
- QI_SUCCEED(pVideoRenderer, IID_IMediaPosition, pMediaPosition);
- RELEASE_EXPECT(pMediaPosition, 1);
- QI_SUCCEED(pVideoRenderer, IID_IVideoWindow, pVideoWindow);
- RELEASE_EXPECT(pVideoWindow, 1);
+ IBaseFilter *filter = create_video_renderer();
+
+ check_interface(filter, &IID_IBaseFilter, TRUE);
+ check_interface(filter, &IID_IBasicVideo, TRUE);
+ todo_wine check_interface(filter, &IID_IBasicVideo2, TRUE);
+ todo_wine check_interface(filter, &IID_IDirectDrawVideo, TRUE);
+ todo_wine check_interface(filter, &IID_IKsPropertySet, TRUE);
+ check_interface(filter, &IID_IMediaFilter, TRUE);
+ check_interface(filter, &IID_IMediaPosition, TRUE);
+ check_interface(filter, &IID_IMediaSeeking, TRUE);
+ check_interface(filter, &IID_IPersist, TRUE);
+ check_interface(filter, &IID_IQualityControl, TRUE);
+ todo_wine check_interface(filter, &IID_IQualProp, TRUE);
+ check_interface(filter, &IID_IUnknown, TRUE);
+ check_interface(filter, &IID_IVideoWindow, TRUE);
+
+ todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
+ check_interface(filter, &IID_IBasicAudio, FALSE);
+ check_interface(filter, &IID_IDispatch, FALSE);
+ check_interface(filter, &IID_IOverlay, FALSE);
+ check_interface(filter, &IID_IPersistPropertyBag, FALSE);
+ check_interface(filter, &IID_IPin, FALSE);
+ check_interface(filter, &IID_IReferenceClock, FALSE);
+
+ IBaseFilter_Release(filter);
}
static void test_pin(IPin *pin)
@@ -105,19 +94,11 @@ static void test_pin(IPin *pin)
static void test_basefilter(void)
{
IEnumPins *pin_enum = NULL;
- IBaseFilter *base = NULL;
+ IBaseFilter *base = create_video_renderer();
IPin *pins[2];
ULONG ref;
HRESULT hr;
- IUnknown_QueryInterface(pVideoRenderer, &IID_IBaseFilter, (void **)&base);
- if (base == NULL)
- {
- /* test_query_interface handles this case */
- skip("No IBaseFilter\n");
- return;
- }
-
hr = IBaseFilter_EnumPins(base, NULL);
ok(hr == E_POINTER, "hr = %08x and not E_POINTER\n", hr);
@@ -153,13 +134,9 @@ static void test_basefilter(void)
START_TEST(videorenderer)
{
CoInitialize(NULL);
- if (!create_video_renderer())
- return;
- test_query_interface();
+ test_interfaces();
test_basefilter();
- release_video_renderer();
-
CoUninitialize();
}
--
2.20.1
April 1, 2019