Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce client object in python tests #772

Merged
merged 5 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 55 additions & 19 deletions test/py/libvfio_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#

from types import SimpleNamespace
import collections.abc
import ctypes as c
import array
import errno
Expand Down Expand Up @@ -685,25 +686,60 @@ def connect_sock():
return sock


def connect_client(ctx):
sock = connect_sock()

json = b'{ "capabilities": { "max_msg_fds": 8 } }'
# struct vfio_user_version
payload = struct.pack("HH%dsc" % len(json), LIBVFIO_USER_MAJOR,
LIBVFIO_USER_MINOR, json, b'\0')
hdr = vfio_user_header(VFIO_USER_VERSION, size=len(payload))
sock.send(hdr + payload)
vfu_attach_ctx(ctx, expect=0)
payload = get_reply(sock, expect=0)
return sock


def disconnect_client(ctx, sock):
sock.close()

# notice client closed connection
vfu_run_ctx(ctx, errno.ENOTCONN)
class Client:
"""Models a VFIO-user client connected to the server under test."""

def __init__(self, sock=None):
self.sock = sock
self.client_cmd_socket = None

def connect(self, ctx, capabilities={}):
self.sock = connect_sock()

effective_caps = {
"capabilities": {
"max_data_xfer_size": VFIO_USER_DEFAULT_MAX_DATA_XFER_SIZE,
"max_msg_fds": 8,
"twin_socket": False,
mnissler-rivos marked this conversation as resolved.
Show resolved Hide resolved
},
}

def update(target, overrides):
for k, v in overrides.items():
if isinstance(v, collections.abc.Mapping):
target[k] = target.get(k, {})
update(target[k], v)
else:
target[k] = v

update(effective_caps, capabilities)
caps_json = json.dumps(effective_caps)

# struct vfio_user_version
payload = struct.pack("HH%dsc" % len(caps_json), LIBVFIO_USER_MAJOR,
LIBVFIO_USER_MINOR, caps_json.encode(), b'\0')
hdr = vfio_user_header(VFIO_USER_VERSION, size=len(payload))
self.sock.send(hdr + payload)
vfu_attach_ctx(ctx, expect=0)
fds, payload = get_reply_fds(self.sock, expect=0)
self.client_cmd_socket = socket.socket(fileno=fds[0]) if fds else None
mnissler-rivos marked this conversation as resolved.
Show resolved Hide resolved
return self.sock

def disconnect(self, ctx):
self.sock.close()
self.sock = None
if self.client_cmd_socket is not None:
mnissler-rivos marked this conversation as resolved.
Show resolved Hide resolved
self.client_cmd_socket.close()
self.client_cmd_socket = None

# notice client closed connection
vfu_run_ctx(ctx, errno.ENOTCONN)


def connect_client(*args, **kwargs):
client = Client()
client.connect(*args, **kwargs)
return client


def get_reply(sock, expect=0):
Expand Down
4 changes: 2 additions & 2 deletions test/py/test_destroy.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@


def setup_function(function):
global ctx, sock
global ctx, client
ctx = prepare_ctx_for_dma()
assert ctx is not None
sock = connect_client(ctx)
client = connect_client(ctx)


def teardown_function(function):
Expand Down
10 changes: 5 additions & 5 deletions test/py/test_device_get_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,27 @@ def test_device_get_info():

# test short write

sock = connect_client(ctx)
client = connect_client(ctx)

payload = struct.pack("II", 0, 0)

msg(ctx, sock, VFIO_USER_DEVICE_GET_INFO, payload,
msg(ctx, client.sock, VFIO_USER_DEVICE_GET_INFO, payload,
expect=errno.EINVAL)

# bad argsz

payload = vfio_user_device_info(argsz=8, flags=0,
num_regions=0, num_irqs=0)

msg(ctx, sock, VFIO_USER_DEVICE_GET_INFO, payload,
msg(ctx, client.sock, VFIO_USER_DEVICE_GET_INFO, payload,
expect=errno.EINVAL)

# valid with larger argsz

payload = vfio_user_device_info(argsz=32, flags=0,
num_regions=0, num_irqs=0)

result = msg(ctx, sock, VFIO_USER_DEVICE_GET_INFO, payload)
result = msg(ctx, client.sock, VFIO_USER_DEVICE_GET_INFO, payload)

(argsz, flags, num_regions, num_irqs) = struct.unpack("IIII", result)

Expand All @@ -78,7 +78,7 @@ def test_device_get_info():
assert num_regions == VFU_PCI_DEV_NUM_REGIONS
assert num_irqs == VFU_DEV_NUM_IRQS

disconnect_client(ctx, sock)
client.disconnect(ctx)

vfu_destroy_ctx(ctx)

Expand Down
22 changes: 11 additions & 11 deletions test/py/test_device_get_irq_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
import errno

ctx = None
sock = None
client = None

argsz = len(vfio_irq_info())


def test_device_get_irq_info_setup():
global ctx, sock
global ctx, client

ctx = vfu_create_ctx(flags=LIBVFIO_USER_FLAG_ATTACH_NB)
assert ctx is not None
Expand All @@ -55,27 +55,27 @@ def test_device_get_irq_info_setup():
ret = vfu_realize_ctx(ctx)
assert ret == 0

sock = connect_client(ctx)
client = connect_client(ctx)


def test_device_get_irq_info_bad_in():
payload = struct.pack("II", 0, 0)

msg(ctx, sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload,
msg(ctx, client.sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload,
expect=errno.EINVAL)

# bad argsz
payload = vfio_irq_info(argsz=8, flags=0, index=VFU_DEV_REQ_IRQ,
count=0)

msg(ctx, sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload,
msg(ctx, client.sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload,
expect=errno.EINVAL)

# bad index
payload = vfio_irq_info(argsz=argsz, flags=0, index=VFU_DEV_NUM_IRQS,
count=0)

msg(ctx, sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload,
msg(ctx, client.sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload,
expect=errno.EINVAL)


Expand All @@ -86,12 +86,12 @@ def test_device_get_irq_info():
payload = vfio_irq_info(argsz=argsz + 16, flags=0, index=VFU_DEV_REQ_IRQ,
count=0)

msg(ctx, sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)
msg(ctx, client.sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)

payload = vfio_irq_info(argsz=argsz, flags=0, index=VFU_DEV_REQ_IRQ,
count=0)

result = msg(ctx, sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)
result = msg(ctx, client.sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)

info, _ = vfio_irq_info.pop_from_buffer(result)

Expand All @@ -103,7 +103,7 @@ def test_device_get_irq_info():
payload = vfio_irq_info(argsz=argsz, flags=0, index=VFU_DEV_ERR_IRQ,
count=0)

result = msg(ctx, sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)
result = msg(ctx, client.sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)

info, _ = vfio_irq_info.pop_from_buffer(result)

Expand All @@ -115,7 +115,7 @@ def test_device_get_irq_info():
payload = vfio_irq_info(argsz=argsz, flags=0, index=VFU_DEV_MSIX_IRQ,
count=0)

result = msg(ctx, sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)
result = msg(ctx, client.sock, VFIO_USER_DEVICE_GET_IRQ_INFO, payload)

info, _ = vfio_irq_info.pop_from_buffer(result)

Expand All @@ -126,7 +126,7 @@ def test_device_get_irq_info():


def test_device_get_irq_info_cleanup():
disconnect_client(ctx, sock)
client.disconnect(ctx)

vfu_destroy_ctx(ctx)

Expand Down
Loading