qemu/tests/unit/test-qgraph.c
<<
>>
Prefs
   1/*
   2 * libqos driver framework
   3 *
   4 * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
   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 version 2.1 as published by the Free Software Foundation.
   9 *
  10 * This library is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * Lesser General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU Lesser General Public
  16 * License along with this library; if not, see <http://www.gnu.org/licenses/>
  17 */
  18
  19#include "qemu/osdep.h"
  20#include "../qtest/libqos/qgraph.h"
  21#include "../qtest/libqos/qgraph_internal.h"
  22
  23#define MACHINE_PC "x86_64/pc"
  24#define MACHINE_RASPI2 "arm/raspi2b"
  25#define I440FX "i440FX-pcihost"
  26#define PCIBUS_PC "pcibus-pc"
  27#define SDHCI "sdhci"
  28#define PCIBUS "pci-bus"
  29#define SDHCI_PCI "sdhci-pci"
  30#define SDHCI_MM "generic-sdhci"
  31#define REGISTER_TEST "register-test"
  32
  33int npath;
  34
  35static void *machinefunct(QTestState *qts)
  36{
  37    return NULL;
  38}
  39
  40static void *driverfunct(void *obj, QGuestAllocator *machine, void *arg)
  41{
  42    return NULL;
  43}
  44
  45static void testfunct(void *obj, void *arg, QGuestAllocator *alloc)
  46{
  47    return;
  48}
  49
  50static void check_interface(const char *interface)
  51{
  52    g_assert_cmpint(qos_graph_has_machine(interface), ==, FALSE);
  53    g_assert_nonnull(qos_graph_get_node(interface));
  54    g_assert_cmpint(qos_graph_has_node(interface), ==, TRUE);
  55    g_assert_cmpint(qos_graph_get_node_type(interface), ==, QNODE_INTERFACE);
  56    qos_graph_node_set_availability(interface, TRUE);
  57    g_assert_cmpint(qos_graph_get_node_availability(interface), ==, TRUE);
  58}
  59
  60static void check_machine(const char *machine)
  61{
  62    qos_node_create_machine(machine, machinefunct);
  63    g_assert_nonnull(qos_graph_get_machine(machine));
  64    g_assert_cmpint(qos_graph_has_machine(machine), ==, TRUE);
  65    g_assert_nonnull(qos_graph_get_node(machine));
  66    g_assert_cmpint(qos_graph_get_node_availability(machine), ==, FALSE);
  67    qos_graph_node_set_availability(machine, TRUE);
  68    g_assert_cmpint(qos_graph_get_node_availability(machine), ==, TRUE);
  69    g_assert_cmpint(qos_graph_has_node(machine), ==, TRUE);
  70    g_assert_cmpint(qos_graph_get_node_type(machine), ==, QNODE_MACHINE);
  71}
  72
  73static void check_contains(const char *machine, const char *driver)
  74{
  75    QOSGraphEdge *edge;
  76    qos_node_contains(machine, driver, NULL);
  77
  78    edge = qos_graph_get_edge(machine, driver);
  79    g_assert_nonnull(edge);
  80    g_assert_cmpint(qos_graph_edge_get_type(edge), ==, QEDGE_CONTAINS);
  81    g_assert_cmpint(qos_graph_has_edge(machine, driver), ==, TRUE);
  82}
  83
  84static void check_produces(const char *machine, const char *interface)
  85{
  86    QOSGraphEdge *edge;
  87
  88    qos_node_produces(machine, interface);
  89    check_interface(interface);
  90    edge = qos_graph_get_edge(machine, interface);
  91    g_assert_nonnull(edge);
  92    g_assert_cmpint(qos_graph_edge_get_type(edge), ==,
  93                    QEDGE_PRODUCES);
  94    g_assert_cmpint(qos_graph_has_edge(machine, interface), ==, TRUE);
  95}
  96
  97static void check_consumes(const char *driver, const char *interface)
  98{
  99    QOSGraphEdge *edge;
 100
 101    qos_node_consumes(driver, interface, NULL);
 102    check_interface(interface);
 103    edge = qos_graph_get_edge(interface, driver);
 104    g_assert_nonnull(edge);
 105    g_assert_cmpint(qos_graph_edge_get_type(edge), ==, QEDGE_CONSUMED_BY);
 106    g_assert_cmpint(qos_graph_has_edge(interface, driver), ==, TRUE);
 107}
 108
 109static void check_driver(const char *driver)
 110{
 111    qos_node_create_driver(driver, driverfunct);
 112    g_assert_cmpint(qos_graph_has_machine(driver), ==, FALSE);
 113    g_assert_nonnull(qos_graph_get_node(driver));
 114    g_assert_cmpint(qos_graph_has_node(driver), ==, TRUE);
 115    g_assert_cmpint(qos_graph_get_node_type(driver), ==, QNODE_DRIVER);
 116    g_assert_cmpint(qos_graph_get_node_availability(driver), ==, FALSE);
 117    qos_graph_node_set_availability(driver, TRUE);
 118    g_assert_cmpint(qos_graph_get_node_availability(driver), ==, TRUE);
 119}
 120
 121static void check_test(const char *test, const char *interface)
 122{
 123    QOSGraphEdge *edge;
 124    char *full_name = g_strdup_printf("%s-tests/%s", interface, test);
 125
 126    qos_add_test(test, interface, testfunct, NULL);
 127    g_assert_cmpint(qos_graph_has_machine(test), ==, FALSE);
 128    g_assert_cmpint(qos_graph_has_machine(full_name), ==, FALSE);
 129    g_assert_nonnull(qos_graph_get_node(full_name));
 130    g_assert_cmpint(qos_graph_has_node(full_name), ==, TRUE);
 131    g_assert_cmpint(qos_graph_get_node_type(full_name), ==, QNODE_TEST);
 132    edge = qos_graph_get_edge(interface, full_name);
 133    g_assert_nonnull(edge);
 134    g_assert_cmpint(qos_graph_edge_get_type(edge), ==,
 135                    QEDGE_CONSUMED_BY);
 136    g_assert_cmpint(qos_graph_has_edge(interface, full_name), ==, TRUE);
 137    g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, TRUE);
 138    qos_graph_node_set_availability(full_name, FALSE);
 139    g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, FALSE);
 140    g_free(full_name);
 141}
 142
 143static void count_each_test(QOSGraphNode *path, int len)
 144{
 145    npath++;
 146}
 147
 148static void check_leaf_discovered(int n)
 149{
 150    npath = 0;
 151    qos_graph_foreach_test_path(count_each_test);
 152    g_assert_cmpint(n, ==, npath);
 153}
 154
 155/* G_Test functions */
 156
 157static void init_nop(void)
 158{
 159    qos_graph_init();
 160    qos_graph_destroy();
 161}
 162
 163static void test_machine(void)
 164{
 165    qos_graph_init();
 166    check_machine(MACHINE_PC);
 167    qos_graph_destroy();
 168}
 169
 170static void test_contains(void)
 171{
 172    qos_graph_init();
 173    check_contains(MACHINE_PC, I440FX);
 174    g_assert_null(qos_graph_get_machine(MACHINE_PC));
 175    g_assert_null(qos_graph_get_machine(I440FX));
 176    g_assert_null(qos_graph_get_node(MACHINE_PC));
 177    g_assert_null(qos_graph_get_node(I440FX));
 178    qos_graph_destroy();
 179}
 180
 181static void test_multiple_contains(void)
 182{
 183    qos_graph_init();
 184    check_contains(MACHINE_PC, I440FX);
 185    check_contains(MACHINE_PC, PCIBUS_PC);
 186    qos_graph_destroy();
 187}
 188
 189static void test_produces(void)
 190{
 191    qos_graph_init();
 192    check_produces(MACHINE_PC, I440FX);
 193    g_assert_null(qos_graph_get_machine(MACHINE_PC));
 194    g_assert_null(qos_graph_get_machine(I440FX));
 195    g_assert_null(qos_graph_get_node(MACHINE_PC));
 196    g_assert_nonnull(qos_graph_get_node(I440FX));
 197    qos_graph_destroy();
 198}
 199
 200static void test_multiple_produces(void)
 201{
 202    qos_graph_init();
 203    check_produces(MACHINE_PC, I440FX);
 204    check_produces(MACHINE_PC, PCIBUS_PC);
 205    qos_graph_destroy();
 206}
 207
 208static void test_consumes(void)
 209{
 210    qos_graph_init();
 211    check_consumes(I440FX, SDHCI);
 212    g_assert_null(qos_graph_get_machine(I440FX));
 213    g_assert_null(qos_graph_get_machine(SDHCI));
 214    g_assert_null(qos_graph_get_node(I440FX));
 215    g_assert_nonnull(qos_graph_get_node(SDHCI));
 216    qos_graph_destroy();
 217}
 218
 219static void test_multiple_consumes(void)
 220{
 221    qos_graph_init();
 222    check_consumes(I440FX, SDHCI);
 223    check_consumes(PCIBUS_PC, SDHCI);
 224    qos_graph_destroy();
 225}
 226
 227static void test_driver(void)
 228{
 229    qos_graph_init();
 230    check_driver(I440FX);
 231    qos_graph_destroy();
 232}
 233
 234static void test_test(void)
 235{
 236    qos_graph_init();
 237    check_test(REGISTER_TEST, SDHCI);
 238    qos_graph_destroy();
 239}
 240
 241static void test_machine_contains_driver(void)
 242{
 243    qos_graph_init();
 244    check_machine(MACHINE_PC);
 245    check_driver(I440FX);
 246    check_contains(MACHINE_PC, I440FX);
 247    qos_graph_destroy();
 248}
 249
 250static void test_driver_contains_driver(void)
 251{
 252    qos_graph_init();
 253    check_driver(PCIBUS_PC);
 254    check_driver(I440FX);
 255    check_contains(PCIBUS_PC, I440FX);
 256    qos_graph_destroy();
 257}
 258
 259static void test_machine_produces_interface(void)
 260{
 261    qos_graph_init();
 262    check_machine(MACHINE_PC);
 263    check_produces(MACHINE_PC, SDHCI);
 264    qos_graph_destroy();
 265}
 266
 267static void test_driver_produces_interface(void)
 268{
 269    qos_graph_init();
 270    check_driver(I440FX);
 271    check_produces(I440FX, SDHCI);
 272    qos_graph_destroy();
 273}
 274
 275static void test_machine_consumes_interface(void)
 276{
 277    qos_graph_init();
 278    check_machine(MACHINE_PC);
 279    check_consumes(MACHINE_PC, SDHCI);
 280    qos_graph_destroy();
 281}
 282
 283static void test_driver_consumes_interface(void)
 284{
 285    qos_graph_init();
 286    check_driver(I440FX);
 287    check_consumes(I440FX, SDHCI);
 288    qos_graph_destroy();
 289}
 290
 291static void test_test_consumes_interface(void)
 292{
 293    qos_graph_init();
 294    check_test(REGISTER_TEST, SDHCI);
 295    qos_graph_destroy();
 296}
 297
 298static void test_full_sample(void)
 299{
 300    qos_graph_init();
 301    check_machine(MACHINE_PC);
 302    check_contains(MACHINE_PC, I440FX);
 303    check_driver(I440FX);
 304    check_driver(PCIBUS_PC);
 305    check_contains(I440FX, PCIBUS_PC);
 306    check_produces(PCIBUS_PC, PCIBUS);
 307    check_driver(SDHCI_PCI);
 308    qos_node_consumes(SDHCI_PCI, PCIBUS, NULL);
 309    check_produces(SDHCI_PCI, SDHCI);
 310    check_driver(SDHCI_MM);
 311    check_produces(SDHCI_MM, SDHCI);
 312    qos_add_test(REGISTER_TEST, SDHCI, testfunct, NULL);
 313    check_leaf_discovered(1);
 314    qos_print_graph();
 315    qos_graph_destroy();
 316}
 317
 318static void test_full_sample_raspi(void)
 319{
 320    qos_graph_init();
 321    check_machine(MACHINE_PC);
 322    check_contains(MACHINE_PC, I440FX);
 323    check_driver(I440FX);
 324    check_driver(PCIBUS_PC);
 325    check_contains(I440FX, PCIBUS_PC);
 326    check_produces(PCIBUS_PC, PCIBUS);
 327    check_driver(SDHCI_PCI);
 328    qos_node_consumes(SDHCI_PCI, PCIBUS, NULL);
 329    check_produces(SDHCI_PCI, SDHCI);
 330    check_machine(MACHINE_RASPI2);
 331    check_contains(MACHINE_RASPI2, SDHCI_MM);
 332    check_driver(SDHCI_MM);
 333    check_produces(SDHCI_MM, SDHCI);
 334    qos_add_test(REGISTER_TEST, SDHCI, testfunct, NULL);
 335    qos_print_graph();
 336    check_leaf_discovered(2);
 337    qos_graph_destroy();
 338}
 339
 340static void test_cycle(void)
 341{
 342    qos_graph_init();
 343    check_machine(MACHINE_RASPI2);
 344    check_driver("B");
 345    check_driver("C");
 346    check_driver("D");
 347    check_contains(MACHINE_RASPI2, "B");
 348    check_contains("B", "C");
 349    check_contains("C", "D");
 350    check_contains("D", MACHINE_RASPI2);
 351    check_leaf_discovered(0);
 352    qos_print_graph();
 353    qos_graph_destroy();
 354}
 355
 356static void test_two_test_same_interface(void)
 357{
 358    qos_graph_init();
 359    check_machine(MACHINE_RASPI2);
 360    check_produces(MACHINE_RASPI2, "B");
 361    qos_add_test("C", "B", testfunct, NULL);
 362    qos_add_test("D", "B", testfunct, NULL);
 363    check_contains(MACHINE_RASPI2, "B");
 364    check_leaf_discovered(4);
 365    qos_print_graph();
 366    qos_graph_destroy();
 367}
 368
 369static void test_test_in_path(void)
 370{
 371    qos_graph_init();
 372    check_machine(MACHINE_RASPI2);
 373    check_produces(MACHINE_RASPI2, "B");
 374    qos_add_test("C", "B", testfunct, NULL);
 375    check_driver("D");
 376    check_consumes("D", "B");
 377    check_produces("D", "E");
 378    qos_add_test("F", "E", testfunct, NULL);
 379    check_leaf_discovered(2);
 380    qos_print_graph();
 381    qos_graph_destroy();
 382}
 383
 384static void test_double_edge(void)
 385{
 386    qos_graph_init();
 387    check_machine(MACHINE_RASPI2);
 388    check_produces("B", "C");
 389    qos_node_consumes("C", "B", NULL);
 390    qos_add_test("D", "C", testfunct, NULL);
 391    check_contains(MACHINE_RASPI2, "B");
 392    qos_print_graph();
 393    qos_graph_destroy();
 394}
 395
 396int main(int argc, char **argv)
 397{
 398    g_test_init(&argc, &argv, NULL);
 399    g_test_add_func("/qgraph/init_nop", init_nop);
 400    g_test_add_func("/qgraph/test_machine", test_machine);
 401    g_test_add_func("/qgraph/test_contains", test_contains);
 402    g_test_add_func("/qgraph/test_multiple_contains", test_multiple_contains);
 403    g_test_add_func("/qgraph/test_produces", test_produces);
 404    g_test_add_func("/qgraph/test_multiple_produces", test_multiple_produces);
 405    g_test_add_func("/qgraph/test_consumes", test_consumes);
 406    g_test_add_func("/qgraph/test_multiple_consumes",
 407                    test_multiple_consumes);
 408    g_test_add_func("/qgraph/test_driver", test_driver);
 409    g_test_add_func("/qgraph/test_test", test_test);
 410    g_test_add_func("/qgraph/test_machine_contains_driver",
 411                    test_machine_contains_driver);
 412    g_test_add_func("/qgraph/test_driver_contains_driver",
 413                    test_driver_contains_driver);
 414    g_test_add_func("/qgraph/test_machine_produces_interface",
 415                    test_machine_produces_interface);
 416    g_test_add_func("/qgraph/test_driver_produces_interface",
 417                    test_driver_produces_interface);
 418    g_test_add_func("/qgraph/test_machine_consumes_interface",
 419                    test_machine_consumes_interface);
 420    g_test_add_func("/qgraph/test_driver_consumes_interface",
 421                    test_driver_consumes_interface);
 422    g_test_add_func("/qgraph/test_test_consumes_interface",
 423                    test_test_consumes_interface);
 424    g_test_add_func("/qgraph/test_full_sample", test_full_sample);
 425    g_test_add_func("/qgraph/test_full_sample_raspi", test_full_sample_raspi);
 426    g_test_add_func("/qgraph/test_cycle", test_cycle);
 427    g_test_add_func("/qgraph/test_two_test_same_interface",
 428                    test_two_test_same_interface);
 429    g_test_add_func("/qgraph/test_test_in_path", test_test_in_path);
 430    g_test_add_func("/qgraph/test_double_edge", test_double_edge);
 431
 432    g_test_run();
 433    return 0;
 434}
 435