1 /*
2  * QEMU tests for shared dma-buf API
3  *
4  * Copyright (c) 2023 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "qemu/osdep.h"
22 #include "hw/virtio/virtio-dmabuf.h"
23 
24 
25 static void test_add_remove_resources(void)
26 {
27     QemuUUID uuid;
28     int i, dmabuf_fd;
29 
30     for (i = 0; i < 100; ++i) {
31         qemu_uuid_generate(&uuid);
32         dmabuf_fd = g_random_int_range(3, 500);
33         /* Add a new resource */
34         g_assert(virtio_add_dmabuf(&uuid, dmabuf_fd));
35         g_assert_cmpint(virtio_lookup_dmabuf(&uuid), ==, dmabuf_fd);
36         /* Remove the resource */
37         g_assert(virtio_remove_resource(&uuid));
38         /* Resource is not found anymore */
39         g_assert_cmpint(virtio_lookup_dmabuf(&uuid), ==, -1);
40     }
41 }
42 
43 static void test_add_remove_dev(void)
44 {
45     QemuUUID uuid;
46     struct vhost_dev *dev = g_new0(struct vhost_dev, 1);
47     int i;
48 
49     for (i = 0; i < 100; ++i) {
50         qemu_uuid_generate(&uuid);
51         virtio_add_vhost_device(&uuid, dev);
52         /* vhost device is found */
53         g_assert(virtio_lookup_vhost_device(&uuid) != NULL);
54         /* Remove the vhost device */
55         g_assert(virtio_remove_resource(&uuid));
56         /* vhost device is not found anymore */
57         g_assert(virtio_lookup_vhost_device(&uuid) == NULL);
58     }
59     g_free(dev);
60 }
61 
62 static void test_remove_invalid_resource(void)
63 {
64     QemuUUID uuid;
65     int i;
66 
67     for (i = 0; i < 20; ++i) {
68         qemu_uuid_generate(&uuid);
69         g_assert_cmpint(virtio_lookup_dmabuf(&uuid), ==, -1);
70         /* Removing a resource that does not exist returns false */
71         g_assert_false(virtio_remove_resource(&uuid));
72     }
73 }
74 
75 static void test_add_invalid_resource(void)
76 {
77     QemuUUID uuid;
78     struct vhost_dev *dev = NULL;
79     int i, dmabuf_fd = -2, alt_dmabuf = 2;
80 
81     for (i = 0; i < 20; ++i) {
82         qemu_uuid_generate(&uuid);
83         /* Add a new resource with invalid (negative) resource fd */
84         g_assert_false(virtio_add_dmabuf(&uuid, dmabuf_fd));
85         /* Resource is not found */
86         g_assert_cmpint(virtio_lookup_dmabuf(&uuid), ==, -1);
87         /* Add a new vhost device with invalid (NULL) pointer */
88         g_assert_false(virtio_add_vhost_device(&uuid, dev));
89         /* vhost device is not found */
90         g_assert(virtio_lookup_vhost_device(&uuid) == NULL);
91     }
92 
93     for (i = 0; i < 20; ++i) {
94         /* Add a valid resource */
95         qemu_uuid_generate(&uuid);
96         dmabuf_fd = g_random_int_range(3, 500);
97         g_assert(virtio_add_dmabuf(&uuid, dmabuf_fd));
98         g_assert_cmpint(virtio_lookup_dmabuf(&uuid), ==, dmabuf_fd);
99         /* Add a new resource with repeated uuid returns false */
100         g_assert_false(virtio_add_dmabuf(&uuid, alt_dmabuf));
101         /* The value for the uuid key is not replaced */
102         g_assert_cmpint(virtio_lookup_dmabuf(&uuid), ==, dmabuf_fd);
103     }
104 }
105 
106 static void test_free_resources(void)
107 {
108     QemuUUID uuids[20];
109     int i, dmabuf_fd;
110 
111     for (i = 0; i < ARRAY_SIZE(uuids); ++i) {
112         qemu_uuid_generate(&uuids[i]);
113         dmabuf_fd = g_random_int_range(3, 500);
114         g_assert(virtio_add_dmabuf(&uuids[i], dmabuf_fd));
115         g_assert_cmpint(virtio_lookup_dmabuf(&uuids[i]), ==, dmabuf_fd);
116     }
117     virtio_free_resources();
118     for (i = 0; i < ARRAY_SIZE(uuids); ++i) {
119         /* None of the resources is found after free'd */
120         g_assert_cmpint(virtio_lookup_dmabuf(&uuids[i]), ==, -1);
121     }
122 
123 }
124 
125 int main(int argc, char **argv)
126 {
127     g_test_init(&argc, &argv, NULL);
128     g_test_add_func("/virtio-dmabuf/add_rm_res", test_add_remove_resources);
129     g_test_add_func("/virtio-dmabuf/add_rm_dev", test_add_remove_dev);
130     g_test_add_func("/virtio-dmabuf/rm_invalid_res",
131                     test_remove_invalid_resource);
132     g_test_add_func("/virtio-dmabuf/add_invalid_res",
133                     test_add_invalid_resource);
134     g_test_add_func("/virtio-dmabuf/free_res", test_free_resources);
135 
136     return g_test_run();
137 }
138