test-qgraph.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  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 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. #include "qemu/osdep.h"
  19. #include "libqtest.h"
  20. #include "libqos/qgraph.h"
  21. #include "libqos/qgraph_internal.h"
  22. #define MACHINE_PC "x86_64/pc"
  23. #define MACHINE_RASPI2 "arm/raspi2"
  24. #define I440FX "i440FX-pcihost"
  25. #define PCIBUS_PC "pcibus-pc"
  26. #define SDHCI "sdhci"
  27. #define PCIBUS "pci-bus"
  28. #define SDHCI_PCI "sdhci-pci"
  29. #define SDHCI_MM "generic-sdhci"
  30. #define REGISTER_TEST "register-test"
  31. int npath;
  32. static void *machinefunct(QTestState *qts)
  33. {
  34. return NULL;
  35. }
  36. static void *driverfunct(void *obj, QGuestAllocator *machine, void *arg)
  37. {
  38. return NULL;
  39. }
  40. static void testfunct(void *obj, void *arg, QGuestAllocator *alloc)
  41. {
  42. return;
  43. }
  44. static void check_interface(const char *interface)
  45. {
  46. g_assert_cmpint(qos_graph_has_machine(interface), ==, FALSE);
  47. g_assert_nonnull(qos_graph_get_node(interface));
  48. g_assert_cmpint(qos_graph_has_node(interface), ==, TRUE);
  49. g_assert_cmpint(qos_graph_get_node_type(interface), ==, QNODE_INTERFACE);
  50. qos_graph_node_set_availability(interface, TRUE);
  51. g_assert_cmpint(qos_graph_get_node_availability(interface), ==, TRUE);
  52. }
  53. static void check_machine(const char *machine)
  54. {
  55. qos_node_create_machine(machine, machinefunct);
  56. g_assert_nonnull(qos_graph_get_machine(machine));
  57. g_assert_cmpint(qos_graph_has_machine(machine), ==, TRUE);
  58. g_assert_nonnull(qos_graph_get_node(machine));
  59. g_assert_cmpint(qos_graph_get_node_availability(machine), ==, FALSE);
  60. qos_graph_node_set_availability(machine, TRUE);
  61. g_assert_cmpint(qos_graph_get_node_availability(machine), ==, TRUE);
  62. g_assert_cmpint(qos_graph_has_node(machine), ==, TRUE);
  63. g_assert_cmpint(qos_graph_get_node_type(machine), ==, QNODE_MACHINE);
  64. }
  65. static void check_contains(const char *machine, const char *driver)
  66. {
  67. QOSGraphEdge *edge;
  68. qos_node_contains(machine, driver, NULL);
  69. edge = qos_graph_get_edge(machine, driver);
  70. g_assert_nonnull(edge);
  71. g_assert_cmpint(qos_graph_edge_get_type(edge), ==, QEDGE_CONTAINS);
  72. g_assert_cmpint(qos_graph_has_edge(machine, driver), ==, TRUE);
  73. }
  74. static void check_produces(const char *machine, const char *interface)
  75. {
  76. QOSGraphEdge *edge;
  77. qos_node_produces(machine, interface);
  78. check_interface(interface);
  79. edge = qos_graph_get_edge(machine, interface);
  80. g_assert_nonnull(edge);
  81. g_assert_cmpint(qos_graph_edge_get_type(edge), ==,
  82. QEDGE_PRODUCES);
  83. g_assert_cmpint(qos_graph_has_edge(machine, interface), ==, TRUE);
  84. }
  85. static void check_consumes(const char *driver, const char *interface)
  86. {
  87. QOSGraphEdge *edge;
  88. qos_node_consumes(driver, interface, NULL);
  89. check_interface(interface);
  90. edge = qos_graph_get_edge(interface, driver);
  91. g_assert_nonnull(edge);
  92. g_assert_cmpint(qos_graph_edge_get_type(edge), ==, QEDGE_CONSUMED_BY);
  93. g_assert_cmpint(qos_graph_has_edge(interface, driver), ==, TRUE);
  94. }
  95. static void check_driver(const char *driver)
  96. {
  97. qos_node_create_driver(driver, driverfunct);
  98. g_assert_cmpint(qos_graph_has_machine(driver), ==, FALSE);
  99. g_assert_nonnull(qos_graph_get_node(driver));
  100. g_assert_cmpint(qos_graph_has_node(driver), ==, TRUE);
  101. g_assert_cmpint(qos_graph_get_node_type(driver), ==, QNODE_DRIVER);
  102. g_assert_cmpint(qos_graph_get_node_availability(driver), ==, FALSE);
  103. qos_graph_node_set_availability(driver, TRUE);
  104. g_assert_cmpint(qos_graph_get_node_availability(driver), ==, TRUE);
  105. }
  106. static void check_test(const char *test, const char *interface)
  107. {
  108. QOSGraphEdge *edge;
  109. char *full_name = g_strdup_printf("%s-tests/%s", interface, test);
  110. qos_add_test(test, interface, testfunct, NULL);
  111. g_assert_cmpint(qos_graph_has_machine(test), ==, FALSE);
  112. g_assert_cmpint(qos_graph_has_machine(full_name), ==, FALSE);
  113. g_assert_nonnull(qos_graph_get_node(full_name));
  114. g_assert_cmpint(qos_graph_has_node(full_name), ==, TRUE);
  115. g_assert_cmpint(qos_graph_get_node_type(full_name), ==, QNODE_TEST);
  116. edge = qos_graph_get_edge(interface, full_name);
  117. g_assert_nonnull(edge);
  118. g_assert_cmpint(qos_graph_edge_get_type(edge), ==,
  119. QEDGE_CONSUMED_BY);
  120. g_assert_cmpint(qos_graph_has_edge(interface, full_name), ==, TRUE);
  121. g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, TRUE);
  122. qos_graph_node_set_availability(full_name, FALSE);
  123. g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, FALSE);
  124. g_free(full_name);
  125. }
  126. static void count_each_test(QOSGraphNode *path, int len)
  127. {
  128. npath++;
  129. }
  130. static void check_leaf_discovered(int n)
  131. {
  132. npath = 0;
  133. qos_graph_foreach_test_path(count_each_test);
  134. g_assert_cmpint(n, ==, npath);
  135. }
  136. /* G_Test functions */
  137. static void init_nop(void)
  138. {
  139. qos_graph_init();
  140. qos_graph_destroy();
  141. }
  142. static void test_machine(void)
  143. {
  144. qos_graph_init();
  145. check_machine(MACHINE_PC);
  146. qos_graph_destroy();
  147. }
  148. static void test_contains(void)
  149. {
  150. qos_graph_init();
  151. check_contains(MACHINE_PC, I440FX);
  152. g_assert_null(qos_graph_get_machine(MACHINE_PC));
  153. g_assert_null(qos_graph_get_machine(I440FX));
  154. g_assert_null(qos_graph_get_node(MACHINE_PC));
  155. g_assert_null(qos_graph_get_node(I440FX));
  156. qos_graph_destroy();
  157. }
  158. static void test_multiple_contains(void)
  159. {
  160. qos_graph_init();
  161. check_contains(MACHINE_PC, I440FX);
  162. check_contains(MACHINE_PC, PCIBUS_PC);
  163. qos_graph_destroy();
  164. }
  165. static void test_produces(void)
  166. {
  167. qos_graph_init();
  168. check_produces(MACHINE_PC, I440FX);
  169. g_assert_null(qos_graph_get_machine(MACHINE_PC));
  170. g_assert_null(qos_graph_get_machine(I440FX));
  171. g_assert_null(qos_graph_get_node(MACHINE_PC));
  172. g_assert_nonnull(qos_graph_get_node(I440FX));
  173. qos_graph_destroy();
  174. }
  175. static void test_multiple_produces(void)
  176. {
  177. qos_graph_init();
  178. check_produces(MACHINE_PC, I440FX);
  179. check_produces(MACHINE_PC, PCIBUS_PC);
  180. qos_graph_destroy();
  181. }
  182. static void test_consumes(void)
  183. {
  184. qos_graph_init();
  185. check_consumes(I440FX, SDHCI);
  186. g_assert_null(qos_graph_get_machine(I440FX));
  187. g_assert_null(qos_graph_get_machine(SDHCI));
  188. g_assert_null(qos_graph_get_node(I440FX));
  189. g_assert_nonnull(qos_graph_get_node(SDHCI));
  190. qos_graph_destroy();
  191. }
  192. static void test_multiple_consumes(void)
  193. {
  194. qos_graph_init();
  195. check_consumes(I440FX, SDHCI);
  196. check_consumes(PCIBUS_PC, SDHCI);
  197. qos_graph_destroy();
  198. }
  199. static void test_driver(void)
  200. {
  201. qos_graph_init();
  202. check_driver(I440FX);
  203. qos_graph_destroy();
  204. }
  205. static void test_test(void)
  206. {
  207. qos_graph_init();
  208. check_test(REGISTER_TEST, SDHCI);
  209. qos_graph_destroy();
  210. }
  211. static void test_machine_contains_driver(void)
  212. {
  213. qos_graph_init();
  214. check_machine(MACHINE_PC);
  215. check_driver(I440FX);
  216. check_contains(MACHINE_PC, I440FX);
  217. qos_graph_destroy();
  218. }
  219. static void test_driver_contains_driver(void)
  220. {
  221. qos_graph_init();
  222. check_driver(PCIBUS_PC);
  223. check_driver(I440FX);
  224. check_contains(PCIBUS_PC, I440FX);
  225. qos_graph_destroy();
  226. }
  227. static void test_machine_produces_interface(void)
  228. {
  229. qos_graph_init();
  230. check_machine(MACHINE_PC);
  231. check_produces(MACHINE_PC, SDHCI);
  232. qos_graph_destroy();
  233. }
  234. static void test_driver_produces_interface(void)
  235. {
  236. qos_graph_init();
  237. check_driver(I440FX);
  238. check_produces(I440FX, SDHCI);
  239. qos_graph_destroy();
  240. }
  241. static void test_machine_consumes_interface(void)
  242. {
  243. qos_graph_init();
  244. check_machine(MACHINE_PC);
  245. check_consumes(MACHINE_PC, SDHCI);
  246. qos_graph_destroy();
  247. }
  248. static void test_driver_consumes_interface(void)
  249. {
  250. qos_graph_init();
  251. check_driver(I440FX);
  252. check_consumes(I440FX, SDHCI);
  253. qos_graph_destroy();
  254. }
  255. static void test_test_consumes_interface(void)
  256. {
  257. qos_graph_init();
  258. check_test(REGISTER_TEST, SDHCI);
  259. qos_graph_destroy();
  260. }
  261. static void test_full_sample(void)
  262. {
  263. qos_graph_init();
  264. check_machine(MACHINE_PC);
  265. check_contains(MACHINE_PC, I440FX);
  266. check_driver(I440FX);
  267. check_driver(PCIBUS_PC);
  268. check_contains(I440FX, PCIBUS_PC);
  269. check_produces(PCIBUS_PC, PCIBUS);
  270. check_driver(SDHCI_PCI);
  271. qos_node_consumes(SDHCI_PCI, PCIBUS, NULL);
  272. check_produces(SDHCI_PCI, SDHCI);
  273. check_driver(SDHCI_MM);
  274. check_produces(SDHCI_MM, SDHCI);
  275. qos_add_test(REGISTER_TEST, SDHCI, testfunct, NULL);
  276. check_leaf_discovered(1);
  277. qos_print_graph();
  278. qos_graph_destroy();
  279. }
  280. static void test_full_sample_raspi(void)
  281. {
  282. qos_graph_init();
  283. check_machine(MACHINE_PC);
  284. check_contains(MACHINE_PC, I440FX);
  285. check_driver(I440FX);
  286. check_driver(PCIBUS_PC);
  287. check_contains(I440FX, PCIBUS_PC);
  288. check_produces(PCIBUS_PC, PCIBUS);
  289. check_driver(SDHCI_PCI);
  290. qos_node_consumes(SDHCI_PCI, PCIBUS, NULL);
  291. check_produces(SDHCI_PCI, SDHCI);
  292. check_machine(MACHINE_RASPI2);
  293. check_contains(MACHINE_RASPI2, SDHCI_MM);
  294. check_driver(SDHCI_MM);
  295. check_produces(SDHCI_MM, SDHCI);
  296. qos_add_test(REGISTER_TEST, SDHCI, testfunct, NULL);
  297. qos_print_graph();
  298. check_leaf_discovered(2);
  299. qos_graph_destroy();
  300. }
  301. static void test_cycle(void)
  302. {
  303. qos_graph_init();
  304. check_machine(MACHINE_RASPI2);
  305. check_driver("B");
  306. check_driver("C");
  307. check_driver("D");
  308. check_contains(MACHINE_RASPI2, "B");
  309. check_contains("B", "C");
  310. check_contains("C", "D");
  311. check_contains("D", MACHINE_RASPI2);
  312. check_leaf_discovered(0);
  313. qos_print_graph();
  314. qos_graph_destroy();
  315. }
  316. static void test_two_test_same_interface(void)
  317. {
  318. qos_graph_init();
  319. check_machine(MACHINE_RASPI2);
  320. check_produces(MACHINE_RASPI2, "B");
  321. qos_add_test("C", "B", testfunct, NULL);
  322. qos_add_test("D", "B", testfunct, NULL);
  323. check_contains(MACHINE_RASPI2, "B");
  324. check_leaf_discovered(4);
  325. qos_print_graph();
  326. qos_graph_destroy();
  327. }
  328. static void test_test_in_path(void)
  329. {
  330. qos_graph_init();
  331. check_machine(MACHINE_RASPI2);
  332. check_produces(MACHINE_RASPI2, "B");
  333. qos_add_test("C", "B", testfunct, NULL);
  334. check_driver("D");
  335. check_consumes("D", "B");
  336. check_produces("D", "E");
  337. qos_add_test("F", "E", testfunct, NULL);
  338. check_leaf_discovered(2);
  339. qos_print_graph();
  340. qos_graph_destroy();
  341. }
  342. static void test_double_edge(void)
  343. {
  344. qos_graph_init();
  345. check_machine(MACHINE_RASPI2);
  346. check_produces("B", "C");
  347. qos_node_consumes("C", "B", NULL);
  348. qos_add_test("D", "C", testfunct, NULL);
  349. check_contains(MACHINE_RASPI2, "B");
  350. qos_print_graph();
  351. qos_graph_destroy();
  352. }
  353. int main(int argc, char **argv)
  354. {
  355. g_test_init(&argc, &argv, NULL);
  356. g_test_add_func("/qgraph/init_nop", init_nop);
  357. g_test_add_func("/qgraph/test_machine", test_machine);
  358. g_test_add_func("/qgraph/test_contains", test_contains);
  359. g_test_add_func("/qgraph/test_multiple_contains", test_multiple_contains);
  360. g_test_add_func("/qgraph/test_produces", test_produces);
  361. g_test_add_func("/qgraph/test_multiple_produces", test_multiple_produces);
  362. g_test_add_func("/qgraph/test_consumes", test_consumes);
  363. g_test_add_func("/qgraph/test_multiple_consumes",
  364. test_multiple_consumes);
  365. g_test_add_func("/qgraph/test_driver", test_driver);
  366. g_test_add_func("/qgraph/test_test", test_test);
  367. g_test_add_func("/qgraph/test_machine_contains_driver",
  368. test_machine_contains_driver);
  369. g_test_add_func("/qgraph/test_driver_contains_driver",
  370. test_driver_contains_driver);
  371. g_test_add_func("/qgraph/test_machine_produces_interface",
  372. test_machine_produces_interface);
  373. g_test_add_func("/qgraph/test_driver_produces_interface",
  374. test_driver_produces_interface);
  375. g_test_add_func("/qgraph/test_machine_consumes_interface",
  376. test_machine_consumes_interface);
  377. g_test_add_func("/qgraph/test_driver_consumes_interface",
  378. test_driver_consumes_interface);
  379. g_test_add_func("/qgraph/test_test_consumes_interface",
  380. test_test_consumes_interface);
  381. g_test_add_func("/qgraph/test_full_sample", test_full_sample);
  382. g_test_add_func("/qgraph/test_full_sample_raspi", test_full_sample_raspi);
  383. g_test_add_func("/qgraph/test_cycle", test_cycle);
  384. g_test_add_func("/qgraph/test_two_test_same_interface",
  385. test_two_test_same_interface);
  386. g_test_add_func("/qgraph/test_test_in_path", test_test_in_path);
  387. g_test_add_func("/qgraph/test_double_edge", test_double_edge);
  388. g_test_run();
  389. return 0;
  390. }