check-block-qdict.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. /*
  2. * Unit-tests for Block layer QDict extras
  3. *
  4. * Copyright (c) 2013-2018 Red Hat, Inc.
  5. *
  6. * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  7. * See the COPYING.LIB file in the top-level directory.
  8. */
  9. #include "qemu/osdep.h"
  10. #include "block/qdict.h"
  11. #include "qapi/qmp/qlist.h"
  12. #include "qapi/qmp/qnum.h"
  13. #include "qapi/error.h"
  14. static void qdict_defaults_test(void)
  15. {
  16. QDict *dict, *copy;
  17. dict = qdict_new();
  18. copy = qdict_new();
  19. qdict_set_default_str(dict, "foo", "abc");
  20. qdict_set_default_str(dict, "foo", "def");
  21. g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "abc");
  22. qdict_set_default_str(dict, "bar", "ghi");
  23. qdict_copy_default(copy, dict, "foo");
  24. g_assert_cmpstr(qdict_get_str(copy, "foo"), ==, "abc");
  25. qdict_set_default_str(copy, "bar", "xyz");
  26. qdict_copy_default(copy, dict, "bar");
  27. g_assert_cmpstr(qdict_get_str(copy, "bar"), ==, "xyz");
  28. qobject_unref(copy);
  29. qobject_unref(dict);
  30. }
  31. static void qdict_flatten_test(void)
  32. {
  33. QList *e_1 = qlist_new();
  34. QList *e = qlist_new();
  35. QDict *e_1_2 = qdict_new();
  36. QDict *f = qdict_new();
  37. QList *y = qlist_new();
  38. QDict *z = qdict_new();
  39. QDict *root = qdict_new();
  40. /*
  41. * Test the flattening of
  42. *
  43. * {
  44. * "e": [
  45. * 42,
  46. * [
  47. * 23,
  48. * 66,
  49. * {
  50. * "a": 0,
  51. * "b": 1
  52. * }
  53. * ]
  54. * ],
  55. * "f": {
  56. * "c": 2,
  57. * "d": 3,
  58. * },
  59. * "g": 4,
  60. * "y": [{}],
  61. * "z": {"a": []}
  62. * }
  63. *
  64. * to
  65. *
  66. * {
  67. * "e.0": 42,
  68. * "e.1.0": 23,
  69. * "e.1.1": 66,
  70. * "e.1.2.a": 0,
  71. * "e.1.2.b": 1,
  72. * "f.c": 2,
  73. * "f.d": 3,
  74. * "g": 4,
  75. * "y.0": {},
  76. * "z.a": []
  77. * }
  78. */
  79. qdict_put_int(e_1_2, "a", 0);
  80. qdict_put_int(e_1_2, "b", 1);
  81. qlist_append_int(e_1, 23);
  82. qlist_append_int(e_1, 66);
  83. qlist_append(e_1, e_1_2);
  84. qlist_append_int(e, 42);
  85. qlist_append(e, e_1);
  86. qdict_put_int(f, "c", 2);
  87. qdict_put_int(f, "d", 3);
  88. qlist_append(y, qdict_new());
  89. qdict_put(z, "a", qlist_new());
  90. qdict_put(root, "e", e);
  91. qdict_put(root, "f", f);
  92. qdict_put_int(root, "g", 4);
  93. qdict_put(root, "y", y);
  94. qdict_put(root, "z", z);
  95. qdict_flatten(root);
  96. g_assert(qdict_get_int(root, "e.0") == 42);
  97. g_assert(qdict_get_int(root, "e.1.0") == 23);
  98. g_assert(qdict_get_int(root, "e.1.1") == 66);
  99. g_assert(qdict_get_int(root, "e.1.2.a") == 0);
  100. g_assert(qdict_get_int(root, "e.1.2.b") == 1);
  101. g_assert(qdict_get_int(root, "f.c") == 2);
  102. g_assert(qdict_get_int(root, "f.d") == 3);
  103. g_assert(qdict_get_int(root, "g") == 4);
  104. g_assert(!qdict_size(qdict_get_qdict(root, "y.0")));
  105. g_assert(qlist_empty(qdict_get_qlist(root, "z.a")));
  106. g_assert(qdict_size(root) == 10);
  107. qobject_unref(root);
  108. }
  109. static void qdict_clone_flatten_test(void)
  110. {
  111. QDict *dict1 = qdict_new();
  112. QDict *dict2 = qdict_new();
  113. QDict *cloned_dict1;
  114. /*
  115. * Test that we can clone and flatten
  116. * { "a": { "b": 42 } }
  117. * without modifying the clone.
  118. */
  119. qdict_put_int(dict2, "b", 42);
  120. qdict_put(dict1, "a", dict2);
  121. cloned_dict1 = qdict_clone_shallow(dict1);
  122. qdict_flatten(dict1);
  123. g_assert(qdict_size(dict1) == 1);
  124. g_assert(qdict_get_int(dict1, "a.b") == 42);
  125. g_assert(qdict_size(cloned_dict1) == 1);
  126. g_assert(qdict_get_qdict(cloned_dict1, "a") == dict2);
  127. g_assert(qdict_size(dict2) == 1);
  128. g_assert(qdict_get_int(dict2, "b") == 42);
  129. qobject_unref(dict1);
  130. qobject_unref(cloned_dict1);
  131. }
  132. static void qdict_array_split_test(void)
  133. {
  134. QDict *test_dict = qdict_new();
  135. QDict *dict1, *dict2;
  136. QNum *int1;
  137. QList *test_list;
  138. /*
  139. * Test the split of
  140. *
  141. * {
  142. * "1.x": 0,
  143. * "4.y": 1,
  144. * "0.a": 42,
  145. * "o.o": 7,
  146. * "0.b": 23,
  147. * "2": 66
  148. * }
  149. *
  150. * to
  151. *
  152. * [
  153. * {
  154. * "a": 42,
  155. * "b": 23
  156. * },
  157. * {
  158. * "x": 0
  159. * },
  160. * 66
  161. * ]
  162. *
  163. * and
  164. *
  165. * {
  166. * "4.y": 1,
  167. * "o.o": 7
  168. * }
  169. *
  170. * (remaining in the old QDict)
  171. *
  172. * This example is given in the comment of qdict_array_split().
  173. */
  174. qdict_put_int(test_dict, "1.x", 0);
  175. qdict_put_int(test_dict, "4.y", 1);
  176. qdict_put_int(test_dict, "0.a", 42);
  177. qdict_put_int(test_dict, "o.o", 7);
  178. qdict_put_int(test_dict, "0.b", 23);
  179. qdict_put_int(test_dict, "2", 66);
  180. qdict_array_split(test_dict, &test_list);
  181. dict1 = qobject_to(QDict, qlist_pop(test_list));
  182. dict2 = qobject_to(QDict, qlist_pop(test_list));
  183. int1 = qobject_to(QNum, qlist_pop(test_list));
  184. g_assert(dict1);
  185. g_assert(dict2);
  186. g_assert(int1);
  187. g_assert(qlist_empty(test_list));
  188. qobject_unref(test_list);
  189. g_assert(qdict_get_int(dict1, "a") == 42);
  190. g_assert(qdict_get_int(dict1, "b") == 23);
  191. g_assert(qdict_size(dict1) == 2);
  192. qobject_unref(dict1);
  193. g_assert(qdict_get_int(dict2, "x") == 0);
  194. g_assert(qdict_size(dict2) == 1);
  195. qobject_unref(dict2);
  196. g_assert_cmpint(qnum_get_int(int1), ==, 66);
  197. qobject_unref(int1);
  198. g_assert(qdict_get_int(test_dict, "4.y") == 1);
  199. g_assert(qdict_get_int(test_dict, "o.o") == 7);
  200. g_assert(qdict_size(test_dict) == 2);
  201. qobject_unref(test_dict);
  202. /*
  203. * Test the split of
  204. *
  205. * {
  206. * "0": 42,
  207. * "1": 23,
  208. * "1.x": 84
  209. * }
  210. *
  211. * to
  212. *
  213. * [
  214. * 42
  215. * ]
  216. *
  217. * and
  218. *
  219. * {
  220. * "1": 23,
  221. * "1.x": 84
  222. * }
  223. *
  224. * That is, test whether splitting stops if there is both an entry with key
  225. * of "%u" and other entries with keys prefixed "%u." for the same index.
  226. */
  227. test_dict = qdict_new();
  228. qdict_put_int(test_dict, "0", 42);
  229. qdict_put_int(test_dict, "1", 23);
  230. qdict_put_int(test_dict, "1.x", 84);
  231. qdict_array_split(test_dict, &test_list);
  232. int1 = qobject_to(QNum, qlist_pop(test_list));
  233. g_assert(int1);
  234. g_assert(qlist_empty(test_list));
  235. qobject_unref(test_list);
  236. g_assert_cmpint(qnum_get_int(int1), ==, 42);
  237. qobject_unref(int1);
  238. g_assert(qdict_get_int(test_dict, "1") == 23);
  239. g_assert(qdict_get_int(test_dict, "1.x") == 84);
  240. g_assert(qdict_size(test_dict) == 2);
  241. qobject_unref(test_dict);
  242. }
  243. static void qdict_array_entries_test(void)
  244. {
  245. QDict *dict = qdict_new();
  246. g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
  247. qdict_put_int(dict, "bar", 0);
  248. qdict_put_int(dict, "baz.0", 0);
  249. g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
  250. qdict_put_int(dict, "foo.1", 0);
  251. g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
  252. qdict_put_int(dict, "foo.0", 0);
  253. g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 2);
  254. qdict_put_int(dict, "foo.bar", 0);
  255. g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
  256. qdict_del(dict, "foo.bar");
  257. qdict_put_int(dict, "foo.2.a", 0);
  258. qdict_put_int(dict, "foo.2.b", 0);
  259. qdict_put_int(dict, "foo.2.c", 0);
  260. g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 3);
  261. g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
  262. qobject_unref(dict);
  263. dict = qdict_new();
  264. qdict_put_int(dict, "1", 0);
  265. g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
  266. qdict_put_int(dict, "0", 0);
  267. g_assert_cmpint(qdict_array_entries(dict, ""), ==, 2);
  268. qdict_put_int(dict, "bar", 0);
  269. g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
  270. qdict_del(dict, "bar");
  271. qdict_put_int(dict, "2.a", 0);
  272. qdict_put_int(dict, "2.b", 0);
  273. qdict_put_int(dict, "2.c", 0);
  274. g_assert_cmpint(qdict_array_entries(dict, ""), ==, 3);
  275. qobject_unref(dict);
  276. }
  277. static void qdict_join_test(void)
  278. {
  279. QDict *dict1, *dict2;
  280. bool overwrite = false;
  281. int i;
  282. dict1 = qdict_new();
  283. dict2 = qdict_new();
  284. /* Test everything once without overwrite and once with */
  285. do {
  286. /* Test empty dicts */
  287. qdict_join(dict1, dict2, overwrite);
  288. g_assert(qdict_size(dict1) == 0);
  289. g_assert(qdict_size(dict2) == 0);
  290. /* First iteration: Test movement */
  291. /* Second iteration: Test empty source and non-empty destination */
  292. qdict_put_int(dict2, "foo", 42);
  293. for (i = 0; i < 2; i++) {
  294. qdict_join(dict1, dict2, overwrite);
  295. g_assert(qdict_size(dict1) == 1);
  296. g_assert(qdict_size(dict2) == 0);
  297. g_assert(qdict_get_int(dict1, "foo") == 42);
  298. }
  299. /* Test non-empty source and destination without conflict */
  300. qdict_put_int(dict2, "bar", 23);
  301. qdict_join(dict1, dict2, overwrite);
  302. g_assert(qdict_size(dict1) == 2);
  303. g_assert(qdict_size(dict2) == 0);
  304. g_assert(qdict_get_int(dict1, "foo") == 42);
  305. g_assert(qdict_get_int(dict1, "bar") == 23);
  306. /* Test conflict */
  307. qdict_put_int(dict2, "foo", 84);
  308. qdict_join(dict1, dict2, overwrite);
  309. g_assert(qdict_size(dict1) == 2);
  310. g_assert(qdict_size(dict2) == !overwrite);
  311. g_assert(qdict_get_int(dict1, "foo") == (overwrite ? 84 : 42));
  312. g_assert(qdict_get_int(dict1, "bar") == 23);
  313. if (!overwrite) {
  314. g_assert(qdict_get_int(dict2, "foo") == 84);
  315. }
  316. /* Check the references */
  317. g_assert(qdict_get(dict1, "foo")->base.refcnt == 1);
  318. g_assert(qdict_get(dict1, "bar")->base.refcnt == 1);
  319. if (!overwrite) {
  320. g_assert(qdict_get(dict2, "foo")->base.refcnt == 1);
  321. }
  322. /* Clean up */
  323. qdict_del(dict1, "foo");
  324. qdict_del(dict1, "bar");
  325. if (!overwrite) {
  326. qdict_del(dict2, "foo");
  327. }
  328. } while (overwrite ^= true);
  329. qobject_unref(dict1);
  330. qobject_unref(dict2);
  331. }
  332. static void qdict_crumple_test_recursive(void)
  333. {
  334. QDict *src, *dst, *rule, *vnc, *acl, *listen;
  335. QDict *empty, *empty_dict, *empty_list_0;
  336. QList *rules, *empty_list, *empty_dict_a;
  337. src = qdict_new();
  338. qdict_put_str(src, "vnc.listen.addr", "127.0.0.1");
  339. qdict_put_str(src, "vnc.listen.port", "5901");
  340. qdict_put_str(src, "vnc.acl.rules.0.match", "fred");
  341. qdict_put_str(src, "vnc.acl.rules.0.policy", "allow");
  342. qdict_put_str(src, "vnc.acl.rules.1.match", "bob");
  343. qdict_put_str(src, "vnc.acl.rules.1.policy", "deny");
  344. qdict_put_str(src, "vnc.acl.default", "deny");
  345. qdict_put_str(src, "vnc.acl..name", "acl0");
  346. qdict_put_str(src, "vnc.acl.rule..name", "acl0");
  347. qdict_put(src, "empty.dict.a", qlist_new());
  348. qdict_put(src, "empty.list.0", qdict_new());
  349. dst = qobject_to(QDict, qdict_crumple(src, &error_abort));
  350. g_assert(dst);
  351. g_assert_cmpint(qdict_size(dst), ==, 2);
  352. vnc = qdict_get_qdict(dst, "vnc");
  353. g_assert(vnc);
  354. g_assert_cmpint(qdict_size(vnc), ==, 3);
  355. listen = qdict_get_qdict(vnc, "listen");
  356. g_assert(listen);
  357. g_assert_cmpint(qdict_size(listen), ==, 2);
  358. g_assert_cmpstr("127.0.0.1", ==, qdict_get_str(listen, "addr"));
  359. g_assert_cmpstr("5901", ==, qdict_get_str(listen, "port"));
  360. acl = qdict_get_qdict(vnc, "acl");
  361. g_assert(acl);
  362. g_assert_cmpint(qdict_size(acl), ==, 3);
  363. rules = qdict_get_qlist(acl, "rules");
  364. g_assert(rules);
  365. g_assert_cmpint(qlist_size(rules), ==, 2);
  366. rule = qobject_to(QDict, qlist_pop(rules));
  367. g_assert(rule);
  368. g_assert_cmpint(qdict_size(rule), ==, 2);
  369. g_assert_cmpstr("fred", ==, qdict_get_str(rule, "match"));
  370. g_assert_cmpstr("allow", ==, qdict_get_str(rule, "policy"));
  371. qobject_unref(rule);
  372. rule = qobject_to(QDict, qlist_pop(rules));
  373. g_assert(rule);
  374. g_assert_cmpint(qdict_size(rule), ==, 2);
  375. g_assert_cmpstr("bob", ==, qdict_get_str(rule, "match"));
  376. g_assert_cmpstr("deny", ==, qdict_get_str(rule, "policy"));
  377. qobject_unref(rule);
  378. /* With recursive crumpling, we should see all names unescaped */
  379. g_assert_cmpstr("acl0", ==, qdict_get_str(vnc, "acl.name"));
  380. g_assert_cmpstr("acl0", ==, qdict_get_str(acl, "rule.name"));
  381. empty = qdict_get_qdict(dst, "empty");
  382. g_assert(empty);
  383. g_assert_cmpint(qdict_size(empty), ==, 2);
  384. empty_dict = qdict_get_qdict(empty, "dict");
  385. g_assert(empty_dict);
  386. g_assert_cmpint(qdict_size(empty_dict), ==, 1);
  387. empty_dict_a = qdict_get_qlist(empty_dict, "a");
  388. g_assert(empty_dict_a && qlist_empty(empty_dict_a));
  389. empty_list = qdict_get_qlist(empty, "list");
  390. g_assert(empty_list);
  391. g_assert_cmpint(qlist_size(empty_list), ==, 1);
  392. empty_list_0 = qobject_to(QDict, qlist_pop(empty_list));
  393. g_assert(empty_list_0);
  394. g_assert_cmpint(qdict_size(empty_list_0), ==, 0);
  395. qobject_unref(empty_list_0);
  396. qobject_unref(src);
  397. qobject_unref(dst);
  398. }
  399. static void qdict_crumple_test_empty(void)
  400. {
  401. QDict *src, *dst;
  402. src = qdict_new();
  403. dst = qobject_to(QDict, qdict_crumple(src, &error_abort));
  404. g_assert_cmpint(qdict_size(dst), ==, 0);
  405. qobject_unref(src);
  406. qobject_unref(dst);
  407. }
  408. static int qdict_count_entries(QDict *dict)
  409. {
  410. const QDictEntry *e;
  411. int count = 0;
  412. for (e = qdict_first(dict); e; e = qdict_next(dict, e)) {
  413. count++;
  414. }
  415. return count;
  416. }
  417. static void qdict_rename_keys_test(void)
  418. {
  419. QDict *dict = qdict_new();
  420. QDict *copy;
  421. QDictRenames *renames;
  422. Error *local_err = NULL;
  423. qdict_put_str(dict, "abc", "foo");
  424. qdict_put_str(dict, "abcdef", "bar");
  425. qdict_put_int(dict, "number", 42);
  426. qdict_put_bool(dict, "flag", true);
  427. qdict_put_null(dict, "nothing");
  428. /* Empty rename list */
  429. renames = (QDictRenames[]) {
  430. { NULL, "this can be anything" }
  431. };
  432. copy = qdict_clone_shallow(dict);
  433. qdict_rename_keys(copy, renames, &error_abort);
  434. g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo");
  435. g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar");
  436. g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42);
  437. g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true);
  438. g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL);
  439. g_assert_cmpint(qdict_count_entries(copy), ==, 5);
  440. qobject_unref(copy);
  441. /* Simple rename of all entries */
  442. renames = (QDictRenames[]) {
  443. { "abc", "str1" },
  444. { "abcdef", "str2" },
  445. { "number", "int" },
  446. { "flag", "bool" },
  447. { "nothing", "null" },
  448. { NULL , NULL }
  449. };
  450. copy = qdict_clone_shallow(dict);
  451. qdict_rename_keys(copy, renames, &error_abort);
  452. g_assert(!qdict_haskey(copy, "abc"));
  453. g_assert(!qdict_haskey(copy, "abcdef"));
  454. g_assert(!qdict_haskey(copy, "number"));
  455. g_assert(!qdict_haskey(copy, "flag"));
  456. g_assert(!qdict_haskey(copy, "nothing"));
  457. g_assert_cmpstr(qdict_get_str(copy, "str1"), ==, "foo");
  458. g_assert_cmpstr(qdict_get_str(copy, "str2"), ==, "bar");
  459. g_assert_cmpint(qdict_get_int(copy, "int"), ==, 42);
  460. g_assert_cmpint(qdict_get_bool(copy, "bool"), ==, true);
  461. g_assert(qobject_type(qdict_get(copy, "null")) == QTYPE_QNULL);
  462. g_assert_cmpint(qdict_count_entries(copy), ==, 5);
  463. qobject_unref(copy);
  464. /* Renames are processed top to bottom */
  465. renames = (QDictRenames[]) {
  466. { "abc", "tmp" },
  467. { "abcdef", "abc" },
  468. { "number", "abcdef" },
  469. { "flag", "number" },
  470. { "nothing", "flag" },
  471. { "tmp", "nothing" },
  472. { NULL , NULL }
  473. };
  474. copy = qdict_clone_shallow(dict);
  475. qdict_rename_keys(copy, renames, &error_abort);
  476. g_assert_cmpstr(qdict_get_str(copy, "nothing"), ==, "foo");
  477. g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "bar");
  478. g_assert_cmpint(qdict_get_int(copy, "abcdef"), ==, 42);
  479. g_assert_cmpint(qdict_get_bool(copy, "number"), ==, true);
  480. g_assert(qobject_type(qdict_get(copy, "flag")) == QTYPE_QNULL);
  481. g_assert(!qdict_haskey(copy, "tmp"));
  482. g_assert_cmpint(qdict_count_entries(copy), ==, 5);
  483. qobject_unref(copy);
  484. /* Conflicting rename */
  485. renames = (QDictRenames[]) {
  486. { "abcdef", "abc" },
  487. { NULL , NULL }
  488. };
  489. copy = qdict_clone_shallow(dict);
  490. qdict_rename_keys(copy, renames, &local_err);
  491. g_assert(local_err != NULL);
  492. error_free(local_err);
  493. local_err = NULL;
  494. g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo");
  495. g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar");
  496. g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42);
  497. g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true);
  498. g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL);
  499. g_assert_cmpint(qdict_count_entries(copy), ==, 5);
  500. qobject_unref(copy);
  501. /* Renames in an empty dict */
  502. renames = (QDictRenames[]) {
  503. { "abcdef", "abc" },
  504. { NULL , NULL }
  505. };
  506. qobject_unref(dict);
  507. dict = qdict_new();
  508. qdict_rename_keys(dict, renames, &error_abort);
  509. g_assert(qdict_first(dict) == NULL);
  510. qobject_unref(dict);
  511. }
  512. static void qdict_crumple_test_bad_inputs(void)
  513. {
  514. QDict *src, *nested;
  515. Error *error = NULL;
  516. src = qdict_new();
  517. /* rule.0 can't be both a string and a dict */
  518. qdict_put_str(src, "rule.0", "fred");
  519. qdict_put_str(src, "rule.0.policy", "allow");
  520. g_assert(qdict_crumple(src, &error) == NULL);
  521. g_assert(error != NULL);
  522. error_free(error);
  523. error = NULL;
  524. qobject_unref(src);
  525. src = qdict_new();
  526. /* rule can't be both a list and a dict */
  527. qdict_put_str(src, "rule.0", "fred");
  528. qdict_put_str(src, "rule.a", "allow");
  529. g_assert(qdict_crumple(src, &error) == NULL);
  530. g_assert(error != NULL);
  531. error_free(error);
  532. error = NULL;
  533. qobject_unref(src);
  534. src = qdict_new();
  535. /* The input should be flat, ie no dicts or lists */
  536. nested = qdict_new();
  537. qdict_put(nested, "x", qdict_new());
  538. qdict_put(src, "rule.a", nested);
  539. qdict_put_str(src, "rule.b", "allow");
  540. g_assert(qdict_crumple(src, &error) == NULL);
  541. g_assert(error != NULL);
  542. error_free(error);
  543. error = NULL;
  544. qobject_unref(src);
  545. src = qdict_new();
  546. /* List indexes must not have gaps */
  547. qdict_put_str(src, "rule.0", "deny");
  548. qdict_put_str(src, "rule.3", "allow");
  549. g_assert(qdict_crumple(src, &error) == NULL);
  550. g_assert(error != NULL);
  551. error_free(error);
  552. error = NULL;
  553. qobject_unref(src);
  554. src = qdict_new();
  555. /* List indexes must be in %zu format */
  556. qdict_put_str(src, "rule.0", "deny");
  557. qdict_put_str(src, "rule.+1", "allow");
  558. g_assert(qdict_crumple(src, &error) == NULL);
  559. g_assert(error != NULL);
  560. error_free(error);
  561. error = NULL;
  562. qobject_unref(src);
  563. }
  564. int main(int argc, char **argv)
  565. {
  566. g_test_init(&argc, &argv, NULL);
  567. g_test_add_func("/public/defaults", qdict_defaults_test);
  568. g_test_add_func("/public/flatten", qdict_flatten_test);
  569. g_test_add_func("/public/clone_flatten", qdict_clone_flatten_test);
  570. g_test_add_func("/public/array_split", qdict_array_split_test);
  571. g_test_add_func("/public/array_entries", qdict_array_entries_test);
  572. g_test_add_func("/public/join", qdict_join_test);
  573. g_test_add_func("/public/crumple/recursive",
  574. qdict_crumple_test_recursive);
  575. g_test_add_func("/public/crumple/empty",
  576. qdict_crumple_test_empty);
  577. g_test_add_func("/public/crumple/bad_inputs",
  578. qdict_crumple_test_bad_inputs);
  579. g_test_add_func("/public/rename_keys", qdict_rename_keys_test);
  580. return g_test_run();
  581. }