From f43ef9703cb6ad6e5d7b6f0ac0a537ca71aa0b1d Mon Sep 17 00:00:00 2001 From: William Henderson Date: Wed, 16 Aug 2023 15:12:19 +0000 Subject: refactor: move a number of tests from C to Python Signed-off-by: William Henderson --- test/py/libvfio_user.py | 17 ++- test/py/test_migration.py | 175 +++++++++++++++------ test/py/test_request_errors.py | 54 +++++++ test/unit-tests.c | 335 ----------------------------------------- 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 +# Authors: William Henderson # # 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), -- cgit v1.1