All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: John Levon <john.levon@nutanix.com>
Cc: qemu-devel@nongnu.org, "Cédric Le Goater" <clg@redhat.com>,
	"Thanos Makatos" <thanos.makatos@nutanix.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Zhao Liu" <zhao1.liu@intel.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Mark Cave-Ayland" <mark.caveayland@nutanix.com>
Subject: Re: [PATCH v4 3/3] tests/functional: add a vfio-user smoke test
Date: Mon, 8 Sep 2025 15:42:35 +0100	[thread overview]
Message-ID: <aL7rW6Tq9d-z8sGL@redhat.com> (raw)
In-Reply-To: <20250903201931.168317-4-john.levon@nutanix.com>

On Wed, Sep 03, 2025 at 10:19:31PM +0200, John Levon wrote:
> From: Mark Cave-Ayland <mark.caveayland@nutanix.com>
> 
> Add a basic test of the vfio-user PCI client implementation.
> 
> Co-authored-by: John Levon <john.levon@nutanix.com>
> Signed-off-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
> Signed-off-by: John Levon <john.levon@nutanix.com>
> ---
>  MAINTAINERS                                   |   1 +
>  tests/functional/x86_64/meson.build           |   1 +
>  .../x86_64/test_vfio_user_client.py           | 207 ++++++++++++++++++
>  3 files changed, 209 insertions(+)
>  create mode 100755 tests/functional/x86_64/test_vfio_user_client.py
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1ae28e8804..9987ac8a4d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4305,6 +4305,7 @@ F: docs/system/devices/vfio-user.rst
>  F: hw/vfio-user/*
>  F: include/hw/vfio-user/*
>  F: subprojects/libvfio-user
> +F: tests/functional/x86_64/test_vfio_user_client.py
>  
>  EBPF:
>  M: Jason Wang <jasowang@redhat.com>
> diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/meson.build
> index d0b4667bb8..eed1936976 100644
> --- a/tests/functional/x86_64/meson.build
> +++ b/tests/functional/x86_64/meson.build
> @@ -31,6 +31,7 @@ tests_x86_64_system_thorough = [
>    'replay',
>    'reverse_debug',
>    'tuxrun',
> +  'vfio_user_client',
>    'virtio_balloon',
>    'virtio_gpu',
>  ]
> diff --git a/tests/functional/x86_64/test_vfio_user_client.py b/tests/functional/x86_64/test_vfio_user_client.py
> new file mode 100755
> index 0000000000..a9cb2f4621
> --- /dev/null
> +++ b/tests/functional/x86_64/test_vfio_user_client.py
> @@ -0,0 +1,207 @@


> +    def prepare_images(self):
> +        """Set up the images for the VMs."""
> +        self.kernel_path = self.ASSET_KERNEL.fetch()
> +        rootfs_path = self.ASSET_ROOTFS.fetch()
> +
> +        self.server_rootfs_path = self.scratch_file('server.ext2')
> +        shutil.copy(rootfs_path, self.server_rootfs_path)
> +        os.chmod(self.server_rootfs_path, 0o600)
> +        self.client_rootfs_path = self.scratch_file('client.ext2')
> +        shutil.copy(rootfs_path, self.client_rootfs_path)
> +        os.chmod(self.client_rootfs_path, 0o600)

So copying the read-only asset to a writable file in the scratchdir....

> +
> +    def configure_server_vm_args(self, server_vm, sock_path):
> +        """
> +        Configuration for the server VM. Set up virtio-serial device backed by
> +        the given socket path.
> +        """
> +        server_vm.add_args('-kernel', self.kernel_path)
> +        server_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
> +        server_vm.add_args('-drive',
> +            f"file={self.server_rootfs_path},if=ide,format=raw,id=drv0")
> +        server_vm.add_args('-snapshot')

..but here you're using -snapshot, so surely the copying of the asset
into the scratch dir is not required ?

> +        server_vm.add_args('-chardev',
> +            f"socket,id=sock0,path={sock_path},telnet=off,server=on,wait=off")
> +        server_vm.add_args('-device', 'virtio-serial')
> +        server_vm.add_args('-device',
> +            'virtserialport,chardev=sock0,name=org.fedoraproject.port.0')
> +
> +    def configure_client_vm_args(self, client_vm, sock_path):
> +        """
> +        Configuration for the client VM. Point the vfio-user-pci device to the
> +        socket path configured above.
> +        """
> +
> +        client_vm.add_args('-kernel', self.kernel_path)
> +        client_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
> +        client_vm.add_args('-drive',
> +            f'file={self.client_rootfs_path},if=ide,format=raw,id=drv0')

...but  no using of -snapshot here, so copying the asset would be
required?

Can we just use -snapshot in both cases & avoid the copying ?

> +        client_vm.add_args('-device',
> +            '{"driver":"vfio-user-pci",' +
> +            '"socket":{"path": "%s", "type": "unix"}}' % sock_path)
> +

> +    def setup_vfio_user_pci_server(self, server_vm):
> +        """
> +        Start the libvfio-user server within the server VM, and arrange
> +        for data to shuttle between its socket and the virtio serial port.
> +        """
> +        wait_for_console_pattern(self, 'login:', None, server_vm)
> +        exec_command_and_wait_for_pattern(self, 'root', '#', None, server_vm)
> +
> +        exec_command_and_wait_for_pattern(self,
> +            'gpio-pci-idio-16 -v /tmp/vfio-user.sock >/var/tmp/gpio.out 2>&1 &',
> +            '#', None, server_vm)
> +        # wait for libvfio-user to initialize properly
> +        exec_command_and_wait_for_pattern(self, 'sleep 5', '#', None, server_vm)
> +        exec_command_and_wait_for_pattern(self,
> +            'socat UNIX-CONNECT:/tmp/vfio-user.sock /dev/vport0p1,ignoreeof ' +
> +            ' &', '#', None, server_vm)

Hardcoded socket paths in /tmp ...

> +
> +    def test_vfio_user_pci(self):
> +        self.prepare_images()
> +        self.set_machine('pc')
> +        self.require_device('virtio-serial')
> +        self.require_device('vfio-user-pci')
> +
> +        sock_dir = self.socket_dir()
> +        socket_path = sock_dir.name + '/vfio-user.sock'
> +        socket_path = '/tmp/vfio-user.sock'

This isn't honouring the temporary dir for the socket files.
This temp dir needs to be passed into setup_vfio_user_pci_server

> +
> +        server_vm = self.get_vm(name='server')
> +        server_vm.set_console()
> +        self.configure_server_vm_args(server_vm, socket_path)
> +
> +        server_vm.launch()
> +
> +        self.log.debug('starting libvfio-user server')
> +
> +        self.setup_vfio_user_pci_server(server_vm)
> +
> +        client_vm = self.get_vm(name="client")
> +        client_vm.set_console()
> +        self.configure_client_vm_args(client_vm, socket_path)
> +
> +        try:
> +            client_vm.launch()
> +        except:
> +            self.log.error('client VM failed to start, dumping server logs')
> +            exec_command_and_wait_for_pattern(self, 'cat /var/tmp/gpio.out',
> +                '#', None, server_vm)
> +            raise
> +
> +        self.log.debug('waiting for client VM boot')
> +
> +        wait_for_console_pattern(self, 'login:', None, client_vm)
> +        exec_command_and_wait_for_pattern(self, 'root', '#', None, client_vm)
> +
> +        #
> +        # Here, we'd like to actually interact with the gpio device a little
> +        # more as described at:
> +        #
> +        # https://github.com/nutanix/libvfio-user/blob/master/docs/qemu.md
> +        #
> +        # Unfortunately, the buildroot Linux kernel has some undiagnosed issue
> +        # so we don't get /sys/class/gpio. Nonetheless just the basic
> +        # initialization and setup is enough for basic testing of vfio-user.
> +        #
> +
> +        self.log.debug('collecting libvfio-user server output')
> +
> +        out = exec_command_and_wait_for_pattern(self,
> +            'cat /var/tmp/gpio.out',
> +            'gpio: region2: wrote 0 to (0x1:1)',
> +            None, server_vm)
> +
> +        pattern = re.compile(r'^gpio:')

Use of 're' is overkill here...

> +
> +        gpio_server_out = [s for s in out.decode().splitlines()
> +                                   if pattern.search(s)]

......  as this can just use s.startswith("gpio:")

> +
> +        for line in EXPECTED_SERVER_LINES:
> +            if line not in gpio_server_out:
> +                self.log.error(f'Missing server debug line: {line}')
> +                self.fail(False)
> +
> +
> +if __name__ == '__main__':
> +    QemuSystemTest.main()
> -- 
> 2.43.0
> 

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  reply	other threads:[~2025-09-08 14:44 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-03 20:19 [PATCH v4 0/3] vfio-user client functional test John Levon
2025-09-03 20:19 ` [PATCH v4 1/3] tests/functional: return output from cmd.py helpers John Levon
2025-09-08 14:32   ` Daniel P. Berrangé
2025-09-03 20:19 ` [PATCH v4 2/3] tests/functional: add vm param to " John Levon
2025-09-08 14:33   ` Daniel P. Berrangé
2025-09-03 20:19 ` [PATCH v4 3/3] tests/functional: add a vfio-user smoke test John Levon
2025-09-08 14:42   ` Daniel P. Berrangé [this message]
2025-09-09 14:44     ` John Levon
2025-09-09 13:58 ` [PATCH v4 0/3] vfio-user client functional test Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aL7rW6Tq9d-z8sGL@redhat.com \
    --to=berrange@redhat.com \
    --cc=clg@redhat.com \
    --cc=john.levon@nutanix.com \
    --cc=mark.caveayland@nutanix.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=thanos.makatos@nutanix.com \
    --cc=thuth@redhat.com \
    --cc=zhao1.liu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.