test_bucket.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \brief Bucket Unit Tests
  21. *
  22. * \author Joshua Colp <jcolp@digium.com>
  23. *
  24. */
  25. /*** MODULEINFO
  26. <depend>TEST_FRAMEWORK</depend>
  27. <support_level>core</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "")
  31. #include <sys/stat.h>
  32. #include "asterisk/test.h"
  33. #include "asterisk/module.h"
  34. #include "asterisk/bucket.h"
  35. #include "asterisk/logger.h"
  36. #include "asterisk/json.h"
  37. #include "asterisk/file.h"
  38. /*! \brief Test state structure for scheme wizards */
  39. struct bucket_test_state {
  40. /*! \brief Whether the object has been created or not */
  41. unsigned int created:1;
  42. /*! \brief Whether the object has been updated or not */
  43. unsigned int updated:1;
  44. /*! \brief Whether the object has been deleted or not */
  45. unsigned int deleted:1;
  46. };
  47. /*! \brief Global scope structure for testing bucket wizards */
  48. static struct bucket_test_state bucket_test_wizard_state;
  49. static void bucket_test_wizard_clear(void)
  50. {
  51. bucket_test_wizard_state.created = 0;
  52. bucket_test_wizard_state.updated = 0;
  53. bucket_test_wizard_state.deleted = 0;
  54. }
  55. static int bucket_test_wizard_create(const struct ast_sorcery *sorcery, void *data, void *object)
  56. {
  57. if (bucket_test_wizard_state.created) {
  58. return -1;
  59. }
  60. bucket_test_wizard_state.created = 1;
  61. return 0;
  62. }
  63. static int bucket_test_wizard_update(const struct ast_sorcery *sorcery, void *data, void *object)
  64. {
  65. if (bucket_test_wizard_state.updated) {
  66. return -1;
  67. }
  68. bucket_test_wizard_state.updated = 1;
  69. return 0;
  70. }
  71. static void *bucket_test_wizard_retrieve_id(const struct ast_sorcery *sorcery, void *data, const char *type,
  72. const char *id)
  73. {
  74. if (!strcmp(type, "bucket")) {
  75. return ast_bucket_alloc(id);
  76. } else if (!strcmp(type, "file")) {
  77. return ast_bucket_file_alloc(id);
  78. } else {
  79. return NULL;
  80. }
  81. }
  82. static int bucket_test_wizard_delete(const struct ast_sorcery *sorcery, void *data, void *object)
  83. {
  84. if (bucket_test_wizard_state.deleted) {
  85. return -1;
  86. }
  87. bucket_test_wizard_state.deleted = 1;
  88. return 0;
  89. }
  90. static struct ast_sorcery_wizard bucket_test_wizard = {
  91. .name = "test",
  92. .create = bucket_test_wizard_create,
  93. .retrieve_id = bucket_test_wizard_retrieve_id,
  94. .delete = bucket_test_wizard_delete,
  95. };
  96. static struct ast_sorcery_wizard bucket_file_test_wizard = {
  97. .name = "test",
  98. .create = bucket_test_wizard_create,
  99. .update = bucket_test_wizard_update,
  100. .retrieve_id = bucket_test_wizard_retrieve_id,
  101. .delete = bucket_test_wizard_delete,
  102. };
  103. AST_TEST_DEFINE(bucket_scheme_register)
  104. {
  105. switch (cmd) {
  106. case TEST_INIT:
  107. info->name = "bucket_scheme_register_unregister";
  108. info->category = "/main/bucket/";
  109. info->summary = "bucket scheme registration/unregistration unit test";
  110. info->description =
  111. "Test registration and unregistration of bucket scheme";
  112. return AST_TEST_NOT_RUN;
  113. case TEST_EXECUTE:
  114. break;
  115. }
  116. if (!ast_bucket_scheme_register("", NULL, NULL, NULL, NULL)) {
  117. ast_test_status_update(test, "Successfully registered a Bucket scheme without name or wizards\n");
  118. return AST_TEST_FAIL;
  119. }
  120. if (!ast_bucket_scheme_register("test", &bucket_test_wizard, &bucket_file_test_wizard, NULL, NULL)) {
  121. ast_test_status_update(test, "Successfully registered a Bucket scheme twice\n");
  122. return AST_TEST_FAIL;
  123. }
  124. return AST_TEST_PASS;
  125. }
  126. AST_TEST_DEFINE(bucket_alloc)
  127. {
  128. RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
  129. switch (cmd) {
  130. case TEST_INIT:
  131. info->name = "bucket_alloc";
  132. info->category = "/main/bucket/";
  133. info->summary = "bucket allocation unit test";
  134. info->description =
  135. "Test allocation of buckets";
  136. return AST_TEST_NOT_RUN;
  137. case TEST_EXECUTE:
  138. break;
  139. }
  140. if ((bucket = ast_bucket_alloc(""))) {
  141. ast_test_status_update(test, "Allocated a bucket with no URI provided\n");
  142. return AST_TEST_FAIL;
  143. }
  144. if (!(bucket = ast_bucket_alloc("test:///tmp/bob"))) {
  145. ast_test_status_update(test, "Failed to allocate bucket\n");
  146. return AST_TEST_FAIL;
  147. }
  148. if (strcmp(ast_sorcery_object_get_id(bucket), "test:///tmp/bob")) {
  149. ast_test_status_update(test, "URI within allocated bucket is '%s' and should be test:///tmp/bob\n",
  150. ast_sorcery_object_get_id(bucket));
  151. return AST_TEST_FAIL;
  152. }
  153. if (strcmp(bucket->scheme, "test")) {
  154. ast_test_status_update(test, "Scheme within allocated bucket is '%s' and should be test\n",
  155. bucket->scheme);
  156. return AST_TEST_FAIL;
  157. }
  158. return AST_TEST_PASS;
  159. }
  160. AST_TEST_DEFINE(bucket_create)
  161. {
  162. RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
  163. switch (cmd) {
  164. case TEST_INIT:
  165. info->name = "bucket_create";
  166. info->category = "/main/bucket/";
  167. info->summary = "bucket creation unit test";
  168. info->description =
  169. "Test creation of buckets";
  170. return AST_TEST_NOT_RUN;
  171. case TEST_EXECUTE:
  172. break;
  173. }
  174. if (!(bucket = ast_bucket_alloc("test:///tmp/bob"))) {
  175. ast_test_status_update(test, "Failed to allocate bucket\n");
  176. return AST_TEST_FAIL;
  177. }
  178. bucket_test_wizard_clear();
  179. if (ast_bucket_create(bucket)) {
  180. ast_test_status_update(test, "Failed to create bucket with URI '%s'\n",
  181. ast_sorcery_object_get_id(bucket));
  182. return AST_TEST_FAIL;
  183. }
  184. if (!bucket_test_wizard_state.created) {
  185. ast_test_status_update(test, "Bucket creation returned success but scheme implementation never actually created it\n");
  186. return AST_TEST_FAIL;
  187. }
  188. if (!ast_bucket_create(bucket)) {
  189. ast_test_status_update(test, "Successfully created bucket with URI '%s' twice\n",
  190. ast_sorcery_object_get_id(bucket));
  191. return AST_TEST_FAIL;
  192. }
  193. return AST_TEST_PASS;
  194. }
  195. AST_TEST_DEFINE(bucket_delete)
  196. {
  197. RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
  198. switch (cmd) {
  199. case TEST_INIT:
  200. info->name = "bucket_delete";
  201. info->category = "/main/bucket/";
  202. info->summary = "bucket deletion unit test";
  203. info->description =
  204. "Test deletion of buckets";
  205. return AST_TEST_NOT_RUN;
  206. case TEST_EXECUTE:
  207. break;
  208. }
  209. if (!(bucket = ast_bucket_alloc("test:///tmp/bob"))) {
  210. ast_test_status_update(test, "Failed to allocate bucket\n");
  211. return AST_TEST_FAIL;
  212. }
  213. bucket_test_wizard_clear();
  214. if (ast_bucket_delete(bucket)) {
  215. ast_test_status_update(test, "Failed to delete bucket with URI '%s'\n",
  216. ast_sorcery_object_get_id(bucket));
  217. return AST_TEST_FAIL;
  218. }
  219. if (!bucket_test_wizard_state.deleted) {
  220. ast_test_status_update(test, "Bucket deletion returned success but scheme implementation never actually deleted it\n");
  221. return AST_TEST_FAIL;
  222. }
  223. if (!ast_bucket_delete(bucket)) {
  224. ast_test_status_update(test, "Successfully deleted bucket with URI '%s' twice\n",
  225. ast_sorcery_object_get_id(bucket));
  226. return AST_TEST_FAIL;
  227. }
  228. return AST_TEST_PASS;
  229. }
  230. AST_TEST_DEFINE(bucket_json)
  231. {
  232. RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
  233. RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
  234. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  235. switch (cmd) {
  236. case TEST_INIT:
  237. info->name = "bucket_json";
  238. info->category = "/main/bucket/";
  239. info->summary = "bucket json unit test";
  240. info->description =
  241. "Test creation of JSON for a bucket";
  242. return AST_TEST_NOT_RUN;
  243. case TEST_EXECUTE:
  244. break;
  245. }
  246. if (!(bucket = ast_bucket_alloc("test:///tmp/bob"))) {
  247. ast_test_status_update(test, "Failed to allocate bucket\n");
  248. return AST_TEST_FAIL;
  249. }
  250. ast_str_container_add(bucket->buckets, "test:///tmp/bob/joe");
  251. ast_str_container_add(bucket->files, "test:///tmp/bob/recording.wav");
  252. expected = ast_json_pack("{s: s, s: s, s: [s], s: s, s: [s], s: s}",
  253. "modified", "0.000000", "created", "0.000000",
  254. "buckets", "test:///tmp/bob/joe",
  255. "scheme", "test",
  256. "files", "test:///tmp/bob/recording.wav",
  257. "id", "test:///tmp/bob");
  258. if (!expected) {
  259. ast_test_status_update(test, "Could not produce JSON for expected bucket value\n");
  260. return AST_TEST_FAIL;
  261. }
  262. json = ast_bucket_json(bucket);
  263. if (!json) {
  264. ast_test_status_update(test, "Could not produce JSON for a valid bucket\n");
  265. return AST_TEST_FAIL;
  266. }
  267. if (!ast_json_equal(json, expected)) {
  268. ast_test_status_update(test, "Bucket JSON does not match expected output\n");
  269. return AST_TEST_FAIL;
  270. }
  271. return AST_TEST_PASS;
  272. }
  273. AST_TEST_DEFINE(bucket_retrieve)
  274. {
  275. RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
  276. switch (cmd) {
  277. case TEST_INIT:
  278. info->name = "bucket_retrieve";
  279. info->category = "/main/bucket/";
  280. info->summary = "bucket retrieval unit test";
  281. info->description =
  282. "Test retrieval of buckets";
  283. return AST_TEST_NOT_RUN;
  284. case TEST_EXECUTE:
  285. break;
  286. }
  287. if (!(bucket = ast_bucket_retrieve("test://tmp/bob"))) {
  288. ast_test_status_update(test, "Failed to retrieve known valid bucket\n");
  289. return AST_TEST_FAIL;
  290. }
  291. return AST_TEST_PASS;
  292. }
  293. AST_TEST_DEFINE(bucket_file_alloc)
  294. {
  295. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  296. switch (cmd) {
  297. case TEST_INIT:
  298. info->name = "bucket_file_alloc";
  299. info->category = "/main/bucket/";
  300. info->summary = "bucket file allocation unit test";
  301. info->description =
  302. "Test allocation of bucket files";
  303. return AST_TEST_NOT_RUN;
  304. case TEST_EXECUTE:
  305. break;
  306. }
  307. if ((file = ast_bucket_file_alloc(""))) {
  308. ast_test_status_update(test, "Allocated a file with no URI provided\n");
  309. return AST_TEST_FAIL;
  310. }
  311. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  312. ast_test_status_update(test, "Failed to allocate file\n");
  313. return AST_TEST_FAIL;
  314. }
  315. if (ast_strlen_zero(file->path)) {
  316. ast_test_status_update(test, "Expected temporary path in allocated file");
  317. return AST_TEST_FAIL;
  318. }
  319. if (strcmp(ast_sorcery_object_get_id(file), "test:///tmp/bob")) {
  320. ast_test_status_update(test, "URI within allocated file is '%s' and should be test:///tmp/bob\n",
  321. ast_sorcery_object_get_id(file));
  322. return AST_TEST_FAIL;
  323. }
  324. if (strcmp(file->scheme, "test")) {
  325. ast_test_status_update(test, "Scheme within allocated file is '%s' and should be test\n",
  326. file->scheme);
  327. return AST_TEST_FAIL;
  328. }
  329. return AST_TEST_PASS;
  330. }
  331. AST_TEST_DEFINE(bucket_file_create)
  332. {
  333. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  334. switch (cmd) {
  335. case TEST_INIT:
  336. info->name = "bucket_file_create";
  337. info->category = "/main/bucket/";
  338. info->summary = "file creation unit test";
  339. info->description =
  340. "Test creation of files";
  341. return AST_TEST_NOT_RUN;
  342. case TEST_EXECUTE:
  343. break;
  344. }
  345. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  346. ast_test_status_update(test, "Failed to allocate file\n");
  347. return AST_TEST_FAIL;
  348. }
  349. bucket_test_wizard_clear();
  350. if (ast_bucket_file_create(file)) {
  351. ast_test_status_update(test, "Failed to create file with URI '%s'\n",
  352. ast_sorcery_object_get_id(file));
  353. return AST_TEST_FAIL;
  354. }
  355. if (!bucket_test_wizard_state.created) {
  356. ast_test_status_update(test, "Bucket file creation returned success but scheme implementation never actually created it\n");
  357. return AST_TEST_FAIL;
  358. }
  359. if (!ast_bucket_file_create(file)) {
  360. ast_test_status_update(test, "Successfully created file with URI '%s' twice\n",
  361. ast_sorcery_object_get_id(file));
  362. return AST_TEST_FAIL;
  363. }
  364. return AST_TEST_PASS;
  365. }
  366. AST_TEST_DEFINE(bucket_file_copy)
  367. {
  368. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  369. RAII_VAR(struct ast_bucket_file *, copy, NULL, ao2_cleanup);
  370. FILE *temporary;
  371. struct stat old, new;
  372. RAII_VAR(struct ast_bucket_metadata *, metadata, NULL, ao2_cleanup);
  373. switch (cmd) {
  374. case TEST_INIT:
  375. info->name = "bucket_file_copy";
  376. info->category = "/main/bucket/";
  377. info->summary = "bucket file copying unit test";
  378. info->description =
  379. "Test copying of bucket files";
  380. return AST_TEST_NOT_RUN;
  381. case TEST_EXECUTE:
  382. break;
  383. }
  384. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  385. ast_test_status_update(test, "Failed to allocate file\n");
  386. return AST_TEST_FAIL;
  387. }
  388. ast_bucket_file_metadata_set(file, "bob", "joe");
  389. if (!(temporary = fopen(file->path, "w"))) {
  390. ast_test_status_update(test, "Failed to open temporary file '%s'\n", file->path);
  391. return AST_TEST_FAIL;
  392. }
  393. fprintf(temporary, "bob");
  394. fclose(temporary);
  395. if (!(copy = ast_bucket_file_copy(file, "test:///tmp/bob2"))) {
  396. ast_test_status_update(test, "Failed to copy file '%s' to test:///tmp/bob2\n",
  397. ast_sorcery_object_get_id(file));
  398. return AST_TEST_FAIL;
  399. }
  400. if (stat(file->path, &old)) {
  401. ast_test_status_update(test, "Failed to retrieve information on old file '%s'\n", file->path);
  402. return AST_TEST_FAIL;
  403. }
  404. if (stat(copy->path, &new)) {
  405. ast_test_status_update(test, "Failed to retrieve information on copy file '%s'\n", copy->path);
  406. return AST_TEST_FAIL;
  407. }
  408. if (old.st_size != new.st_size) {
  409. ast_test_status_update(test, "Copying of underlying temporary file failed\n");
  410. return AST_TEST_FAIL;
  411. }
  412. if (ao2_container_count(file->metadata) != ao2_container_count(copy->metadata)) {
  413. ast_test_status_update(test, "Number of metadata entries does not match original\n");
  414. return AST_TEST_FAIL;
  415. }
  416. metadata = ast_bucket_file_metadata_get(copy, "bob");
  417. if (!metadata) {
  418. ast_test_status_update(test, "Copy of file does not have expected metadata\n");
  419. return AST_TEST_FAIL;
  420. }
  421. if (strcmp(metadata->value, "joe")) {
  422. ast_test_status_update(test, "Copy of file contains metadata for 'bob' but value is not what it should be\n");
  423. return AST_TEST_FAIL;
  424. }
  425. return AST_TEST_PASS;
  426. }
  427. AST_TEST_DEFINE(bucket_file_retrieve)
  428. {
  429. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  430. switch (cmd) {
  431. case TEST_INIT:
  432. info->name = "bucket_file_retrieve";
  433. info->category = "/main/bucket/";
  434. info->summary = "file retrieval unit test";
  435. info->description =
  436. "Test retrieval of files";
  437. return AST_TEST_NOT_RUN;
  438. case TEST_EXECUTE:
  439. break;
  440. }
  441. if (!(file = ast_bucket_file_retrieve("test://tmp/bob"))) {
  442. ast_test_status_update(test, "Failed to retrieve known valid file\n");
  443. return AST_TEST_FAIL;
  444. }
  445. return AST_TEST_PASS;
  446. }
  447. AST_TEST_DEFINE(bucket_file_update)
  448. {
  449. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  450. switch (cmd) {
  451. case TEST_INIT:
  452. info->name = "bucket_file_update";
  453. info->category = "/main/bucket/";
  454. info->summary = "file updating unit test";
  455. info->description =
  456. "Test updating of files";
  457. return AST_TEST_NOT_RUN;
  458. case TEST_EXECUTE:
  459. break;
  460. }
  461. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  462. ast_test_status_update(test, "Failed to allocate file\n");
  463. return AST_TEST_FAIL;
  464. }
  465. bucket_test_wizard_clear();
  466. if (ast_bucket_file_update(file)) {
  467. ast_test_status_update(test, "Failed to update file with URI '%s'\n",
  468. ast_sorcery_object_get_id(file));
  469. return AST_TEST_FAIL;
  470. }
  471. if (!bucket_test_wizard_state.updated) {
  472. ast_test_status_update(test, "Successfully returned file was updated, but it was not\n");
  473. return AST_TEST_FAIL;
  474. }
  475. if (!ast_bucket_file_update(file)) {
  476. ast_test_status_update(test, "Successfully updated file with URI '%s' twice\n",
  477. ast_sorcery_object_get_id(file));
  478. return AST_TEST_FAIL;
  479. }
  480. return AST_TEST_PASS;
  481. }
  482. AST_TEST_DEFINE(bucket_file_delete)
  483. {
  484. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  485. switch (cmd) {
  486. case TEST_INIT:
  487. info->name = "bucket_file_delete";
  488. info->category = "/main/bucket/";
  489. info->summary = "file deletion unit test";
  490. info->description =
  491. "Test deletion of files";
  492. return AST_TEST_NOT_RUN;
  493. case TEST_EXECUTE:
  494. break;
  495. }
  496. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  497. ast_test_status_update(test, "Failed to allocate file\n");
  498. return AST_TEST_FAIL;
  499. }
  500. bucket_test_wizard_clear();
  501. if (ast_bucket_file_delete(file)) {
  502. ast_test_status_update(test, "Failed to delete file with URI '%s'\n",
  503. ast_sorcery_object_get_id(file));
  504. return AST_TEST_FAIL;
  505. }
  506. if (!bucket_test_wizard_state.deleted) {
  507. ast_test_status_update(test, "Bucket file deletion returned success but scheme implementation never actually deleted it\n");
  508. return AST_TEST_FAIL;
  509. }
  510. if (!ast_bucket_file_delete(file)) {
  511. ast_test_status_update(test, "Successfully deleted file with URI '%s' twice\n",
  512. ast_sorcery_object_get_id(file));
  513. return AST_TEST_FAIL;
  514. }
  515. return AST_TEST_PASS;
  516. }
  517. AST_TEST_DEFINE(bucket_file_metadata_set)
  518. {
  519. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  520. RAII_VAR(struct ast_bucket_metadata *, metadata, NULL, ao2_cleanup);
  521. switch (cmd) {
  522. case TEST_INIT:
  523. info->name = "bucket_file_metadata_set";
  524. info->category = "/main/bucket/";
  525. info->summary = "file metadata setting unit test";
  526. info->description =
  527. "Test setting of metadata on files";
  528. return AST_TEST_NOT_RUN;
  529. case TEST_EXECUTE:
  530. break;
  531. }
  532. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  533. ast_test_status_update(test, "Failed to allocate file\n");
  534. return AST_TEST_FAIL;
  535. }
  536. if (ao2_container_count(file->metadata) != 0) {
  537. ast_test_status_update(test, "Newly allocated file has metadata count of '%d' when should be 0\n",
  538. ao2_container_count(file->metadata));
  539. return AST_TEST_FAIL;
  540. }
  541. if (ast_bucket_file_metadata_set(file, "bob", "joe")) {
  542. ast_test_status_update(test, "Failed to set metadata 'bob' to 'joe' on newly allocated file\n");
  543. return AST_TEST_FAIL;
  544. }
  545. if (!(metadata = ao2_find(file->metadata, "bob", OBJ_KEY))) {
  546. ast_test_status_update(test, "Failed to find set metadata 'bob' on newly allocated file\n");
  547. return AST_TEST_FAIL;
  548. }
  549. if (strcmp(metadata->value, "joe")) {
  550. ast_test_status_update(test, "Metadata has value '%s' when should be 'joe'\n",
  551. metadata->value);
  552. return AST_TEST_FAIL;
  553. }
  554. ao2_cleanup(metadata);
  555. metadata = NULL;
  556. if (ast_bucket_file_metadata_set(file, "bob", "fred")) {
  557. ast_test_status_update(test, "Failed to overwrite metadata 'bob' with new value 'fred'\n");
  558. return AST_TEST_FAIL;
  559. }
  560. if (!(metadata = ao2_find(file->metadata, "bob", OBJ_KEY))) {
  561. ast_test_status_update(test, "Failed to find overwritten metadata 'bob' on newly allocated file\n");
  562. return AST_TEST_FAIL;
  563. }
  564. if (strcmp(metadata->value, "fred")) {
  565. ast_test_status_update(test, "Metadata has value '%s' when should be 'fred'\n",
  566. metadata->value);
  567. return AST_TEST_FAIL;
  568. }
  569. return AST_TEST_PASS;
  570. }
  571. AST_TEST_DEFINE(bucket_file_metadata_unset)
  572. {
  573. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  574. RAII_VAR(struct ast_bucket_metadata *, metadata, NULL, ao2_cleanup);
  575. switch (cmd) {
  576. case TEST_INIT:
  577. info->name = "bucket_file_metadata_unset";
  578. info->category = "/main/bucket/";
  579. info->summary = "file metadata unsetting unit test";
  580. info->description =
  581. "Test unsetting of metadata on files";
  582. return AST_TEST_NOT_RUN;
  583. case TEST_EXECUTE:
  584. break;
  585. }
  586. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  587. ast_test_status_update(test, "Failed to allocate file\n");
  588. return AST_TEST_FAIL;
  589. }
  590. if (ast_bucket_file_metadata_set(file, "bob", "joe")) {
  591. ast_test_status_update(test, "Failed to set metadata 'bob' to 'joe' on newly allocated file\n");
  592. return AST_TEST_FAIL;
  593. }
  594. if (ast_bucket_file_metadata_unset(file, "bob")) {
  595. ast_test_status_update(test, "Failed to unset metadata 'bob' on newly allocated file\n");
  596. return AST_TEST_FAIL;
  597. }
  598. if ((metadata = ao2_find(file->metadata, "bob", OBJ_KEY))) {
  599. ast_test_status_update(test, "Metadata 'bob' was unset, but can still be found\n");
  600. return AST_TEST_FAIL;
  601. }
  602. return AST_TEST_PASS;
  603. }
  604. AST_TEST_DEFINE(bucket_file_metadata_get)
  605. {
  606. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  607. RAII_VAR(struct ast_bucket_metadata *, metadata, NULL, ao2_cleanup);
  608. switch (cmd) {
  609. case TEST_INIT:
  610. info->name = "bucket_file_metadata_get";
  611. info->category = "/main/bucket/";
  612. info->summary = "file metadata getting unit test";
  613. info->description =
  614. "Test getting of metadata on files";
  615. return AST_TEST_NOT_RUN;
  616. case TEST_EXECUTE:
  617. break;
  618. }
  619. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  620. ast_test_status_update(test, "Failed to allocate file\n");
  621. return AST_TEST_FAIL;
  622. }
  623. if (ast_bucket_file_metadata_set(file, "bob", "joe")) {
  624. ast_test_status_update(test, "Failed to set metadata 'bob' to 'joe' on newly allocated file\n");
  625. return AST_TEST_FAIL;
  626. }
  627. if (!(metadata = ast_bucket_file_metadata_get(file, "bob"))) {
  628. ast_test_status_update(test, "Failed to retrieve metadata 'bob' that was just set\n");
  629. return AST_TEST_FAIL;
  630. }
  631. if (strcmp(metadata->value, "joe")) {
  632. ast_test_status_update(test, "Retrieved metadata value is '%s' while it should be 'joe'\n",
  633. metadata->value);
  634. return AST_TEST_FAIL;
  635. }
  636. return AST_TEST_PASS;
  637. }
  638. AST_TEST_DEFINE(bucket_file_json)
  639. {
  640. RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
  641. RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
  642. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  643. switch (cmd) {
  644. case TEST_INIT:
  645. info->name = "bucket_file_json";
  646. info->category = "/main/bucket/";
  647. info->summary = "file json unit test";
  648. info->description =
  649. "Test creation of JSON for a file";
  650. return AST_TEST_NOT_RUN;
  651. case TEST_EXECUTE:
  652. break;
  653. }
  654. if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
  655. ast_test_status_update(test, "Failed to allocate bucket\n");
  656. return AST_TEST_FAIL;
  657. }
  658. if (ast_bucket_file_metadata_set(file, "bob", "joe")) {
  659. ast_test_status_update(test, "Failed to set metadata 'bob' to 'joe' on newly allocated file\n");
  660. return AST_TEST_FAIL;
  661. }
  662. expected = ast_json_pack("{s: s, s: s, s: s, s: s, s: {s :s}}",
  663. "modified", "0.000000", "created", "0.000000", "scheme", "test",
  664. "id", "test:///tmp/bob", "metadata", "bob", "joe");
  665. if (!expected) {
  666. ast_test_status_update(test, "Could not produce JSON for expected bucket file value\n");
  667. return AST_TEST_FAIL;
  668. }
  669. json = ast_bucket_file_json(file);
  670. if (!json) {
  671. ast_test_status_update(test, "Could not produce JSON for a valid file\n");
  672. return AST_TEST_FAIL;
  673. }
  674. if (!ast_json_equal(json, expected)) {
  675. ast_test_status_update(test, "Bucket file JSON does not match expected output\n");
  676. return AST_TEST_FAIL;
  677. }
  678. return AST_TEST_PASS;
  679. }
  680. static int unload_module(void)
  681. {
  682. AST_TEST_UNREGISTER(bucket_scheme_register);
  683. AST_TEST_UNREGISTER(bucket_alloc);
  684. AST_TEST_UNREGISTER(bucket_create);
  685. AST_TEST_UNREGISTER(bucket_delete);
  686. AST_TEST_UNREGISTER(bucket_retrieve);
  687. AST_TEST_UNREGISTER(bucket_json);
  688. AST_TEST_UNREGISTER(bucket_file_alloc);
  689. AST_TEST_UNREGISTER(bucket_file_create);
  690. AST_TEST_UNREGISTER(bucket_file_copy);
  691. AST_TEST_UNREGISTER(bucket_file_retrieve);
  692. AST_TEST_UNREGISTER(bucket_file_update);
  693. AST_TEST_UNREGISTER(bucket_file_delete);
  694. AST_TEST_UNREGISTER(bucket_file_metadata_set);
  695. AST_TEST_UNREGISTER(bucket_file_metadata_unset);
  696. AST_TEST_UNREGISTER(bucket_file_metadata_get);
  697. AST_TEST_UNREGISTER(bucket_file_json);
  698. return 0;
  699. }
  700. static int load_module(void)
  701. {
  702. if (ast_bucket_scheme_register("test", &bucket_test_wizard, &bucket_file_test_wizard,
  703. ast_bucket_file_temporary_create, ast_bucket_file_temporary_destroy)) {
  704. ast_log(LOG_ERROR, "Failed to register Bucket test wizard scheme implementation\n");
  705. return AST_MODULE_LOAD_DECLINE;
  706. }
  707. AST_TEST_REGISTER(bucket_scheme_register);
  708. AST_TEST_REGISTER(bucket_alloc);
  709. AST_TEST_REGISTER(bucket_create);
  710. AST_TEST_REGISTER(bucket_delete);
  711. AST_TEST_REGISTER(bucket_retrieve);
  712. AST_TEST_REGISTER(bucket_json);
  713. AST_TEST_REGISTER(bucket_file_alloc);
  714. AST_TEST_REGISTER(bucket_file_create);
  715. AST_TEST_REGISTER(bucket_file_copy);
  716. AST_TEST_REGISTER(bucket_file_retrieve);
  717. AST_TEST_REGISTER(bucket_file_update);
  718. AST_TEST_REGISTER(bucket_file_delete);
  719. AST_TEST_REGISTER(bucket_file_metadata_set);
  720. AST_TEST_REGISTER(bucket_file_metadata_unset);
  721. AST_TEST_REGISTER(bucket_file_metadata_get);
  722. AST_TEST_REGISTER(bucket_file_json);
  723. return AST_MODULE_LOAD_SUCCESS;
  724. }
  725. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Bucket test module");