aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Henderson <william.henderson@nutanix.com>2023-08-16 15:12:19 +0000
committerJohn Levon <john.levon@nutanix.com>2023-09-15 13:06:15 +0100
commitf43ef9703cb6ad6e5d7b6f0ac0a537ca71aa0b1d (patch)
tree9cc078a323839c9f76842a84f884be15eb97e2a9
parentecf1d0efaa998e0eb1ba3dde988b40f6bef1b880 (diff)
downloadlibvfio-user-f43ef9703cb6ad6e5d7b6f0ac0a537ca71aa0b1d.zip
libvfio-user-f43ef9703cb6ad6e5d7b6f0ac0a537ca71aa0b1d.tar.gz
libvfio-user-f43ef9703cb6ad6e5d7b6f0ac0a537ca71aa0b1d.tar.bz2
refactor: move a number of tests from C to Python
Signed-off-by: William Henderson <william.henderson@nutanix.com>
-rw-r--r--test/py/libvfio_user.py17
-rw-r--r--test/py/test_migration.py175
-rw-r--r--test/py/test_request_errors.py54
-rw-r--r--test/unit-tests.c335
4 files changed, 195 insertions, 386 deletions
diff --git a/test/py/libvfio_user.py b/test/py/libvfio_user.py
index 4e414cd..d586888 100644
--- a/test/py/libvfio_user.py
+++ b/test/py/libvfio_user.py
@@ -599,6 +599,14 @@ class vfio_user_device_feature_dma_logging_report(Structure):
]
+class vfio_user_mig_data(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("argsz", c.c_uint32),
+ ("size", c.c_uint32)
+ ]
+
+
class dma_sg_t(Structure):
_fields_ = [
("dma_addr", c.c_void_p),
@@ -711,10 +719,15 @@ def connect_sock():
return sock
-def connect_client(ctx):
+def connect_client(ctx, max_data_xfer_size=None):
sock = connect_sock()
- json = b'{ "capabilities": { "max_msg_fds": 8 } }'
+ if max_data_xfer_size is None:
+ json = b'{ "capabilities": { "max_msg_fds": 8 } }'
+ else:
+ json = b'{ "capabilities": { "max_msg_fds": 8, "max_data_xfer_size": '\
+ + str(max_data_xfer_size).encode("utf-8") + b' } }'
+
# struct vfio_user_version
payload = struct.pack("HH%dsc" % len(json), LIBVFIO_USER_MAJOR,
LIBVFIO_USER_MINOR, json, b'\0')
diff --git a/test/py/test_migration.py b/test/py/test_migration.py
index 83c941c..0a59bd3 100644
--- a/test/py/test_migration.py
+++ b/test/py/test_migration.py
@@ -1,7 +1,7 @@
#
-# Copyright (c) 2021 Nutanix Inc. All rights reserved.
+# Copyright (c) 2023 Nutanix Inc. All rights reserved.
#
-# Authors: John Levon <john.levon@nutanix.com>
+# Authors: William Henderson <william.henderson@nutanix.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -29,11 +29,15 @@
from libvfio_user import *
from collections import deque
+import ctypes
+import errno
ctx = None
sock = None
current_state = None
path = []
+read_data = None
+write_data = None
UNREACHABLE_STATES = {
@@ -68,13 +72,31 @@ def migr_trans_cb(_ctx, state):
@read_data_cb_t
-def migr_read_data_cb(_ctx, _buf, _count, _offset):
- return
+def migr_read_data_cb(_ctx, buf, count):
+ global read_data
+ length = min(count, len(read_data))
+ ctypes.memmove(buf, read_data, length)
+ read_data = None
+ return length
@write_data_cb_t
-def migr_write_data_cb(_ctx, _buf, _count, _offset):
- return
+def migr_write_data_cb(_ctx, buf, count):
+ global write_data
+ write_data = bytes(count)
+ ctypes.memmove(write_data, buf, count)
+ return count
+
+
+def transition_to_state(state, expect=0):
+ feature = vfio_user_device_feature(
+ argsz=len(vfio_user_device_feature()) +
+ len(vfio_user_device_feature_mig_state()),
+ flags=VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE
+ )
+ payload = vfio_user_device_feature_mig_state(device_state=state)
+ msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, bytes(feature) + bytes(payload),
+ expect=expect)
def test_migration_setup():
@@ -97,40 +119,26 @@ def test_migration_setup():
ret = vfu_realize_ctx(ctx)
assert ret == 0
- sock = connect_client(ctx)
+ sock = connect_client(ctx, 4)
def get_server_shortest_path(a, b, expectA=0, expectB=0):
- global ctx, sock, path
-
- feature = vfio_user_device_feature(
- argsz=len(vfio_user_device_feature()) +
- len(vfio_user_device_feature_mig_state()),
- flags=VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE
- )
+ global path
if current_state == VFIO_USER_DEVICE_STATE_STOP_COPY and \
a == VFIO_USER_DEVICE_STATE_PRE_COPY:
# The transition STOP_COPY -> PRE_COPY is explicitly blocked so we
# advance one state to get around this in order to set up the test.
- payload = vfio_user_device_feature_mig_state(
- device_state=VFIO_USER_DEVICE_STATE_STOP
- )
- msg(ctx, sock, VFIO_USER_DEVICE_FEATURE,
- bytes(feature) + bytes(payload))
+ transition_to_state(VFIO_USER_DEVICE_STATE_STOP)
- payload = vfio_user_device_feature_mig_state(device_state=a)
- msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, bytes(feature) + bytes(payload),
- expect=expectA)
+ transition_to_state(a, expect=expectA)
if expectA != 0:
return None
path = []
- payload = vfio_user_device_feature_mig_state(device_state=b)
- msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, bytes(feature) + bytes(payload),
- expect=expectB)
+ transition_to_state(b, expect=expectB)
return path.copy()
@@ -149,8 +157,6 @@ def test_migration_shortest_state_transition_paths():
by the implementation correctly follow these rules.
"""
- global ctx, sock
-
# states (vertices)
V = {VFIO_USER_DEVICE_STATE_ERROR, VFIO_USER_DEVICE_STATE_STOP,
VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_STOP_COPY,
@@ -218,38 +224,109 @@ def test_migration_shortest_state_transition_paths():
def test_migration_stop_copy_to_pre_copy_blocked():
- global ctx, sock
+ transition_to_state(VFIO_USER_DEVICE_STATE_STOP_COPY)
+ transition_to_state(VFIO_USER_DEVICE_STATE_PRE_COPY, expect=errno.EINVAL)
- feature = vfio_user_device_feature(
- argsz=len(vfio_user_device_feature()) +
- len(vfio_user_device_feature_mig_state()),
- flags=VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE
+
+def test_migration_nonexistent_state():
+ transition_to_state(0xabcd, expect=errno.EINVAL)
+
+
+def test_handle_mig_data_read():
+ global read_data
+
+ transition_to_state(VFIO_USER_DEVICE_STATE_RUNNING)
+
+ argsz = len(vfio_user_mig_data())
+
+ payload = vfio_user_mig_data(
+ argsz=argsz,
+ size=4
)
- payload = vfio_user_device_feature_mig_state(
- device_state=VFIO_USER_DEVICE_STATE_STOP_COPY
+
+ data = bytes([0, 1, 2, 3])
+
+ transition_to_state(VFIO_USER_DEVICE_STATE_PRE_COPY)
+ read_data = data
+ result = msg(ctx, sock, VFIO_USER_MIG_DATA_READ, payload)
+ assert len(result) == argsz + 4
+ assert result[argsz:argsz + 4] == data
+
+ transition_to_state(VFIO_USER_DEVICE_STATE_STOP_COPY)
+ read_data = data
+ result = msg(ctx, sock, VFIO_USER_MIG_DATA_READ, payload)
+ assert len(result) == argsz + 4
+ assert result[argsz:argsz + 4] == data
+
+
+def test_handle_mig_data_read_too_long():
+ global read_data
+
+ transition_to_state(VFIO_USER_DEVICE_STATE_RUNNING)
+
+ payload = vfio_user_mig_data(
+ argsz=len(vfio_user_mig_data()),
+ size=8
)
- msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, bytes(feature) + bytes(payload))
- payload = vfio_user_device_feature_mig_state(
- device_state=VFIO_USER_DEVICE_STATE_PRE_COPY
+ # When we set up the tests at the top of this file we specify that the max
+ # data transfer size is 4 bytes. Here we test to check that a transfer of 8
+ # bytes fails.
+
+ transition_to_state(VFIO_USER_DEVICE_STATE_PRE_COPY)
+ read_data = bytes([1, 2, 3, 4, 5, 6, 7, 8])
+ msg(ctx, sock, VFIO_USER_MIG_DATA_READ, payload, expect=errno.EINVAL)
+
+
+def test_handle_mig_data_read_invalid_state():
+ global read_data
+
+ payload = vfio_user_mig_data(
+ argsz=len(vfio_user_mig_data()),
+ size=4
)
- msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, bytes(feature) + bytes(payload),
- expect=22)
+ data = bytes([1, 2, 3, 4])
-def test_migration_nonexistent_state():
- global ctx, sock
+ transition_to_state(VFIO_USER_DEVICE_STATE_RUNNING)
+ read_data = data
+ msg(ctx, sock, VFIO_USER_MIG_DATA_READ, payload, expect=errno.EINVAL)
- feature = vfio_user_device_feature(
- argsz=len(vfio_user_device_feature()) +
- len(vfio_user_device_feature_mig_state()),
- flags=VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE
+ transition_to_state(VFIO_USER_DEVICE_STATE_STOP)
+ read_data = data
+ msg(ctx, sock, VFIO_USER_MIG_DATA_READ, payload, expect=errno.EINVAL)
+
+
+def test_handle_mig_data_write():
+ payload = vfio_user_mig_data(
+ argsz=len(vfio_user_mig_data()) + 4,
+ size=4
)
- payload = vfio_user_device_feature_mig_state(
- device_state=0xabcd
+
+ data = bytes([1, 2, 3, 4])
+
+ transition_to_state(VFIO_USER_DEVICE_STATE_RESUMING)
+ msg(ctx, sock, VFIO_USER_MIG_DATA_WRITE, bytes(payload) + data)
+ assert write_data == data
+
+
+def test_handle_mig_data_write_invalid_state():
+ payload = vfio_user_mig_data(
+ argsz=len(vfio_user_mig_data()) + 4,
+ size=4
)
- msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, bytes(feature) + bytes(payload),
- expect=22)
+
+ data = bytes([1, 2, 3, 4])
+
+ transition_to_state(VFIO_USER_DEVICE_STATE_RUNNING)
+ msg(ctx, sock, VFIO_USER_MIG_DATA_WRITE, bytes(payload) + data,
+ expect=errno.EINVAL)
+
+
+def test_device_feature_short_write():
+ payload = struct.pack("I", 8)
+
+ msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, payload, expect=errno.EINVAL)
def test_migration_cleanup():
diff --git a/test/py/test_request_errors.py b/test/py/test_request_errors.py
index 8a8c14c..a82174c 100644
--- a/test/py/test_request_errors.py
+++ b/test/py/test_request_errors.py
@@ -183,4 +183,58 @@ def test_disconnected_socket_quiesce_busy(mock_quiesce):
mock_quiesce.assert_called_once_with(ctx)
+@patch('libvfio_user.reset_cb')
+@patch('libvfio_user.quiesce_cb', side_effect=fail_with_errno(errno.EBUSY))
+@patch('libvfio_user.migr_trans_cb')
+def test_reply_fail_quiesce_busy(mock_migr_trans_cb, mock_quiesce,
+ mock_reset):
+ """Tests failing to reply and the quiesce callback returning EBUSY."""
+
+ global ctx, sock
+
+ def migr_trans_cb_side_effect(ctx, state):
+ sock.close()
+ return 0
+ mock_migr_trans_cb.side_effect = migr_trans_cb_side_effect
+
+ # change the state, it should close the socket causing the reply to fail
+ feature = vfio_user_device_feature(
+ argsz=len(vfio_user_device_feature()) +
+ len(vfio_user_device_feature_mig_state()),
+ flags=VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE
+ )
+ payload = vfio_user_device_feature_mig_state(
+ device_state=VFIO_USER_DEVICE_STATE_STOP_COPY
+ )
+ msg(ctx, sock, VFIO_USER_DEVICE_FEATURE, bytes(feature) + bytes(payload),
+ rsp=False, busy=True)
+
+ # vfu_run_ctx will try to reset the context and to do that it needs to
+ # quiesce the device first
+ mock_quiesce.assert_called_once_with(ctx)
+
+ # vfu_run_ctx will be returning EBUSY and nothing should have happened
+ # until the device quiesces
+ for _ in range(0, 3):
+ vfu_run_ctx(ctx, errno.EBUSY)
+ mock_quiesce.assert_called_once_with(ctx)
+ mock_reset.assert_not_called()
+
+ ret = vfu_device_quiesced(ctx, 0)
+ assert ret == 0
+
+ # the device quiesced, reset should should happen now
+ mock_quiesce.assert_called_once_with(ctx)
+ mock_reset.assert_called_once_with(ctx, VFU_RESET_LOST_CONN)
+
+ try:
+ get_reply(sock)
+ except OSError as e:
+ assert e.errno == errno.EBADF
+ else:
+ assert False
+
+ vfu_run_ctx(ctx, errno.ENOTCONN)
+
+
# ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: #
diff --git a/test/unit-tests.c b/test/unit-tests.c
index 580eb29..36faaf9 100644
--- a/test/unit-tests.c
+++ b/test/unit-tests.c
@@ -399,319 +399,6 @@ typedef struct {
} tran_sock_t;
static void
-test_migration_state_transitions(void **state UNUSED)
-{
- bool (*f)(uint32_t, uint32_t) = vfio_migr_state_transition_is_valid;
- uint32_t i;
-
- /* from ERROR: all transitions are invalid */
- for (i = 0; i < 8; i++) {
- assert_false(f(VFIO_USER_DEVICE_STATE_ERROR, i));
- }
-
- /* from STOP */
- assert_false(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_ERROR));
- assert_false(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_STOP));
- assert_true(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_RUNNING));
- assert_true(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_STOP_COPY));
- assert_true(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_RESUMING));
- assert_false(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_RUNNING_P2P));
- assert_false(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_PRE_COPY));
- assert_false(f(VFIO_USER_DEVICE_STATE_STOP, VFIO_USER_DEVICE_STATE_PRE_COPY_P2P));
-
- /* from RUNNING */
- assert_false(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_ERROR));
- assert_true(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_STOP));
- assert_false(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_RUNNING));
- assert_false(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_STOP_COPY));
- assert_false(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_RESUMING));
- assert_false(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_RUNNING_P2P));
- assert_true(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_PRE_COPY));
- assert_false(f(VFIO_USER_DEVICE_STATE_RUNNING, VFIO_USER_DEVICE_STATE_PRE_COPY_P2P));
-
- /* from STOP_COPY and RESUMING */
- for (i = 3; i < 5; i++) {
- assert_false(f(i, VFIO_USER_DEVICE_STATE_ERROR));
- assert_true(f(i, VFIO_USER_DEVICE_STATE_STOP));
- assert_false(f(i, VFIO_USER_DEVICE_STATE_RUNNING));
- assert_false(f(i, VFIO_USER_DEVICE_STATE_STOP_COPY));
- assert_false(f(i, VFIO_USER_DEVICE_STATE_RESUMING));
- assert_false(f(i, VFIO_USER_DEVICE_STATE_RUNNING_P2P));
- assert_false(f(i, VFIO_USER_DEVICE_STATE_PRE_COPY));
- assert_false(f(i, VFIO_USER_DEVICE_STATE_PRE_COPY_P2P));
- }
-
- /* from RUNNING_P2P: all transitions are invalid */
- for (i = 0; i < 8; i++) {
- assert_false(f(VFIO_USER_DEVICE_STATE_RUNNING_P2P, i));
- }
-
- /* from PRE_COPY */
- assert_false(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_ERROR));
- assert_false(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_STOP));
- assert_true(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_RUNNING));
- assert_true(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_STOP_COPY));
- assert_false(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_RESUMING));
- assert_false(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_RUNNING_P2P));
- assert_false(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_PRE_COPY));
- assert_false(f(VFIO_USER_DEVICE_STATE_PRE_COPY, VFIO_USER_DEVICE_STATE_PRE_COPY_P2P));
-
- /* from PRE_COPY_P2P: all transitions are invalid */
- for (i = 0; i < 8; i++) {
- assert_false(f(VFIO_USER_DEVICE_STATE_PRE_COPY_P2P, i));
- }
-}
-
-static vfu_migr_state_t LAST_STATE = -1;
-static void *LAST_WRITE = NULL;
-static int transition_callback(vfu_ctx_t *ctx UNUSED, vfu_migr_state_t state) {
- LAST_STATE = state;
- return 0;
-}
-static ssize_t read_callback(vfu_ctx_t *ctx UNUSED, void *buf, uint64_t count)
-{
- assert(count < 256);
- uint8_t *data = buf;
- for (uint8_t i = 0; i < count; i++) {
- *(data + i) = i;
- }
- return count;
-}
-static ssize_t write_callback(vfu_ctx_t *ctx UNUSED, void *buf, uint64_t count)
-{
- if (LAST_WRITE != NULL) {
- free(LAST_WRITE);
- }
-
- LAST_WRITE = malloc(count);
- memcpy(LAST_WRITE, buf, count);
- return count;
-}
-
-static struct test_setup_migr_reg_dat {
- vfu_ctx_t *v;
- const vfu_migration_callbacks_t c;
-} migr_reg_data = {
- .c = {
- .version = VFU_MIGR_CALLBACKS_VERS,
- .transition = transition_callback,
- .read_data = read_callback,
- .write_data = write_callback
- }
-};
-
-static int
-setup_test_setup_migration(void **state)
-{
- struct test_setup_migr_reg_dat *p = &migr_reg_data;
-
- p->v = vfu_create_ctx(VFU_TRANS_SOCK, "test", 0, NULL, VFU_DEV_TYPE_PCI);
- if (p->v == NULL) {
- return -1;
- }
-
- *state = p;
- return setup(state);
-}
-
-static int
-teardown_test_setup_migration(void **state) {
- struct test_setup_migr_reg_dat *p = *state;
- vfu_destroy_ctx(p->v);
-
- if (LAST_WRITE != NULL) {
- free(LAST_WRITE);
- LAST_WRITE = NULL;
- }
-
- return 0;
-}
-
-static void
-test_setup_migration_callbacks(void **state)
-{
- struct test_setup_migr_reg_dat *p = *state;
- int r = vfu_setup_device_migration_callbacks(p->v, &p->c);
- assert_int_equal(0, r);
- assert_non_null(p->v->migration);
- assert_int_equal(p->v->migration->state, VFIO_USER_DEVICE_STATE_RUNNING);
-}
-
-static void
-test_handle_device_state(void **state)
-{
- test_setup_migration_callbacks(state);
-
- struct test_setup_migr_reg_dat *p = *state;
- struct migration *migr = p->v->migration;
-
- assert(migr->state == VFIO_USER_DEVICE_STATE_RUNNING);
-
- int r;
-
- r = handle_device_state(p->v, migr, VFIO_USER_DEVICE_STATE_PRE_COPY, true);
- assert_int_equal(0, r);
- assert_int_equal(LAST_STATE, VFU_MIGR_STATE_PRE_COPY);
-
- r = handle_device_state(p->v, migr, VFIO_USER_DEVICE_STATE_STOP_COPY, true);
- assert_int_equal(0, r);
- assert_int_equal(LAST_STATE, VFU_MIGR_STATE_STOP_AND_COPY);
-
- r = handle_device_state(p->v, migr, VFIO_USER_DEVICE_STATE_STOP, true);
- assert_int_equal(0, r);
- assert_int_equal(LAST_STATE, VFU_MIGR_STATE_STOP);
-
- r = handle_device_state(p->v, migr, VFIO_USER_DEVICE_STATE_RUNNING, true);
- assert_int_equal(0, r);
- assert_int_equal(LAST_STATE, VFU_MIGR_STATE_RUNNING);
-}
-
-static void
-test_handle_mig_data_read(void **state)
-{
- test_setup_migration_callbacks(state);
-
- struct test_setup_migr_reg_dat *p = *state;
- struct migration *migr = p->v->migration;
-
- struct vfio_user_mig_data data = {
- .argsz = sizeof(data),
- .size = 4
- };
-
- vfu_msg_t *m = mkmsg(VFIO_USER_MIG_DATA_READ, &data, sizeof(data));
-
- uint8_t expect[4] = {0, 1, 2, 3};
-
- p->v->client_max_data_xfer_size = 4;
-
- ssize_t r;
-
- migr->state = VFIO_USER_DEVICE_STATE_PRE_COPY;
- r = handle_mig_data_read(p->v, m);
- assert_int_equal(4, r);
- assert_int_equal(0, memcmp(msg.out.iov.iov_base + sizeof(data), &expect, 4));
- free(msg.out.iov.iov_base);
-
- migr->state = VFIO_USER_DEVICE_STATE_STOP_COPY;
- r = handle_mig_data_read(p->v, m);
- assert_int_equal(4, r);
- assert_int_equal(0, memcmp(msg.out.iov.iov_base + sizeof(data), &expect, 4));
- free(msg.out.iov.iov_base);
-}
-
-static void
-test_handle_mig_data_read_too_long(void **state) {
- test_setup_migration_callbacks(state);
-
- struct test_setup_migr_reg_dat *p = *state;
- struct migration *migr = p->v->migration;
-
- struct vfio_user_mig_data data = {
- .argsz = sizeof(data),
- .size = 4
- };
-
- vfu_msg_t *m = mkmsg(VFIO_USER_MIG_DATA_READ, &data, sizeof(data));
-
- p->v->client_max_data_xfer_size = 2;
-
- ssize_t r;
-
- migr->state = VFIO_USER_DEVICE_STATE_PRE_COPY;
- r = handle_mig_data_read(p->v, m);
- assert_int_equal(-1, r);
-}
-
-static void
-test_handle_mig_data_read_invalid_state(void **state) {
- test_setup_migration_callbacks(state);
-
- struct test_setup_migr_reg_dat *p = *state;
- struct migration *migr = p->v->migration;
-
- struct vfio_user_mig_data data = {
- .argsz = sizeof(data),
- .size = 4
- };
-
- vfu_msg_t *m = mkmsg(VFIO_USER_MIG_DATA_READ, &data, sizeof(data));
-
- p->v->client_max_data_xfer_size = 4;
-
- ssize_t r;
-
- migr->state = VFIO_USER_DEVICE_STATE_RUNNING;
- r = handle_mig_data_read(p->v, m);
- assert_int_equal(-1, r);
-
- migr->state = VFIO_USER_DEVICE_STATE_STOP;
- r = handle_mig_data_read(p->v, m);
- assert_int_equal(-1, r);
-}
-
-static void
-test_handle_mig_data_write(void **state)
-{
- test_setup_migration_callbacks(state);
-
- struct test_setup_migr_reg_dat *p = *state;
- struct migration *migr = p->v->migration;
-
- uint8_t req[12] = {0};
-
- struct vfio_user_mig_data *data = (void*)&req;
- data->argsz = sizeof(req);
- data->size = 4;
-
- uint8_t *buf = (void*)data + sizeof(*data);
- for (int i = 0; i < 4; i++) {
- *(buf + i) = i;
- }
-
- vfu_msg_t *m = mkmsg(VFIO_USER_MIG_DATA_READ, &req, sizeof(req));
-
- p->v->client_max_data_xfer_size = 4;
-
- ssize_t r;
-
- migr->state = VFIO_USER_DEVICE_STATE_RESUMING;
- r = handle_mig_data_write(p->v, m);
- assert_int_equal(4, r);
- assert_int_equal(0, memcmp(LAST_WRITE, buf, 4));
-}
-
-static void
-test_handle_mig_data_write_invalid_state(void **state)
-{
- test_setup_migration_callbacks(state);
-
- struct test_setup_migr_reg_dat *p = *state;
- struct migration *migr = p->v->migration;
-
- uint8_t req[12] = {0};
-
- struct vfio_user_mig_data *data = (void*)&req;
- data->argsz = sizeof(req);
- data->size = 4;
-
- uint8_t *buf = (void*)data + sizeof(*data);
- for (int i = 0; i < 4; i++) {
- *(buf + i) = i;
- }
-
- vfu_msg_t *m = mkmsg(VFIO_USER_MIG_DATA_READ, &req, sizeof(req));
-
- p->v->client_max_data_xfer_size = 4;
-
- ssize_t r;
-
- migr->state = VFIO_USER_DEVICE_STATE_RUNNING;
- r = handle_mig_data_write(p->v, m);
- assert_int_equal(-1, r);
-}
-
-static void
test_device_is_stopped_and_copying(UNUSED void **state)
{
assert_false(device_is_stopped_and_copying(vfu_ctx.migration));
@@ -811,28 +498,6 @@ main(void)
cmocka_unit_test_setup(test_dma_controller_remove_region_unmapped, setup),
cmocka_unit_test_setup(test_dma_addr_to_sgl, setup),
cmocka_unit_test_setup(test_vfu_setup_device_dma, setup),
- cmocka_unit_test_setup(test_migration_state_transitions, setup),
- cmocka_unit_test_setup_teardown(test_setup_migration_callbacks,
- setup_test_setup_migration,
- teardown_test_setup_migration),
- cmocka_unit_test_setup_teardown(test_handle_device_state,
- setup_test_setup_migration,
- teardown_test_setup_migration),
- cmocka_unit_test_setup_teardown(test_handle_mig_data_read,
- setup_test_setup_migration,
- teardown_test_setup_migration),
- cmocka_unit_test_setup_teardown(test_handle_mig_data_read_too_long,
- setup_test_setup_migration,
- teardown_test_setup_migration),
- cmocka_unit_test_setup_teardown(test_handle_mig_data_read_invalid_state,
- setup_test_setup_migration,
- teardown_test_setup_migration),
- cmocka_unit_test_setup_teardown(test_handle_mig_data_write,
- setup_test_setup_migration,
- teardown_test_setup_migration),
- cmocka_unit_test_setup_teardown(test_handle_mig_data_write_invalid_state,
- setup_test_setup_migration,
- teardown_test_setup_migration),
cmocka_unit_test_setup(test_device_is_stopped_and_copying, setup),
cmocka_unit_test_setup(test_cmd_allowed_when_stopped_and_copying, setup),
cmocka_unit_test_setup(test_should_exec_command, setup),