diff mbox series

[v2,20/20] tests: add some virtio-gpu & vhost-user-gpu acceptance test

Message ID 20210204105232.834642-21-marcandre.lureau@redhat.com (mailing list archive)
State New, archived
Headers show
Series Various vhost-user-gpu & UI fixes | expand

Commit Message

Marc-André Lureau Feb. 4, 2021, 10:52 a.m. UTC
From: Marc-André Lureau <marcandre.lureau@redhat.com>

This will check virtio/vhost-user-vga & virgl are correctly initialized
by the Linux kernel on an egl-headless display.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/acceptance/virtio-gpu.py | 161 +++++++++++++++++++++++++++++++++
 1 file changed, 161 insertions(+)
 create mode 100644 tests/acceptance/virtio-gpu.py

Comments

Alex Bennée Feb. 16, 2021, 4:34 p.m. UTC | #1
marcandre.lureau@redhat.com writes:

> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> This will check virtio/vhost-user-vga & virgl are correctly initialized
> by the Linux kernel on an egl-headless display.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  tests/acceptance/virtio-gpu.py | 161 +++++++++++++++++++++++++++++++++
>  1 file changed, 161 insertions(+)
>  create mode 100644 tests/acceptance/virtio-gpu.py

This failed when I got to master:

  2021-02-16 14:33:46,266 qmp              L0255 DEBUG| >>> {'execute': 'qmp_capabilities'}
  2021-02-16 14:33:46,441 machine          L0385 DEBUG| Error launching VM
  2021-02-16 14:33:46,441 machine          L0387 DEBUG| Command: './qemu-system-x86_64 -display none -vga none -chardev socket,id=mon,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu
  -29492-monitor.sock -mon chardev=mon,mode=control -chardev socket,id=console,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu-29492-console.sock,server=on,wait=off -serial chardev:
  console -cpu host -m 2G -machine pc,accel=kvm -device virtio-vga,virgl=on -display egl-headless -kernel /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d8
  1e1c0bf204ecebe555bb/vmlinuz -initrd /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d81e1c0bf204ecebe555bb/initrd.img -append printk.time=0 console=ttyS0
   rdinit=/bin/bash'
  2021-02-16 14:33:46,441 machine          L0389 DEBUG| Output: "qemu-system-x86_64: -device virtio-vga,virgl=on: Property 'virtio-vga.virgl' not found\n"
  2021-02-16 14:33:46,441 stacktrace       L0039 ERROR|

I'm going to assume this is because the beefy server I was building on
didn't have the VirGL headers to enable this feature. In lieu of feature
probing you might have to do what I did for the plugins test:

        try:
            vm.launch()
        except:
            # TODO: probably fails because plugins not enabled but we
            # can't currently probe for the feature.
            self.cancel("TCG Plugins not enabled?")


>
> diff --git a/tests/acceptance/virtio-gpu.py b/tests/acceptance/virtio-gpu.py
> new file mode 100644
> index 0000000000..211f02932f
> --- /dev/null
> +++ b/tests/acceptance/virtio-gpu.py
> @@ -0,0 +1,161 @@
> +# virtio-gpu tests
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or
> +# later.  See the COPYING file in the top-level directory.
> +
> +
> +from avocado_qemu import Test
> +from avocado_qemu import BUILD_DIR
> +from avocado_qemu import wait_for_console_pattern
> +from avocado_qemu import exec_command_and_wait_for_pattern
> +from avocado_qemu import is_readable_executable_file
> +
> +from qemu.accel import kvm_available
> +
> +import os
> +import socket
> +import subprocess
> +
> +
> +ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
> +KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
> +
> +
> +def pick_default_vug_bin():
> +    relative_path = "./contrib/vhost-user-gpu/vhost-user-gpu"
> +    if is_readable_executable_file(relative_path):
> +        return relative_path
> +
> +    bld_dir_path = os.path.join(BUILD_DIR, relative_path)
> +    if is_readable_executable_file(bld_dir_path):
> +        return bld_dir_path
> +
> +
> +class VirtioGPUx86(Test):
> +    """
> +    :avocado: tags=virtio-gpu
> +    """
> +
> +    KERNEL_COMMON_COMMAND_LINE = "printk.time=0 "
> +    KERNEL_URL = (
> +        "https://archives.fedoraproject.org/pub/fedora"
> +        "/linux/releases/33/Everything/x86_64/os/images"
> +        "/pxeboot/vmlinuz"
> +    )
> +    INITRD_URL = (
> +        "https://archives.fedoraproject.org/pub/fedora"
> +        "/linux/releases/33/Everything/x86_64/os/images"
> +        "/pxeboot/initrd.img"
> +    )
> +
> +    def wait_for_console_pattern(self, success_message, vm=None):
> +        wait_for_console_pattern(
> +            self,
> +            success_message,
> +            failure_message="Kernel panic - not syncing",
> +            vm=vm,
> +        )
> +
> +    def test_virtio_vga_virgl(self):
> +        """
> +        :avocado: tags=arch:x86_64
> +        :avocado: tags=device:virtio-vga
> +        """
> +        kernel_command_line = (
> +            self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash"
> +        )
> +        # FIXME: should check presence of virtio, virgl etc
> +        if not kvm_available(self.arch, self.qemu_bin):
> +            self.cancel(KVM_NOT_AVAILABLE)
> +
> +        kernel_path = self.fetch_asset(self.KERNEL_URL)
> +        initrd_path = self.fetch_asset(self.INITRD_URL)
> +
> +        self.vm.set_console()
> +        self.vm.add_args("-cpu", "host")
> +        self.vm.add_args("-m", "2G")
> +        self.vm.add_args("-machine", "pc,accel=kvm")
> +        self.vm.add_args("-device", "virtio-vga,virgl=on")
> +        self.vm.add_args("-display", "egl-headless")
> +        self.vm.add_args(
> +            "-kernel",
> +            kernel_path,
> +            "-initrd",
> +            initrd_path,
> +            "-append",
> +            kernel_command_line,
> +        )
> +        self.vm.launch()
> +        self.wait_for_console_pattern("as init process")
> +        exec_command_and_wait_for_pattern(
> +            self, "/usr/sbin/modprobe virtio_gpu", ""
> +        )
> +        self.wait_for_console_pattern("features: +virgl +edid")
> +
> +    def test_vhost_user_vga_virgl(self):
> +        """
> +        :avocado: tags=arch:x86_64
> +        :avocado: tags=device:vhost-user-vga
> +        """
> +        kernel_command_line = (
> +            self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash"
> +        )
> +        # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc
> +        if not kvm_available(self.arch, self.qemu_bin):
> +            self.cancel(KVM_NOT_AVAILABLE)
> +
> +        vug = pick_default_vug_bin()
> +        if not vug:
> +            self.cancel("Could not find vhost-user-gpu")
> +
> +        kernel_path = self.fetch_asset(self.KERNEL_URL)
> +        initrd_path = self.fetch_asset(self.INITRD_URL)
> +
> +        # Create socketpair to connect proxy and remote processes
> +        qemu_sock, vug_sock = socket.socketpair(
> +            socket.AF_UNIX, socket.SOCK_STREAM
> +        )
> +        os.set_inheritable(qemu_sock.fileno(), True)
> +        os.set_inheritable(vug_sock.fileno(), True)
> +
> +        self._vug_log_path = os.path.join(
> +            self.vm._test_dir, "vhost-user-gpu.log"
> +        )
> +        self._vug_log_file = open(self._vug_log_path, "wb")
> +        print(self._vug_log_path)
> +
> +        vugp = subprocess.Popen(
> +            [vug, "--virgl", "--fd=%d" % vug_sock.fileno()],
> +            stdin=subprocess.DEVNULL,
> +            stdout=self._vug_log_file,
> +            stderr=subprocess.STDOUT,
> +            shell=False,
> +            close_fds=False,
> +        )
> +
> +        self.vm.set_console()
> +        self.vm.add_args("-cpu", "host")
> +        self.vm.add_args("-m", "2G")
> +        self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G")
> +        self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm")
> +        self.vm.add_args("-chardev", "socket,id=vug,fd=%d" % qemu_sock.fileno())
> +        self.vm.add_args("-device", "vhost-user-vga,chardev=vug")
> +        self.vm.add_args("-display", "egl-headless")
> +        self.vm.add_args(
> +            "-kernel",
> +            kernel_path,
> +            "-initrd",
> +            initrd_path,
> +            "-append",
> +            kernel_command_line,
> +        )
> +        self.vm.launch()
> +        self.wait_for_console_pattern("as init process")
> +        exec_command_and_wait_for_pattern(
> +            self, "/usr/sbin/modprobe virtio_gpu", ""
> +        )
> +        self.wait_for_console_pattern("features: +virgl -edid")
> +        self.vm.shutdown()
> +        qemu_sock.close()
> +        vugp.terminate()
> +        vugp.wait()
Cleber Rosa Feb. 16, 2021, 5:43 p.m. UTC | #2
On Tue, Feb 16, 2021 at 04:34:06PM +0000, Alex Bennée wrote:
> 
> marcandre.lureau@redhat.com writes:
> 
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > This will check virtio/vhost-user-vga & virgl are correctly initialized
> > by the Linux kernel on an egl-headless display.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >  tests/acceptance/virtio-gpu.py | 161 +++++++++++++++++++++++++++++++++
> >  1 file changed, 161 insertions(+)
> >  create mode 100644 tests/acceptance/virtio-gpu.py
> 
> This failed when I got to master:
> 
>   2021-02-16 14:33:46,266 qmp              L0255 DEBUG| >>> {'execute': 'qmp_capabilities'}
>   2021-02-16 14:33:46,441 machine          L0385 DEBUG| Error launching VM
>   2021-02-16 14:33:46,441 machine          L0387 DEBUG| Command: './qemu-system-x86_64 -display none -vga none -chardev socket,id=mon,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu
>   -29492-monitor.sock -mon chardev=mon,mode=control -chardev socket,id=console,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu-29492-console.sock,server=on,wait=off -serial chardev:
>   console -cpu host -m 2G -machine pc,accel=kvm -device virtio-vga,virgl=on -display egl-headless -kernel /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d8
>   1e1c0bf204ecebe555bb/vmlinuz -initrd /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d81e1c0bf204ecebe555bb/initrd.img -append printk.time=0 console=ttyS0
>    rdinit=/bin/bash'
>   2021-02-16 14:33:46,441 machine          L0389 DEBUG| Output: "qemu-system-x86_64: -device virtio-vga,virgl=on: Property 'virtio-vga.virgl' not found\n"
>   2021-02-16 14:33:46,441 stacktrace       L0039 ERROR|
> 
> I'm going to assume this is because the beefy server I was building on
> didn't have the VirGL headers to enable this feature. In lieu of feature
> probing you might have to do what I did for the plugins test:
> 
>         try:
>             vm.launch()
>         except:
>             # TODO: probably fails because plugins not enabled but we
>             # can't currently probe for the feature.
>             self.cancel("TCG Plugins not enabled?")
> 
>

While this pattern is indeed an improvement over test errors, checking
for "build time features" is far from a new testing requirement, and
its still not properly solved.  A long time ago I proposed a way to
look at the Makefile variables during test time, but it had a number
of shortcomings.  I guess it's now time to revisit this issue.

First, I'm a strong believer in limiting the *probing* that the test itself
does with regards to build time features.  The probing and authoritative
information should already be with the build system.  I'm pretty sure that
meson makes it easy to grab that kind of information.

Once it's understood and agreed that the build system will provide
that information, the question becomes whether tests will get that
information from the build system (and thus require a build tree) or
if that information will be persisted in the QEMU binary and be
available for introspection.

Thoughts? Does this sound like something other people would be
interested in?

Regards,
- Cleber.
Marc-André Lureau Feb. 17, 2021, 8:27 a.m. UTC | #3
Hi

On Tue, Feb 16, 2021 at 9:43 PM Cleber Rosa <crosa@redhat.com> wrote:

> On Tue, Feb 16, 2021 at 04:34:06PM +0000, Alex Bennée wrote:
> >
> > marcandre.lureau@redhat.com writes:
> >
> > > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> > >
> > > This will check virtio/vhost-user-vga & virgl are correctly initialized
> > > by the Linux kernel on an egl-headless display.
> > >
> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > ---
> > >  tests/acceptance/virtio-gpu.py | 161 +++++++++++++++++++++++++++++++++
> > >  1 file changed, 161 insertions(+)
> > >  create mode 100644 tests/acceptance/virtio-gpu.py
> >
> > This failed when I got to master:
> >
> >   2021-02-16 14:33:46,266 qmp              L0255 DEBUG| >>> {'execute':
> 'qmp_capabilities'}
> >   2021-02-16 14:33:46,441 machine          L0385 DEBUG| Error launching
> VM
> >   2021-02-16 14:33:46,441 machine          L0387 DEBUG| Command:
> './qemu-system-x86_64 -display none -vga none -chardev
> socket,id=mon,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu
> >   -29492-monitor.sock -mon chardev=mon,mode=control -chardev
> socket,id=console,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu-29492-console.sock,server=on,wait=off
> -serial chardev:
> >   console -cpu host -m 2G -machine pc,accel=kvm -device
> virtio-vga,virgl=on -display egl-headless -kernel
> /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d8
> >   1e1c0bf204ecebe555bb/vmlinuz -initrd
> /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d81e1c0bf204ecebe555bb/initrd.img
> -append printk.time=0 console=ttyS0
> >    rdinit=/bin/bash'
> >   2021-02-16 14:33:46,441 machine          L0389 DEBUG| Output:
> "qemu-system-x86_64: -device virtio-vga,virgl=on: Property
> 'virtio-vga.virgl' not found\n"
> >   2021-02-16 14:33:46,441 stacktrace       L0039 ERROR|
> >
> > I'm going to assume this is because the beefy server I was building on
> > didn't have the VirGL headers to enable this feature. In lieu of feature
> > probing you might have to do what I did for the plugins test:
> >
> >         try:
> >             vm.launch()
> >         except:
> >             # TODO: probably fails because plugins not enabled but we
> >             # can't currently probe for the feature.
> >             self.cancel("TCG Plugins not enabled?")
> >
> >
>
> While this pattern is indeed an improvement over test errors, checking
> for "build time features" is far from a new testing requirement, and
> its still not properly solved.  A long time ago I proposed a way to
> look at the Makefile variables during test time, but it had a number
> of shortcomings.  I guess it's now time to revisit this issue.
>
> First, I'm a strong believer in limiting the *probing* that the test itself
> does with regards to build time features.  The probing and authoritative
> information should already be with the build system.  I'm pretty sure that
> meson makes it easy to grab that kind of information.
>
> Once it's understood and agreed that the build system will provide
> that information, the question becomes whether tests will get that
> information from the build system (and thus require a build tree) or
> if that information will be persisted in the QEMU binary and be
> available for introspection.
>
> Thoughts? Does this sound like something other people would be
> interested in?
>

It would be more reliable and flexible to do runtime introspection. It
would allow installed tests, and some runtime checks for example.

Given the variability of builds, is there something that does introspection
in avocado-vt already?  I think we could rely on qmp introspection,
qom-list-types etc.

In the meantime Alex, could you send a patch to ignore the test the way you
propose?
Alex Bennée Feb. 17, 2021, 12:12 p.m. UTC | #4
Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Hi
>
> On Tue, Feb 16, 2021 at 9:43 PM Cleber Rosa <crosa@redhat.com> wrote:
>
>> On Tue, Feb 16, 2021 at 04:34:06PM +0000, Alex Bennée wrote:
>> >
>> > marcandre.lureau@redhat.com writes:
>> >
>> > > From: Marc-André Lureau <marcandre.lureau@redhat.com>
>> > >
>> > > This will check virtio/vhost-user-vga & virgl are correctly initialized
>> > > by the Linux kernel on an egl-headless display.
>> > >
>> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> > > ---
>> > >  tests/acceptance/virtio-gpu.py | 161 +++++++++++++++++++++++++++++++++
>> > >  1 file changed, 161 insertions(+)
>> > >  create mode 100644 tests/acceptance/virtio-gpu.py
>> >
>> > This failed when I got to master:
>> >
>> >   2021-02-16 14:33:46,266 qmp              L0255 DEBUG| >>> {'execute':
>> 'qmp_capabilities'}
>> >   2021-02-16 14:33:46,441 machine          L0385 DEBUG| Error launching
>> VM
>> >   2021-02-16 14:33:46,441 machine          L0387 DEBUG| Command:
>> './qemu-system-x86_64 -display none -vga none -chardev
>> socket,id=mon,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu
>> >   -29492-monitor.sock -mon chardev=mon,mode=control -chardev
>> socket,id=console,path=/var/tmp/avo_qemu_sock_xy9ndjnm/qemu-29492-console.sock,server=on,wait=off
>> -serial chardev:
>> >   console -cpu host -m 2G -machine pc,accel=kvm -device
>> virtio-vga,virgl=on -display egl-headless -kernel
>> /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d8
>> >   1e1c0bf204ecebe555bb/vmlinuz -initrd
>> /home/alex.bennee/avocado/data/cache/by_location/892ae21f3ae7d04994d81e1c0bf204ecebe555bb/initrd.img
>> -append printk.time=0 console=ttyS0
>> >    rdinit=/bin/bash'
>> >   2021-02-16 14:33:46,441 machine          L0389 DEBUG| Output:
>> "qemu-system-x86_64: -device virtio-vga,virgl=on: Property
>> 'virtio-vga.virgl' not found\n"
>> >   2021-02-16 14:33:46,441 stacktrace       L0039 ERROR|
>> >
>> > I'm going to assume this is because the beefy server I was building on
>> > didn't have the VirGL headers to enable this feature. In lieu of feature
>> > probing you might have to do what I did for the plugins test:
>> >
>> >         try:
>> >             vm.launch()
>> >         except:
>> >             # TODO: probably fails because plugins not enabled but we
>> >             # can't currently probe for the feature.
>> >             self.cancel("TCG Plugins not enabled?")
>> >
>> >
>>
>> While this pattern is indeed an improvement over test errors, checking
>> for "build time features" is far from a new testing requirement, and
>> its still not properly solved.  A long time ago I proposed a way to
>> look at the Makefile variables during test time, but it had a number
>> of shortcomings.  I guess it's now time to revisit this issue.
>>
>> First, I'm a strong believer in limiting the *probing* that the test itself
>> does with regards to build time features.  The probing and authoritative
>> information should already be with the build system.  I'm pretty sure that
>> meson makes it easy to grab that kind of information.
>>
>> Once it's understood and agreed that the build system will provide
>> that information, the question becomes whether tests will get that
>> information from the build system (and thus require a build tree) or
>> if that information will be persisted in the QEMU binary and be
>> available for introspection.
>>
>> Thoughts? Does this sound like something other people would be
>> interested in?
>>
>
> It would be more reliable and flexible to do runtime introspection. It
> would allow installed tests, and some runtime checks for example.
>
> Given the variability of builds, is there something that does introspection
> in avocado-vt already?  I think we could rely on qmp introspection,
> qom-list-types etc.
>
> In the meantime Alex, could you send a patch to ignore the test the way you
> propose?

Sure.
diff mbox series

Patch

diff --git a/tests/acceptance/virtio-gpu.py b/tests/acceptance/virtio-gpu.py
new file mode 100644
index 0000000000..211f02932f
--- /dev/null
+++ b/tests/acceptance/virtio-gpu.py
@@ -0,0 +1,161 @@ 
+# virtio-gpu tests
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+
+from avocado_qemu import Test
+from avocado_qemu import BUILD_DIR
+from avocado_qemu import wait_for_console_pattern
+from avocado_qemu import exec_command_and_wait_for_pattern
+from avocado_qemu import is_readable_executable_file
+
+from qemu.accel import kvm_available
+
+import os
+import socket
+import subprocess
+
+
+ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
+KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
+
+
+def pick_default_vug_bin():
+    relative_path = "./contrib/vhost-user-gpu/vhost-user-gpu"
+    if is_readable_executable_file(relative_path):
+        return relative_path
+
+    bld_dir_path = os.path.join(BUILD_DIR, relative_path)
+    if is_readable_executable_file(bld_dir_path):
+        return bld_dir_path
+
+
+class VirtioGPUx86(Test):
+    """
+    :avocado: tags=virtio-gpu
+    """
+
+    KERNEL_COMMON_COMMAND_LINE = "printk.time=0 "
+    KERNEL_URL = (
+        "https://archives.fedoraproject.org/pub/fedora"
+        "/linux/releases/33/Everything/x86_64/os/images"
+        "/pxeboot/vmlinuz"
+    )
+    INITRD_URL = (
+        "https://archives.fedoraproject.org/pub/fedora"
+        "/linux/releases/33/Everything/x86_64/os/images"
+        "/pxeboot/initrd.img"
+    )
+
+    def wait_for_console_pattern(self, success_message, vm=None):
+        wait_for_console_pattern(
+            self,
+            success_message,
+            failure_message="Kernel panic - not syncing",
+            vm=vm,
+        )
+
+    def test_virtio_vga_virgl(self):
+        """
+        :avocado: tags=arch:x86_64
+        :avocado: tags=device:virtio-vga
+        """
+        kernel_command_line = (
+            self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash"
+        )
+        # FIXME: should check presence of virtio, virgl etc
+        if not kvm_available(self.arch, self.qemu_bin):
+            self.cancel(KVM_NOT_AVAILABLE)
+
+        kernel_path = self.fetch_asset(self.KERNEL_URL)
+        initrd_path = self.fetch_asset(self.INITRD_URL)
+
+        self.vm.set_console()
+        self.vm.add_args("-cpu", "host")
+        self.vm.add_args("-m", "2G")
+        self.vm.add_args("-machine", "pc,accel=kvm")
+        self.vm.add_args("-device", "virtio-vga,virgl=on")
+        self.vm.add_args("-display", "egl-headless")
+        self.vm.add_args(
+            "-kernel",
+            kernel_path,
+            "-initrd",
+            initrd_path,
+            "-append",
+            kernel_command_line,
+        )
+        self.vm.launch()
+        self.wait_for_console_pattern("as init process")
+        exec_command_and_wait_for_pattern(
+            self, "/usr/sbin/modprobe virtio_gpu", ""
+        )
+        self.wait_for_console_pattern("features: +virgl +edid")
+
+    def test_vhost_user_vga_virgl(self):
+        """
+        :avocado: tags=arch:x86_64
+        :avocado: tags=device:vhost-user-vga
+        """
+        kernel_command_line = (
+            self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash"
+        )
+        # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc
+        if not kvm_available(self.arch, self.qemu_bin):
+            self.cancel(KVM_NOT_AVAILABLE)
+
+        vug = pick_default_vug_bin()
+        if not vug:
+            self.cancel("Could not find vhost-user-gpu")
+
+        kernel_path = self.fetch_asset(self.KERNEL_URL)
+        initrd_path = self.fetch_asset(self.INITRD_URL)
+
+        # Create socketpair to connect proxy and remote processes
+        qemu_sock, vug_sock = socket.socketpair(
+            socket.AF_UNIX, socket.SOCK_STREAM
+        )
+        os.set_inheritable(qemu_sock.fileno(), True)
+        os.set_inheritable(vug_sock.fileno(), True)
+
+        self._vug_log_path = os.path.join(
+            self.vm._test_dir, "vhost-user-gpu.log"
+        )
+        self._vug_log_file = open(self._vug_log_path, "wb")
+        print(self._vug_log_path)
+
+        vugp = subprocess.Popen(
+            [vug, "--virgl", "--fd=%d" % vug_sock.fileno()],
+            stdin=subprocess.DEVNULL,
+            stdout=self._vug_log_file,
+            stderr=subprocess.STDOUT,
+            shell=False,
+            close_fds=False,
+        )
+
+        self.vm.set_console()
+        self.vm.add_args("-cpu", "host")
+        self.vm.add_args("-m", "2G")
+        self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G")
+        self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm")
+        self.vm.add_args("-chardev", "socket,id=vug,fd=%d" % qemu_sock.fileno())
+        self.vm.add_args("-device", "vhost-user-vga,chardev=vug")
+        self.vm.add_args("-display", "egl-headless")
+        self.vm.add_args(
+            "-kernel",
+            kernel_path,
+            "-initrd",
+            initrd_path,
+            "-append",
+            kernel_command_line,
+        )
+        self.vm.launch()
+        self.wait_for_console_pattern("as init process")
+        exec_command_and_wait_for_pattern(
+            self, "/usr/sbin/modprobe virtio_gpu", ""
+        )
+        self.wait_for_console_pattern("features: +virgl -edid")
+        self.vm.shutdown()
+        qemu_sock.close()
+        vugp.terminate()
+        vugp.wait()