test_config.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2010, Digium, Inc.
  5. *
  6. * Mark Michelson <mmichelson@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 Configuration unit tests
  21. *
  22. * \author Mark Michelson <mmichelson@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__, "$Revision$");
  31. #include <math.h> /* HUGE_VAL */
  32. #include <sys/stat.h>
  33. #include "asterisk/config.h"
  34. #include "asterisk/module.h"
  35. #include "asterisk/test.h"
  36. #include "asterisk/paths.h"
  37. #include "asterisk/config_options.h"
  38. #include "asterisk/netsock2.h"
  39. #include "asterisk/acl.h"
  40. #include "asterisk/app.h"
  41. #include "asterisk/pbx.h"
  42. #include "asterisk/frame.h"
  43. #include "asterisk/utils.h"
  44. #include "asterisk/logger.h"
  45. #include "asterisk/format_cap.h"
  46. #define CONFIG_FILE "test_config.conf"
  47. #define CONFIG_INCLUDE_FILE "test_config_include.conf"
  48. /*
  49. * This builds the folowing config:
  50. * [Capitals]
  51. * Germany = Berlin
  52. * China = Beijing
  53. * Canada = Ottawa
  54. *
  55. * [Protagonists]
  56. * 1984 = Winston Smith
  57. * Green Eggs And Ham = Sam I Am
  58. * The Kalevala = Vainamoinen
  59. *
  60. * This config is used for all tests below.
  61. */
  62. const char cat1[] = "Capitals";
  63. const char cat1varname1[] = "Germany";
  64. const char cat1varvalue1[] = "Berlin";
  65. const char cat1varname2[] = "China";
  66. const char cat1varvalue2[] = "Beijing";
  67. const char cat1varname3[] = "Canada";
  68. const char cat1varvalue3[] = "Ottawa";
  69. const char cat2[] = "Protagonists";
  70. const char cat2varname1[] = "1984";
  71. const char cat2varvalue1[] = "Winston Smith";
  72. const char cat2varname2[] = "Green Eggs And Ham";
  73. const char cat2varvalue2[] = "Sam I Am";
  74. const char cat2varname3[] = "The Kalevala";
  75. const char cat2varvalue3[] = "Vainamoinen";
  76. struct pair {
  77. const char *name;
  78. const char *val;
  79. };
  80. struct association {
  81. const char *category;
  82. struct pair vars[3];
  83. } categories [] = {
  84. { cat1,
  85. {
  86. { cat1varname1, cat1varvalue1 },
  87. { cat1varname2, cat1varvalue2 },
  88. { cat1varname3, cat1varvalue3 },
  89. }
  90. },
  91. { cat2,
  92. {
  93. { cat2varname1, cat2varvalue1 },
  94. { cat2varname2, cat2varvalue2 },
  95. { cat2varname3, cat2varvalue3 },
  96. }
  97. },
  98. };
  99. /*!
  100. * \brief Build ast_config struct from above definitions
  101. *
  102. * \retval NULL Failed to build the config
  103. * \retval non-NULL An ast_config struct populated with data
  104. */
  105. static struct ast_config *build_cfg(void)
  106. {
  107. struct ast_config *cfg;
  108. struct association *cat_iter;
  109. struct pair *var_iter;
  110. size_t i;
  111. size_t j;
  112. cfg = ast_config_new();
  113. if (!cfg) {
  114. goto fail;
  115. }
  116. for (i = 0; i < ARRAY_LEN(categories); ++i) {
  117. struct ast_category *cat;
  118. cat_iter = &categories[i];
  119. cat = ast_category_new(cat_iter->category, "", 999999);
  120. if (!cat) {
  121. goto fail;
  122. }
  123. ast_category_append(cfg, cat);
  124. for (j = 0; j < ARRAY_LEN(cat_iter->vars); ++j) {
  125. struct ast_variable *var;
  126. var_iter = &cat_iter->vars[j];
  127. var = ast_variable_new(var_iter->name, var_iter->val, "");
  128. if (!var) {
  129. goto fail;
  130. }
  131. ast_variable_append(cat, var);
  132. }
  133. }
  134. return cfg;
  135. fail:
  136. ast_config_destroy(cfg);
  137. return NULL;
  138. }
  139. /*!
  140. * \brief Tests that the contents of an ast_config is what is expected
  141. *
  142. * \param cfg Config to test
  143. * \retval -1 Failed to pass a test
  144. * \retval 0 Config passes checks
  145. */
  146. static int test_config_validity(struct ast_config *cfg)
  147. {
  148. int i;
  149. const char *cat_iter = NULL;
  150. /* Okay, let's see if the correct content is there */
  151. for (i = 0; i < ARRAY_LEN(categories); ++i) {
  152. struct ast_variable *var = NULL;
  153. size_t j;
  154. cat_iter = ast_category_browse(cfg, cat_iter);
  155. if (strcmp(cat_iter, categories[i].category)) {
  156. ast_log(LOG_ERROR, "Category name mismatch, %s does not match %s\n", cat_iter, categories[i].category);
  157. return -1;
  158. }
  159. for (j = 0; j < ARRAY_LEN(categories[i].vars); ++j) {
  160. var = var ? var->next : ast_variable_browse(cfg, cat_iter);
  161. if (strcmp(var->name, categories[i].vars[j].name)) {
  162. ast_log(LOG_ERROR, "Variable name mismatch, %s does not match %s\n", var->name, categories[i].vars[j].name);
  163. return -1;
  164. }
  165. if (strcmp(var->value, categories[i].vars[j].val)) {
  166. ast_log(LOG_ERROR, "Variable value mismatch, %s does not match %s\n", var->value, categories[i].vars[j].val);
  167. return -1;
  168. }
  169. }
  170. }
  171. return 0;
  172. }
  173. AST_TEST_DEFINE(copy_config)
  174. {
  175. enum ast_test_result_state res = AST_TEST_FAIL;
  176. struct ast_config *cfg = NULL;
  177. struct ast_config *copy = NULL;
  178. switch (cmd) {
  179. case TEST_INIT:
  180. info->name = "copy_config";
  181. info->category = "/main/config/";
  182. info->summary = "Test copying configuration";
  183. info->description =
  184. "Ensure that variables and categories are copied correctly";
  185. return AST_TEST_NOT_RUN;
  186. case TEST_EXECUTE:
  187. break;
  188. }
  189. cfg = build_cfg();
  190. if (!cfg) {
  191. goto out;
  192. }
  193. copy = ast_config_copy(cfg);
  194. if (!copy) {
  195. goto out;
  196. }
  197. if (test_config_validity(copy) != 0) {
  198. goto out;
  199. }
  200. res = AST_TEST_PASS;
  201. out:
  202. ast_config_destroy(cfg);
  203. ast_config_destroy(copy);
  204. return res;
  205. }
  206. AST_TEST_DEFINE(config_basic_ops)
  207. {
  208. enum ast_test_result_state res = AST_TEST_FAIL;
  209. struct ast_config *cfg = NULL;
  210. struct ast_category *cat = NULL;
  211. struct ast_variable *var;
  212. struct ast_variable *varlist;
  213. char temp[32];
  214. const char *cat_name;
  215. const char *var_value;
  216. int i;
  217. switch (cmd) {
  218. case TEST_INIT:
  219. info->name = "config_basic_ops";
  220. info->category = "/main/config/";
  221. info->summary = "Test basic config ops";
  222. info->description = "Test basic config ops";
  223. return AST_TEST_NOT_RUN;
  224. case TEST_EXECUTE:
  225. break;
  226. }
  227. cfg = ast_config_new();
  228. if (!cfg) {
  229. return res;
  230. }
  231. /* load the config */
  232. for(i = 0; i < 5; i++) {
  233. snprintf(temp, sizeof(temp), "test%d", i);
  234. ast_category_append(cfg, ast_category_new(temp, "dummy", -1));
  235. }
  236. /* test0 test1 test2 test3 test4 */
  237. /* check the config has 5 elements */
  238. i = 0;
  239. cat = NULL;
  240. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, NULL))) {
  241. snprintf(temp, sizeof(temp), "test%d", i);
  242. if (strcmp(ast_category_get_name(cat), temp)) {
  243. ast_test_status_update(test, "%s != %s\n", ast_category_get_name(cat), temp);
  244. goto out;
  245. }
  246. i++;
  247. }
  248. if (i != 5) {
  249. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  250. goto out;
  251. }
  252. /* search for test2 */
  253. cat = ast_category_get(cfg, "test2", NULL);
  254. if (!cat || strcmp(ast_category_get_name(cat), "test2")) {
  255. ast_test_status_update(test, "Get failed %s != %s\n", ast_category_get_name(cat), "test2");
  256. goto out;
  257. }
  258. /* delete test2 */
  259. cat = ast_category_delete(cfg, cat);
  260. /* Now: test0 test1 test3 test4 */
  261. /* make sure the curr category is test1 */
  262. if (!cat || strcmp(ast_category_get_name(cat), "test1")) {
  263. ast_test_status_update(test, "Delete failed %s != %s\n", ast_category_get_name(cat), "test1");
  264. goto out;
  265. }
  266. /* Now: test0 test1 test3 test4 */
  267. /* make sure the test2 is not found */
  268. cat = ast_category_get(cfg, "test2", NULL);
  269. if (cat) {
  270. ast_test_status_update(test, "Should not have found test2\n");
  271. goto out;
  272. }
  273. /* Now: test0 test1 test3 test4 */
  274. /* make sure the sequence is correctly missing test2 */
  275. i = 0;
  276. cat = NULL;
  277. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, NULL))) {
  278. snprintf(temp, sizeof(temp), "test%d", i);
  279. if (strcmp(ast_category_get_name(cat), temp)) {
  280. ast_test_status_update(test, "%s != %s\n", ast_category_get_name(cat), temp);
  281. goto out;
  282. }
  283. i++;
  284. if (i == 2) {
  285. i++;
  286. }
  287. }
  288. if (i != 5) {
  289. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  290. goto out;
  291. }
  292. /* insert test2 back in before test3 */
  293. ast_category_insert(cfg, ast_category_new("test2", "dummy", -1), "test3");
  294. /* Now: test0 test1 test2 test3 test4 */
  295. /* make sure the sequence is correct again */
  296. i = 0;
  297. cat = NULL;
  298. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, NULL))) {
  299. snprintf(temp, sizeof(temp), "test%d", i);
  300. if (strcmp(ast_category_get_name(cat), temp)) {
  301. ast_test_status_update(test, "%s != %s\n", ast_category_get_name(cat), temp);
  302. goto out;
  303. }
  304. i++;
  305. }
  306. if (i != 5) {
  307. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  308. goto out;
  309. }
  310. /* Now: test0 test1 test2 test3 test4 */
  311. /* make sure non filtered browse still works */
  312. i = 0;
  313. cat_name = NULL;
  314. while ((cat_name = ast_category_browse(cfg, cat_name))) {
  315. snprintf(temp, sizeof(temp), "test%d", i);
  316. if (strcmp(cat_name, temp)) {
  317. ast_test_status_update(test, "%s != %s\n", cat_name, temp);
  318. goto out;
  319. }
  320. i++;
  321. }
  322. if (i != 5) {
  323. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  324. goto out;
  325. }
  326. /* append another test2 */
  327. ast_category_append(cfg, ast_category_new("test2", "dummy", -1));
  328. /* Now: test0 test1 test2 test3 test4 test2*/
  329. /* make sure only test2's are returned */
  330. i = 0;
  331. cat = NULL;
  332. while ((cat = ast_category_browse_filtered(cfg, "test2", cat, NULL))) {
  333. if (strcmp(ast_category_get_name(cat), "test2")) {
  334. ast_test_status_update(test, "Should have returned test2 instead of %s\n", ast_category_get_name(cat));
  335. goto out;
  336. }
  337. i++;
  338. }
  339. /* make sure 2 test2's were found */
  340. if (i != 2) {
  341. ast_test_status_update(test, "Should have found 2 test2's %d\n", i);
  342. goto out;
  343. }
  344. /* Test in-flight deletion using ast_category_browse_filtered */
  345. /* Now: test0 test1 test2 test3 test4 test2 */
  346. /* Delete the middle test2 and continue */
  347. cat = NULL;
  348. for(i = 0; i < 5; i++) {
  349. snprintf(temp, sizeof(temp), "test%d", i);
  350. cat = ast_category_browse_filtered(cfg, NULL, cat, NULL);
  351. cat_name = ast_category_get_name(cat);
  352. if (strcmp(cat_name, temp)) {
  353. ast_test_status_update(test, "Should have returned %s instead of %s: %d\n", temp, cat_name, i);
  354. goto out;
  355. }
  356. if (i == 2) {
  357. cat = ast_category_delete(cfg, cat);
  358. }
  359. }
  360. /* Now: test0 test3 test4 test2 */
  361. /* delete the head item */
  362. cat = ast_category_browse_filtered(cfg, NULL, NULL, NULL);
  363. cat_name = ast_category_get_name(cat);
  364. if (strcmp(cat_name, "test0")) {
  365. ast_test_status_update(test, "Should have returned test0 instead of %s\n", cat_name);
  366. goto out;
  367. }
  368. ast_category_delete(cfg, cat);
  369. /* Now: test3 test4 test2 */
  370. /* make sure head got updated to the new first element */
  371. cat = ast_category_browse_filtered(cfg, NULL, NULL, NULL);
  372. cat_name = ast_category_get_name(cat);
  373. if (strcmp(cat_name, "test1")) {
  374. ast_test_status_update(test, "Should have returned test3 instead of %s\n", cat_name);
  375. goto out;
  376. }
  377. /* delete the tail item */
  378. cat = ast_category_get(cfg, "test2", NULL);
  379. cat_name = ast_category_get_name(cat);
  380. if (strcmp(cat_name, "test2")) {
  381. ast_test_status_update(test, "Should have returned test2 instead of %s\n", cat_name);
  382. goto out;
  383. }
  384. ast_category_delete(cfg, cat);
  385. /* Now: test3 test4 */
  386. /* There should now only be 2 elements in the list */
  387. cat = NULL;
  388. cat = ast_category_browse_filtered(cfg, NULL, cat, NULL);
  389. cat_name = ast_category_get_name(cat);
  390. if (strcmp(cat_name, "test1")) {
  391. ast_test_status_update(test, "Should have returned test1 instead of %s\n", cat_name);
  392. goto out;
  393. }
  394. cat = ast_category_browse_filtered(cfg, NULL, cat, NULL);
  395. cat_name = ast_category_get_name(cat);
  396. if (strcmp(cat_name, "test3")) {
  397. ast_test_status_update(test, "Should have returned test3 instead of %s\n", cat_name);
  398. goto out;
  399. }
  400. cat = ast_category_browse_filtered(cfg, NULL, cat, NULL);
  401. cat_name = ast_category_get_name(cat);
  402. if (strcmp(cat_name, "test4")) {
  403. ast_test_status_update(test, "Should have returned test4 instead of %s\n", cat_name);
  404. goto out;
  405. }
  406. /* There should be nothing more */
  407. cat = ast_category_browse_filtered(cfg, NULL, cat, NULL);
  408. if (cat) {
  409. ast_test_status_update(test, "Should not have returned anything\n");
  410. goto out;
  411. }
  412. /* Test ast_variable retrieve.
  413. * Get the second category.
  414. */
  415. cat = ast_category_browse_filtered(cfg, NULL, NULL, NULL);
  416. cat = ast_category_browse_filtered(cfg, NULL, cat, NULL);
  417. cat_name = ast_category_get_name(cat);
  418. var = ast_variable_new("aaa", "bbb0", "dummy");
  419. if (!var) {
  420. ast_test_status_update(test, "Couldn't allocate variable.\n");
  421. goto out;
  422. }
  423. ast_variable_append(cat, var);
  424. /* Make sure we can retrieve with specific category name */
  425. var_value = ast_variable_retrieve(cfg, cat_name, "aaa");
  426. if (!var_value || strcmp(var_value, "bbb0")) {
  427. ast_test_status_update(test, "Variable not found or wrong value.\n");
  428. goto out;
  429. }
  430. /* Make sure we can retrieve with NULL category name */
  431. var_value = ast_variable_retrieve(cfg, NULL, "aaa");
  432. if (!var_value || strcmp(var_value, "bbb0")) {
  433. ast_test_status_update(test, "Variable not found or wrong value.\n");
  434. goto out;
  435. }
  436. /* Now test variable retrieve inside a browse loop
  437. * with multiple categories of the same name
  438. */
  439. cat = ast_category_new("test3", "dummy", -1);
  440. if (!cat) {
  441. ast_test_status_update(test, "Couldn't allocate category.\n");
  442. goto out;
  443. }
  444. var = ast_variable_new("aaa", "bbb1", "dummy");
  445. if (!var) {
  446. ast_test_status_update(test, "Couldn't allocate variable.\n");
  447. goto out;
  448. }
  449. ast_variable_append(cat, var);
  450. ast_category_append(cfg, cat);
  451. cat = ast_category_new("test3", "dummy", -1);
  452. if (!cat) {
  453. ast_test_status_update(test, "Couldn't allocate category.\n");
  454. goto out;
  455. }
  456. var = ast_variable_new("aaa", "bbb2", "dummy");
  457. if (!var) {
  458. ast_test_status_update(test, "Couldn't allocate variable.\n");
  459. goto out;
  460. }
  461. ast_variable_append(cat, var);
  462. ast_category_append(cfg, cat);
  463. cat_name = NULL;
  464. i = 0;
  465. while ((cat_name = ast_category_browse(cfg, cat_name))) {
  466. if (!strcmp(cat_name, "test3")) {
  467. snprintf(temp, sizeof(temp), "bbb%d", i);
  468. var_value = ast_variable_retrieve(cfg, cat_name, "aaa");
  469. if (!var_value || strcmp(var_value, temp)) {
  470. ast_test_status_update(test, "Variable not found or wrong value %s.\n", var_value);
  471. goto out;
  472. }
  473. var = ast_variable_browse(cfg, cat_name);
  474. if (!var->value || strcmp(var->value, temp)) {
  475. ast_test_status_update(test, "Variable not found or wrong value %s.\n", var->value);
  476. goto out;
  477. }
  478. i++;
  479. }
  480. }
  481. if (i != 3) {
  482. ast_test_status_update(test, "There should have been 3 matches instead of %d.\n", i);
  483. goto out;
  484. }
  485. varlist = ast_variable_new("name1", "value1", "");
  486. ast_variable_list_append_hint(&varlist, NULL, ast_variable_new("name1", "value2", ""));
  487. ast_variable_list_append_hint(&varlist, NULL, ast_variable_new("name1", "value3", ""));
  488. var_value = ast_variable_find_in_list(varlist, "name1");
  489. if (strcmp(var_value, "value1") != 0) {
  490. ast_test_status_update(test, "Wrong variable retrieved %s.\n", var_value);
  491. goto out;
  492. }
  493. var_value = ast_variable_find_last_in_list(varlist, "name1");
  494. if (strcmp(var_value, "value3") != 0) {
  495. ast_test_status_update(test, "Wrong variable retrieved %s.\n", var_value);
  496. goto out;
  497. }
  498. res = AST_TEST_PASS;
  499. out:
  500. ast_config_destroy(cfg);
  501. return res;
  502. }
  503. AST_TEST_DEFINE(config_filtered_ops)
  504. {
  505. enum ast_test_result_state res = AST_TEST_FAIL;
  506. struct ast_config *cfg = NULL;
  507. struct ast_category *cat = NULL;
  508. char temp[32];
  509. const char *value;
  510. int i;
  511. switch (cmd) {
  512. case TEST_INIT:
  513. info->name = "config_filtered_ops";
  514. info->category = "/main/config/";
  515. info->summary = "Test filtered config ops";
  516. info->description = "Test filtered config ops";
  517. return AST_TEST_NOT_RUN;
  518. case TEST_EXECUTE:
  519. break;
  520. }
  521. cfg = ast_config_new();
  522. if (!cfg) {
  523. return res;
  524. }
  525. /* load the config */
  526. for(i = 0; i < 5; i++) {
  527. snprintf(temp, sizeof(temp), "test%d", i);
  528. cat = ast_category_new(temp, "dummy", -1);
  529. ast_variable_insert(cat, ast_variable_new("type", "a", "dummy"), "0");
  530. ast_category_append(cfg, cat);
  531. }
  532. for(i = 0; i < 5; i++) {
  533. snprintf(temp, sizeof(temp), "test%d", i);
  534. cat = ast_category_new(temp, "dummy", -1);
  535. ast_variable_insert(cat, ast_variable_new("type", "b", "dummy"), "0");
  536. ast_category_append(cfg, cat);
  537. }
  538. /* check the config has 5 elements for each type*/
  539. i = 0;
  540. cat = NULL;
  541. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, "type=a"))) {
  542. snprintf(temp, sizeof(temp), "test%d", i);
  543. if (strcmp(ast_category_get_name(cat), temp)) {
  544. ast_test_status_update(test, "%s != %s\n", ast_category_get_name(cat), temp);
  545. goto out;
  546. }
  547. value = ast_variable_find(cat, "type");
  548. if (!value || strcmp(value, "a")) {
  549. ast_test_status_update(test, "Type %s != %s\n", "a", value);
  550. goto out;
  551. }
  552. i++;
  553. }
  554. if (i != 5) {
  555. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  556. goto out;
  557. }
  558. i = 0;
  559. cat = NULL;
  560. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, "type=b"))) {
  561. snprintf(temp, sizeof(temp), "test%d", i);
  562. if (!cat || strcmp(ast_category_get_name(cat), temp)) {
  563. ast_test_status_update(test, "%s != %s\n", ast_category_get_name(cat), temp);
  564. goto out;
  565. }
  566. value = ast_variable_find(cat, "type");
  567. if (!value || strcmp(value, "b")) {
  568. ast_test_status_update(test, "Type %s != %s\n", "b", value);
  569. goto out;
  570. }
  571. i++;
  572. }
  573. if (i != 5) {
  574. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  575. goto out;
  576. }
  577. /* Delete b3 and make sure it's gone and a3 is still there.
  578. * Really this is a test of get since delete takes a specific category structure.
  579. */
  580. cat = ast_category_get(cfg, "test3", "type=b");
  581. value = ast_variable_find(cat, "type");
  582. if (strcmp(value, "b")) {
  583. ast_test_status_update(test, "Type %s != %s\n", "b", value);
  584. goto out;
  585. }
  586. ast_category_delete(cfg, cat);
  587. cat = ast_category_get(cfg, "test3", "type=b");
  588. if (cat) {
  589. ast_test_status_update(test, "Category b was not deleted.\n");
  590. goto out;
  591. }
  592. cat = ast_category_get(cfg, "test3", "type=a");
  593. if (!cat) {
  594. ast_test_status_update(test, "Category a was deleted.\n");
  595. goto out;
  596. }
  597. value = ast_variable_find(cat, "type");
  598. if (strcmp(value, "a")) {
  599. ast_test_status_update(test, "Type %s != %s\n", value, "a");
  600. goto out;
  601. }
  602. /* Basic regex stuff is handled by regcomp/regexec so not testing here.
  603. * Still need to test multiple name/value pairs though.
  604. */
  605. ast_category_empty(cat);
  606. ast_variable_insert(cat, ast_variable_new("type", "bx", "dummy"), "0");
  607. ast_variable_insert(cat, ast_variable_new("e", "z", "dummy"), "0");
  608. cat = ast_category_get(cfg, "test3", "type=.,e=z");
  609. if (!cat) {
  610. ast_test_status_update(test, "Category not found.\n");
  611. goto out;
  612. }
  613. cat = ast_category_get(cfg, "test3", "type=.,e=zX");
  614. if (cat) {
  615. ast_test_status_update(test, "Category found.\n");
  616. goto out;
  617. }
  618. cat = ast_category_get(cfg, "test3", "TEMPLATE=restrict,type=.,e=z");
  619. if (cat) {
  620. ast_test_status_update(test, "Category found.\n");
  621. goto out;
  622. }
  623. res = AST_TEST_PASS;
  624. out:
  625. ast_config_destroy(cfg);
  626. return res;
  627. }
  628. AST_TEST_DEFINE(config_template_ops)
  629. {
  630. enum ast_test_result_state res = AST_TEST_FAIL;
  631. struct ast_config *cfg = NULL;
  632. struct ast_category *cat = NULL;
  633. char temp[32];
  634. const char *value;
  635. int i;
  636. switch (cmd) {
  637. case TEST_INIT:
  638. info->name = "config_template_ops";
  639. info->category = "/main/config/";
  640. info->summary = "Test template config ops";
  641. info->description = "Test template config ops";
  642. return AST_TEST_NOT_RUN;
  643. case TEST_EXECUTE:
  644. break;
  645. }
  646. cfg = ast_config_new();
  647. if (!cfg) {
  648. return res;
  649. }
  650. /* load the config with 5 templates and 5 regular */
  651. for(i = 0; i < 5; i++) {
  652. snprintf(temp, sizeof(temp), "test%d", i);
  653. cat = ast_category_new_template(temp, "dummy", -1);
  654. ast_variable_insert(cat, ast_variable_new("type", "a", "dummy"), "0");
  655. ast_category_append(cfg, cat);
  656. }
  657. for(i = 0; i < 5; i++) {
  658. snprintf(temp, sizeof(temp), "test%d", i);
  659. cat = ast_category_new(temp, "dummy", -1);
  660. ast_variable_insert(cat, ast_variable_new("type", "b", "dummy"), "0");
  661. ast_category_append(cfg, cat);
  662. }
  663. /* check the config has 5 template elements of type a */
  664. i = 0;
  665. cat = NULL;
  666. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, "TEMPLATES=restrict,type=a"))) {
  667. snprintf(temp, sizeof(temp), "test%d", i);
  668. if (strcmp(ast_category_get_name(cat), temp)) {
  669. ast_test_status_update(test, "%s != %s\n", ast_category_get_name(cat), temp);
  670. goto out;
  671. }
  672. value = ast_variable_find(cat, "type");
  673. if (!value || strcmp(value, "a")) {
  674. ast_test_status_update(test, "Type %s != %s\n", value, "a");
  675. goto out;
  676. }
  677. i++;
  678. }
  679. if (i != 5) {
  680. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  681. goto out;
  682. }
  683. /* Test again with 'include'. There should still only be 5 (type a) */
  684. i = 0;
  685. cat = NULL;
  686. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, "TEMPLATES=include,type=a"))) {
  687. snprintf(temp, sizeof(temp), "test%d", i);
  688. if (strcmp(ast_category_get_name(cat), temp)) {
  689. ast_test_status_update(test, "%s != %s\n", ast_category_get_name(cat), temp);
  690. goto out;
  691. }
  692. value = ast_variable_find(cat, "type");
  693. if (!value || strcmp(value, "a")) {
  694. ast_test_status_update(test, "Type %s != %s\n", value, "a");
  695. goto out;
  696. }
  697. i++;
  698. }
  699. if (i != 5) {
  700. ast_test_status_update(test, "There were %d matches instead of 5.\n", i);
  701. goto out;
  702. }
  703. /* Test again with 'include' but no type. There should now be 10 (type a and type b) */
  704. i = 0;
  705. cat = NULL;
  706. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, "TEMPLATES=include"))) {
  707. i++;
  708. }
  709. if (i != 10) {
  710. ast_test_status_update(test, "There were %d matches instead of 10.\n", i);
  711. goto out;
  712. }
  713. /* Test again with 'restrict' and type b. There should 0 */
  714. i = 0;
  715. cat = NULL;
  716. while ((cat = ast_category_browse_filtered(cfg, NULL, cat, "TEMPLATES=restrict,type=b"))) {
  717. i++;
  718. }
  719. if (i != 0) {
  720. ast_test_status_update(test, "There were %d matches instead of 0.\n", i);
  721. goto out;
  722. }
  723. res = AST_TEST_PASS;
  724. out:
  725. ast_config_destroy(cfg);
  726. return res;
  727. }
  728. /*!
  729. * \brief Write the config file to disk
  730. *
  731. * This is necessary for testing config hooks since
  732. * they are only triggered when a config is read from
  733. * its intended storage medium
  734. */
  735. static int write_config_file(void)
  736. {
  737. int i;
  738. FILE *config_file;
  739. char filename[PATH_MAX];
  740. snprintf(filename, sizeof(filename), "%s/%s",
  741. ast_config_AST_CONFIG_DIR, CONFIG_FILE);
  742. config_file = fopen(filename, "w");
  743. if (!config_file) {
  744. return -1;
  745. }
  746. for (i = 0; i < ARRAY_LEN(categories); ++i) {
  747. int j;
  748. fprintf(config_file, "[%s]\n", categories[i].category);
  749. for (j = 0; j < ARRAY_LEN(categories[i].vars); ++j) {
  750. fprintf(config_file, "%s = %s\n",
  751. categories[i].vars[j].name,
  752. categories[i].vars[j].val);
  753. }
  754. }
  755. fclose(config_file);
  756. return 0;
  757. }
  758. /*!
  759. * \brief Delete config file created by write_config_file
  760. */
  761. static void delete_config_file(void)
  762. {
  763. char filename[PATH_MAX];
  764. snprintf(filename, sizeof(filename), "%s/%s",
  765. ast_config_AST_CONFIG_DIR, CONFIG_FILE);
  766. unlink(filename);
  767. }
  768. /*
  769. * Boolean to indicate if the config hook has run
  770. */
  771. static int hook_run;
  772. /*
  773. * Boolean to indicate if, when the hook runs, the
  774. * data passed to it is what is expected
  775. */
  776. static int hook_config_sane;
  777. static int hook_cb(struct ast_config *cfg)
  778. {
  779. hook_run = 1;
  780. if (test_config_validity(cfg) == 0) {
  781. hook_config_sane = 1;
  782. }
  783. ast_config_destroy(cfg);
  784. return 0;
  785. }
  786. AST_TEST_DEFINE(config_save)
  787. {
  788. enum ast_test_result_state res = AST_TEST_FAIL;
  789. struct ast_flags config_flags = { 0 };
  790. struct ast_config *cfg;
  791. char config_filename[PATH_MAX];
  792. char include_filename[PATH_MAX];
  793. struct stat config_stat;
  794. off_t before_save;
  795. switch (cmd) {
  796. case TEST_INIT:
  797. info->name = "config_save";
  798. info->category = "/main/config/";
  799. info->summary = "Test config save";
  800. info->description =
  801. "Test configuration save.";
  802. return AST_TEST_NOT_RUN;
  803. case TEST_EXECUTE:
  804. break;
  805. }
  806. if (write_config_file()) {
  807. ast_test_status_update(test, "Could not write initial config files\n");
  808. return res;
  809. }
  810. snprintf(config_filename, PATH_MAX, "%s/%s", ast_config_AST_CONFIG_DIR, CONFIG_FILE);
  811. snprintf(include_filename, PATH_MAX, "%s/%s", ast_config_AST_CONFIG_DIR, CONFIG_INCLUDE_FILE);
  812. cfg = ast_config_load(CONFIG_FILE, config_flags);
  813. if (!cfg) {
  814. ast_test_status_update(test, "Could not load config\n");
  815. goto out;
  816. }
  817. /* We need to re-save to get the generator header */
  818. if (ast_config_text_file_save(CONFIG_FILE, cfg, "TEST")) {
  819. ast_test_status_update(test, "Unable to write files\n");
  820. goto out;
  821. }
  822. stat(config_filename, &config_stat);
  823. before_save = config_stat.st_size;
  824. if (!ast_include_new(cfg, CONFIG_FILE, CONFIG_INCLUDE_FILE, 0, NULL, 4, include_filename, PATH_MAX)) {
  825. ast_test_status_update(test, "Could not create include\n");
  826. goto out;
  827. }
  828. if (ast_config_text_file_save(CONFIG_FILE, cfg, "TEST")) {
  829. ast_test_status_update(test, "Unable to write files\n");
  830. goto out;
  831. }
  832. stat(config_filename, &config_stat);
  833. if (config_stat.st_size <= before_save) {
  834. ast_test_status_update(test, "Did not save config file with #include\n");
  835. goto out;
  836. }
  837. res = AST_TEST_PASS;
  838. out:
  839. ast_config_destroy(cfg);
  840. unlink(config_filename);
  841. unlink(include_filename);
  842. return res;
  843. }
  844. AST_TEST_DEFINE(config_hook)
  845. {
  846. enum ast_test_result_state res = AST_TEST_FAIL;
  847. enum config_hook_flags hook_flags = { 0, };
  848. struct ast_flags config_flags = { 0 };
  849. struct ast_flags reload_flags = { CONFIG_FLAG_FILEUNCHANGED };
  850. struct ast_config *cfg;
  851. switch (cmd) {
  852. case TEST_INIT:
  853. info->name = "config_hook";
  854. info->category = "/main/config/";
  855. info->summary = "Test config hooks";
  856. info->description =
  857. "Ensure that config hooks are called at approriate times,"
  858. "not called at inappropriate times, and that all information"
  859. "that should be present is present.";
  860. return AST_TEST_NOT_RUN;
  861. case TEST_EXECUTE:
  862. break;
  863. }
  864. write_config_file();
  865. /*
  866. * Register a config hook to run when CONFIG_FILE is loaded by this module
  867. */
  868. ast_config_hook_register("test_hook",
  869. CONFIG_FILE,
  870. AST_MODULE,
  871. hook_flags,
  872. hook_cb);
  873. /*
  874. * Try loading the config file. This should result in the hook
  875. * being called
  876. */
  877. cfg = ast_config_load(CONFIG_FILE, config_flags);
  878. ast_config_destroy(cfg);
  879. if (!hook_run || !hook_config_sane) {
  880. ast_test_status_update(test, "Config hook either did not run or was given bad data!\n");
  881. goto out;
  882. }
  883. /*
  884. * Now try loading the wrong config file but from the right module.
  885. * Hook should not run
  886. */
  887. hook_run = 0;
  888. cfg = ast_config_load("asterisk.conf", config_flags);
  889. ast_config_destroy(cfg);
  890. if (hook_run) {
  891. ast_test_status_update(test, "Config hook ran even though an incorrect file was specified.\n");
  892. goto out;
  893. }
  894. /*
  895. * Now try loading the correct config file but from the wrong module.
  896. * Hook should not run
  897. */
  898. hook_run = 0;
  899. cfg = ast_config_load2(CONFIG_FILE, "fake_module.so", config_flags);
  900. ast_config_destroy(cfg);
  901. if (hook_run) {
  902. ast_test_status_update(test, "Config hook ran even though an incorrect module was specified.\n");
  903. goto out;
  904. }
  905. /*
  906. * Now try loading the file correctly, but without any changes to the file.
  907. * Hook should not run
  908. */
  909. hook_run = 0;
  910. cfg = ast_config_load(CONFIG_FILE, reload_flags);
  911. /* Only destroy this cfg conditionally. Otherwise a crash happens. */
  912. if (cfg != CONFIG_STATUS_FILEUNCHANGED) {
  913. ast_config_destroy(cfg);
  914. }
  915. if (hook_run) {
  916. ast_test_status_update(test, "Config hook ran even though file contents had not changed\n");
  917. goto out;
  918. }
  919. res = AST_TEST_PASS;
  920. out:
  921. ast_config_hook_unregister("test_hook");
  922. delete_config_file();
  923. return res;
  924. }
  925. enum {
  926. EXPECT_FAIL = 0,
  927. EXPECT_SUCCEED,
  928. };
  929. #define TOOBIG_I32 "2147483649"
  930. #define TOOSMALL_I32 "-2147483649"
  931. #define TOOBIG_U32 "4294967297"
  932. #define TOOSMALL_U32 "-4294967297"
  933. #define DEFAULTVAL 42
  934. #define EPSILON 0.001
  935. #define TEST_PARSE(input, should_succeed, expected_result, flags, result, ...) do {\
  936. int __res = ast_parse_arg(input, (flags), result, ##__VA_ARGS__); \
  937. if (!__res == !should_succeed) { \
  938. ast_test_status_update(test, "ast_parse_arg failed on '%s'. %d/%d\n", input, __res, should_succeed); \
  939. ret = AST_TEST_FAIL; \
  940. } else { \
  941. if (((flags) & PARSE_TYPE) == PARSE_INT32) { \
  942. int32_t *r = (int32_t *) (void *) result; \
  943. int32_t e = (int32_t) expected_result; \
  944. if (*r != e) { \
  945. ast_test_status_update(test, "ast_parse_arg int32_t failed with %d != %d\n", *r, e); \
  946. ret = AST_TEST_FAIL; \
  947. } \
  948. } else if (((flags) & PARSE_TYPE) == PARSE_UINT32) { \
  949. uint32_t *r = (uint32_t *) (void *) result; \
  950. uint32_t e = (uint32_t) expected_result; \
  951. if (*r != e) { \
  952. ast_test_status_update(test, "ast_parse_arg uint32_t failed with %u != %u\n", *r, e); \
  953. ret = AST_TEST_FAIL; \
  954. } \
  955. } else if (((flags) & PARSE_TYPE) == PARSE_DOUBLE) { \
  956. double *r = (double *) (void *) result; \
  957. double e = (double) expected_result; \
  958. if (fabs(*r - e) > EPSILON) { \
  959. ast_test_status_update(test, "ast_parse_arg double failed with %f != %f\n", *r, e); \
  960. ret = AST_TEST_FAIL; \
  961. } \
  962. } else if (((flags) & PARSE_TYPE) == PARSE_TIMELEN) { \
  963. int *r = (int *) (void *) result; \
  964. int e = (int) expected_result; \
  965. if (*r != e) { \
  966. ast_test_status_update(test, "ast_parse_arg timelen failed with %d != %d\n", *r, e); \
  967. ret = AST_TEST_FAIL; \
  968. } \
  969. } \
  970. } \
  971. *(result) = DEFAULTVAL; \
  972. } while (0)
  973. AST_TEST_DEFINE(ast_parse_arg_test)
  974. {
  975. int ret = AST_TEST_PASS;
  976. int32_t int32_t_val = DEFAULTVAL;
  977. uint32_t uint32_t_val = DEFAULTVAL;
  978. int timelen_val = DEFAULTVAL;
  979. double double_val = DEFAULTVAL;
  980. switch (cmd) {
  981. case TEST_INIT:
  982. info->name = "ast_parse_arg";
  983. info->category = "/config/";
  984. info->summary = "Test the output of ast_parse_arg";
  985. info->description =
  986. "Ensures that ast_parse_arg behaves as expected";
  987. return AST_TEST_NOT_RUN;
  988. case TEST_EXECUTE:
  989. break;
  990. }
  991. /* int32 testing */
  992. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_INT32, &int32_t_val);
  993. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_INT32, &int32_t_val);
  994. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_INT32, &int32_t_val);
  995. TEST_PARSE(TOOBIG_I32, EXPECT_FAIL, DEFAULTVAL, PARSE_INT32, &int32_t_val);
  996. TEST_PARSE(TOOSMALL_I32, EXPECT_FAIL, DEFAULTVAL, PARSE_INT32, &int32_t_val);
  997. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32, &int32_t_val);
  998. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32, &int32_t_val);
  999. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_INT32 | PARSE_DEFAULT, &int32_t_val, 7);
  1000. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_INT32 | PARSE_DEFAULT, &int32_t_val, 7);
  1001. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_INT32 | PARSE_DEFAULT, &int32_t_val, 7);
  1002. TEST_PARSE(TOOBIG_I32, EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT, &int32_t_val, 7);
  1003. TEST_PARSE(TOOSMALL_I32, EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT, &int32_t_val, 7);
  1004. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT, &int32_t_val, 7);
  1005. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT, &int32_t_val, 7);
  1006. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, 0, 200);
  1007. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, -200, 100);
  1008. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, -1, 0);
  1009. TEST_PARSE("123", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, 0, 122);
  1010. TEST_PARSE("-123", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, -122, 100);
  1011. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, 1, 100);
  1012. TEST_PARSE(TOOBIG_I32, EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1013. TEST_PARSE(TOOSMALL_I32, EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1014. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1015. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_IN_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1016. TEST_PARSE("123", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, 0, 200);
  1017. TEST_PARSE("-123", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, -200, 100);
  1018. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, -1, 0);
  1019. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, 0, 122);
  1020. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, -122, 100);
  1021. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, 1, 100);
  1022. TEST_PARSE(TOOBIG_I32, EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1023. TEST_PARSE(TOOSMALL_I32, EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1024. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1025. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_INT32 | PARSE_OUT_RANGE, &int32_t_val, INT_MIN, INT_MAX);
  1026. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, 0, 200);
  1027. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, -200, 100);
  1028. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, -1, 0);
  1029. TEST_PARSE("123", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, 0, 122);
  1030. TEST_PARSE("-123", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, -122, 100);
  1031. TEST_PARSE("0", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, 1, 100);
  1032. TEST_PARSE(TOOBIG_I32, EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1033. TEST_PARSE(TOOSMALL_I32, EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1034. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1035. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1036. TEST_PARSE("123", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, 0, 200);
  1037. TEST_PARSE("-123", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, -200, 100);
  1038. TEST_PARSE("0", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, -1, 0);
  1039. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, 0, 122);
  1040. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, -122, 100);
  1041. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, 1, 100);
  1042. TEST_PARSE(TOOBIG_I32, EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1043. TEST_PARSE(TOOSMALL_I32, EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1044. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1045. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_INT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &int32_t_val, 7, INT_MIN, INT_MAX);
  1046. /* uuint32 testing */
  1047. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_UINT32, &uint32_t_val);
  1048. TEST_PARSE("-123", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32, &uint32_t_val);
  1049. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_UINT32, &uint32_t_val);
  1050. TEST_PARSE(TOOBIG_U32, EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32, &uint32_t_val);
  1051. TEST_PARSE(TOOSMALL_U32, EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32, &uint32_t_val);
  1052. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32, &uint32_t_val);
  1053. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32, &uint32_t_val);
  1054. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_UINT32 | PARSE_DEFAULT, &uint32_t_val, 7);
  1055. TEST_PARSE("-123", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT, &uint32_t_val, 7);
  1056. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_UINT32 | PARSE_DEFAULT, &uint32_t_val, 7);
  1057. TEST_PARSE(TOOBIG_U32, EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT, &uint32_t_val, 7);
  1058. TEST_PARSE(TOOSMALL_U32, EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT, &uint32_t_val, 7);
  1059. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT, &uint32_t_val, 7);
  1060. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT, &uint32_t_val, 7);
  1061. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, 0, 200);
  1062. TEST_PARSE("-123", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, 0, 200);
  1063. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, 0, 1);
  1064. TEST_PARSE("123", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, 0, 122);
  1065. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, 1, 100);
  1066. TEST_PARSE(TOOBIG_U32, EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1067. TEST_PARSE(TOOSMALL_U32, EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1068. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1069. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_IN_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1070. TEST_PARSE("123", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, 0, 200);
  1071. TEST_PARSE("-123", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, 0, 200);
  1072. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, 0, 1);
  1073. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, 0, 122);
  1074. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, 1, 100);
  1075. TEST_PARSE(TOOBIG_U32, EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1076. TEST_PARSE(TOOSMALL_U32, EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1077. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1078. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32 | PARSE_OUT_RANGE, &uint32_t_val, INT_MIN, INT_MAX);
  1079. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, 0, 200);
  1080. TEST_PARSE("-123", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, 0, 200);
  1081. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, 0, 1);
  1082. TEST_PARSE("123", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, 0, 122);
  1083. TEST_PARSE("0", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, 1, 100);
  1084. TEST_PARSE(TOOBIG_U32, EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1085. TEST_PARSE(TOOSMALL_U32, EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1086. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1087. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_IN_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1088. TEST_PARSE("123", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, 0, 200);
  1089. TEST_PARSE("-123", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, 0, 100);
  1090. TEST_PARSE("0", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, 0, 1);
  1091. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, 0, 122);
  1092. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, 1, 100);
  1093. TEST_PARSE(TOOBIG_U32, EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1094. TEST_PARSE(TOOSMALL_U32, EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1095. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1096. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_UINT32 | PARSE_DEFAULT | PARSE_OUT_RANGE, &uint32_t_val, 7, INT_MIN, INT_MAX);
  1097. TEST_PARSE(" -123", EXPECT_FAIL, DEFAULTVAL, PARSE_UINT32, &uint32_t_val);
  1098. /* timelen testing */
  1099. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1100. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1101. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1102. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1103. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1104. TEST_PARSE("123s", EXPECT_SUCCEED, 123000, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1105. TEST_PARSE("-123s", EXPECT_SUCCEED, -123000, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1106. TEST_PARSE("1m", EXPECT_SUCCEED, 60000, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1107. TEST_PARSE("1", EXPECT_SUCCEED, 60000, PARSE_TIMELEN, &timelen_val, TIMELEN_MINUTES);
  1108. TEST_PARSE("1h", EXPECT_SUCCEED, 3600000, PARSE_TIMELEN, &timelen_val, TIMELEN_MILLISECONDS);
  1109. TEST_PARSE("1", EXPECT_SUCCEED, 3600000, PARSE_TIMELEN, &timelen_val, TIMELEN_HOURS);
  1110. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_TIMELEN | PARSE_DEFAULT, &timelen_val, TIMELEN_MILLISECONDS, 7);
  1111. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_TIMELEN | PARSE_DEFAULT, &timelen_val, TIMELEN_MILLISECONDS, 7);
  1112. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_TIMELEN | PARSE_DEFAULT, &timelen_val, TIMELEN_MILLISECONDS, 7);
  1113. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT, &timelen_val, TIMELEN_MILLISECONDS, 7);
  1114. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT, &timelen_val, TIMELEN_MILLISECONDS, 7);
  1115. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 0, 200);
  1116. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, -200, 100);
  1117. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, -1, 0);
  1118. TEST_PARSE("123", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 0, 122);
  1119. TEST_PARSE("-123", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, -122, 100);
  1120. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 1, 100);
  1121. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, INT_MIN, INT_MAX);
  1122. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, INT_MIN, INT_MAX);
  1123. TEST_PARSE("123", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 0, 200);
  1124. TEST_PARSE("-123", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, -200, 100);
  1125. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, -1, 0);
  1126. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 0, 122);
  1127. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, -122, 100);
  1128. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 1, 100);
  1129. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, INT_MIN, INT_MAX);
  1130. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_TIMELEN | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, INT_MIN, INT_MAX);
  1131. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, 0, 200);
  1132. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, -200, 100);
  1133. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, -1, 0);
  1134. TEST_PARSE("123", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, 0, 122);
  1135. TEST_PARSE("-123", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, -122, 100);
  1136. TEST_PARSE("0", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, 1, 100);
  1137. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, INT_MIN, INT_MAX);
  1138. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_IN_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, INT_MIN, INT_MAX);
  1139. TEST_PARSE("123", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, 0, 200);
  1140. TEST_PARSE("-123", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, -200, 100);
  1141. TEST_PARSE("0", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, -1, 0);
  1142. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, 0, 122);
  1143. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, -122, 100);
  1144. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, 1, 100);
  1145. TEST_PARSE("not a number", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, INT_MIN, INT_MAX);
  1146. TEST_PARSE("7not a number", EXPECT_FAIL, 7, PARSE_TIMELEN | PARSE_DEFAULT | PARSE_OUT_RANGE, &timelen_val, TIMELEN_MILLISECONDS, 7, INT_MIN, INT_MAX);
  1147. /* double testing */
  1148. TEST_PARSE("123", EXPECT_SUCCEED, 123, PARSE_DOUBLE, &double_val);
  1149. TEST_PARSE("123.123", EXPECT_SUCCEED, 123.123, PARSE_DOUBLE, &double_val);
  1150. TEST_PARSE("-123", EXPECT_SUCCEED, -123, PARSE_DOUBLE, &double_val);
  1151. TEST_PARSE("-123.123", EXPECT_SUCCEED, -123.123, PARSE_DOUBLE, &double_val);
  1152. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_DOUBLE, &double_val);
  1153. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE, &double_val);
  1154. TEST_PARSE("7.0not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE, &double_val);
  1155. TEST_PARSE("123.123", EXPECT_SUCCEED, 123.123, PARSE_DOUBLE | PARSE_DEFAULT, &double_val, 7.0);
  1156. TEST_PARSE("-123.123", EXPECT_SUCCEED, -123.123, PARSE_DOUBLE | PARSE_DEFAULT, &double_val, 7.0);
  1157. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_DOUBLE | PARSE_DEFAULT, &double_val, 7.0);
  1158. TEST_PARSE("not a number", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT, &double_val, 7.0);
  1159. TEST_PARSE("7.0not a number", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT, &double_val, 7.0);
  1160. TEST_PARSE("123.123", EXPECT_SUCCEED, 123.123, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, 0.0, 200.0);
  1161. TEST_PARSE("-123.123", EXPECT_SUCCEED, -123.123, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, -200.0, 100.0);
  1162. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, -1.0, 0.0);
  1163. TEST_PARSE("123.123", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, 0.0, 122.0);
  1164. TEST_PARSE("-123.123", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, -122.0, 100.0);
  1165. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, 1.0, 100.0);
  1166. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, -HUGE_VAL, HUGE_VAL);
  1167. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_IN_RANGE, &double_val, -HUGE_VAL, HUGE_VAL);
  1168. TEST_PARSE("123.123", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, 0.0, 200.0);
  1169. TEST_PARSE("-123.123", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, -200.0, 100.0);
  1170. TEST_PARSE("0", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, -1.0, 0.0);
  1171. TEST_PARSE("123.123", EXPECT_SUCCEED, 123.123, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, 0.0, 122.0);
  1172. TEST_PARSE("-123.123", EXPECT_SUCCEED, -123.123, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, -122.0, 100.0);
  1173. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, 1.0, 100.0);
  1174. TEST_PARSE("not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, -HUGE_VAL, HUGE_VAL);
  1175. TEST_PARSE("7not a number", EXPECT_FAIL, DEFAULTVAL, PARSE_DOUBLE | PARSE_OUT_RANGE, &double_val, -HUGE_VAL, HUGE_VAL);
  1176. TEST_PARSE("123.123", EXPECT_SUCCEED, 123.123, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, 0.0, 200.0);
  1177. TEST_PARSE("-123.123", EXPECT_SUCCEED, -123.123, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, -200.0, 100.0);
  1178. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, -1.0, 0.0);
  1179. TEST_PARSE("123.123", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, 0.0, 122.0);
  1180. TEST_PARSE("-123.123", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, -122.0, 100.0);
  1181. TEST_PARSE("0", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, 1.0, 100.0);
  1182. TEST_PARSE("not a number", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, -HUGE_VAL, HUGE_VAL);
  1183. TEST_PARSE("7not a number", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_IN_RANGE, &double_val, 7.0, -HUGE_VAL, HUGE_VAL);
  1184. TEST_PARSE("123.123", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, 0.0, 200.0);
  1185. TEST_PARSE("-123.123", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, -200.0, 100.0);
  1186. TEST_PARSE("0", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, -1.0, 0.0);
  1187. TEST_PARSE("123.123", EXPECT_SUCCEED, 123.123, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, 0.0, 122.0);
  1188. TEST_PARSE("-123.123", EXPECT_SUCCEED, -123.123, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, -122.0, 100.0);
  1189. TEST_PARSE("0", EXPECT_SUCCEED, 0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, 1.0, 100.0);
  1190. TEST_PARSE("not a number", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, -HUGE_VAL, HUGE_VAL);
  1191. TEST_PARSE("7not a number", EXPECT_FAIL, 7.0, PARSE_DOUBLE | PARSE_DEFAULT | PARSE_OUT_RANGE, &double_val, 7.0, -HUGE_VAL, HUGE_VAL);
  1192. /* ast_sockaddr_parse is tested extensively in test_netsock2.c and PARSE_ADDR is a very simple wrapper */
  1193. return ret;
  1194. }
  1195. struct test_item {
  1196. AST_DECLARE_STRING_FIELDS(
  1197. AST_STRING_FIELD(name);
  1198. AST_STRING_FIELD(stropt);
  1199. );
  1200. int32_t intopt;
  1201. uint32_t uintopt;
  1202. int timelenopt1;
  1203. int timelenopt2;
  1204. int timelenopt3;
  1205. int timelenopt4;
  1206. unsigned int flags;
  1207. double doubleopt;
  1208. struct ast_sockaddr sockaddropt;
  1209. int boolopt;
  1210. struct ast_ha *aclopt;
  1211. struct ast_format_cap *codeccapopt;
  1212. unsigned int customopt:1;
  1213. };
  1214. struct test_config {
  1215. struct test_item *global;
  1216. struct test_item *global_defaults;
  1217. struct ao2_container *items;
  1218. };
  1219. static int test_item_cmp(void *obj, void *arg, int flags)
  1220. {
  1221. struct test_item *one = obj, *two = arg;
  1222. const char *match = (flags & OBJ_KEY) ? arg : two->name;
  1223. return strcasecmp(one->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
  1224. }
  1225. static void test_item_destructor(void *obj)
  1226. {
  1227. struct test_item *item = obj;
  1228. ast_string_field_free_memory(item);
  1229. ao2_cleanup(item->codeccapopt);
  1230. if (item->aclopt) {
  1231. ast_free_ha(item->aclopt);
  1232. }
  1233. return;
  1234. }
  1235. static void *test_item_alloc(const char *cat)
  1236. {
  1237. struct test_item *item;
  1238. if (!(item = ao2_alloc(sizeof(*item), test_item_destructor))) {
  1239. return NULL;
  1240. }
  1241. if (ast_string_field_init(item, 128)) {
  1242. ao2_ref(item, -1);
  1243. return NULL;
  1244. }
  1245. if (!(item->codeccapopt = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
  1246. ao2_ref(item, -1);
  1247. return NULL;
  1248. }
  1249. ast_string_field_set(item, name, cat);
  1250. return item;
  1251. }
  1252. static void test_config_destructor(void *obj)
  1253. {
  1254. struct test_config *cfg = obj;
  1255. ao2_cleanup(cfg->global);
  1256. ao2_cleanup(cfg->global_defaults);
  1257. ao2_cleanup(cfg->items);
  1258. }
  1259. static void *test_config_alloc(void)
  1260. {
  1261. struct test_config *cfg;
  1262. if (!(cfg = ao2_alloc(sizeof(*cfg), test_config_destructor))) {
  1263. goto error;
  1264. }
  1265. if (!(cfg->global = test_item_alloc("global"))) {
  1266. goto error;
  1267. }
  1268. if (!(cfg->global_defaults = test_item_alloc("global_defaults"))) {
  1269. goto error;
  1270. }
  1271. cfg->items = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, test_item_cmp);
  1272. if (!cfg->items) {
  1273. goto error;
  1274. }
  1275. return cfg;
  1276. error:
  1277. ao2_cleanup(cfg);
  1278. return NULL;
  1279. }
  1280. static void *test_item_find(struct ao2_container *container, const char *cat)
  1281. {
  1282. return ao2_find(container, cat, OBJ_KEY);
  1283. }
  1284. static int customopt_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
  1285. {
  1286. struct test_item *item = obj;
  1287. if (!strcasecmp(var->name, "customopt")) {
  1288. item->customopt = ast_true(var->value);
  1289. } else {
  1290. return -1;
  1291. }
  1292. return 0;
  1293. }
  1294. static struct aco_type global = {
  1295. .type = ACO_GLOBAL,
  1296. .item_offset = offsetof(struct test_config, global),
  1297. .category_match = ACO_WHITELIST,
  1298. .category = "^global$",
  1299. };
  1300. static struct aco_type global_defaults = {
  1301. .type = ACO_GLOBAL,
  1302. .item_offset = offsetof(struct test_config, global_defaults),
  1303. .category_match = ACO_WHITELIST_EXACT,
  1304. .category = "global_defaults",
  1305. };
  1306. static const char *item_blacklist[] = {
  1307. "global",
  1308. "global_defaults",
  1309. NULL,
  1310. };
  1311. static struct aco_type item = {
  1312. .type = ACO_ITEM,
  1313. .category_match = ACO_BLACKLIST_ARRAY,
  1314. .category = (const char *)item_blacklist,
  1315. .item_alloc = test_item_alloc,
  1316. .item_find = test_item_find,
  1317. .item_offset = offsetof(struct test_config, items),
  1318. };
  1319. struct aco_file config_test_conf = {
  1320. .filename = "config_test.conf",
  1321. .types = ACO_TYPES(&global, &global_defaults, &item),
  1322. };
  1323. static AO2_GLOBAL_OBJ_STATIC(global_obj);
  1324. CONFIG_INFO_TEST(cfg_info, global_obj, test_config_alloc,
  1325. .files = ACO_FILES(&config_test_conf),
  1326. );
  1327. AST_TEST_DEFINE(config_options_test)
  1328. {
  1329. int res = AST_TEST_PASS, x, error;
  1330. struct test_item defaults = { 0, }, configs = { 0, };
  1331. struct test_item *arr[4];
  1332. struct ast_sockaddr acl_allow = {{ 0, }}, acl_fail = {{ 0, }};
  1333. RAII_VAR(struct test_config *, cfg, NULL, ao2_cleanup);
  1334. RAII_VAR(struct test_item *, item, NULL, ao2_cleanup);
  1335. RAII_VAR(struct test_item *, item_defaults, NULL, ao2_cleanup);
  1336. switch (cmd) {
  1337. case TEST_INIT:
  1338. info->name = "config_options_test";
  1339. info->category = "/config/";
  1340. info->summary = "Config opptions unit test";
  1341. info->description =
  1342. "Tests the Config Options API";
  1343. return AST_TEST_NOT_RUN;
  1344. case TEST_EXECUTE:
  1345. break;
  1346. }
  1347. #define INT_DEFAULT "-2"
  1348. #define INT_CONFIG "-1"
  1349. #define UINT_DEFAULT "2"
  1350. #define UINT_CONFIG "1"
  1351. #define TIMELEN_DEFAULT "2"
  1352. #define TIMELEN_CONFIG "1"
  1353. #define DOUBLE_DEFAULT "1.1"
  1354. #define DOUBLE_CONFIG "0.1"
  1355. #define SOCKADDR_DEFAULT "4.3.2.1:4321"
  1356. #define SOCKADDR_CONFIG "1.2.3.4:1234"
  1357. #define BOOL_DEFAULT "false"
  1358. #define BOOL_CONFIG "true"
  1359. #define BOOLFLAG1_DEFAULT "false"
  1360. #define BOOLFLAG1_CONFIG "true"
  1361. #define BOOLFLAG2_DEFAULT "false"
  1362. #define BOOLFLAG2_CONFIG "false"
  1363. #define BOOLFLAG3_DEFAULT "false"
  1364. #define BOOLFLAG3_CONFIG "true"
  1365. #define ACL_DEFAULT NULL
  1366. #define ACL_CONFIG_PERMIT "1.2.3.4/32"
  1367. #define ACL_CONFIG_DENY "0.0.0.0/0"
  1368. #define CODEC_DEFAULT "!all,alaw"
  1369. #define CODEC_CONFIG "!all,ulaw,g729"
  1370. #define STR_DEFAULT "default"
  1371. #define STR_CONFIG "test"
  1372. #define CUSTOM_DEFAULT "no"
  1373. #define CUSTOM_CONFIG "yes"
  1374. #define BOOLFLAG1 1 << 0
  1375. #define BOOLFLAG2 1 << 1
  1376. #define BOOLFLAG3 1 << 2
  1377. if (aco_info_init(&cfg_info)) {
  1378. ast_test_status_update(test, "Could not init cfg info\n");
  1379. return AST_TEST_FAIL;
  1380. }
  1381. /* Register all options */
  1382. aco_option_register(&cfg_info, "intopt", ACO_EXACT, config_test_conf.types, INT_DEFAULT, OPT_INT_T, 0, FLDSET(struct test_item, intopt));
  1383. aco_option_register(&cfg_info, "uintopt", ACO_EXACT, config_test_conf.types, UINT_DEFAULT, OPT_UINT_T, 0, FLDSET(struct test_item, uintopt));
  1384. aco_option_register(&cfg_info, "timelenopt1", ACO_EXACT, config_test_conf.types, TIMELEN_DEFAULT, OPT_TIMELEN_T, 0, FLDSET(struct test_item, timelenopt1), TIMELEN_MILLISECONDS);
  1385. aco_option_register(&cfg_info, "timelenopt2", ACO_EXACT, config_test_conf.types, TIMELEN_DEFAULT, OPT_TIMELEN_T, 0, FLDSET(struct test_item, timelenopt2), TIMELEN_SECONDS);
  1386. aco_option_register(&cfg_info, "timelenopt3", ACO_EXACT, config_test_conf.types, TIMELEN_DEFAULT, OPT_TIMELEN_T, 0, FLDSET(struct test_item, timelenopt3), TIMELEN_MINUTES);
  1387. aco_option_register(&cfg_info, "timelenopt4", ACO_EXACT, config_test_conf.types, TIMELEN_DEFAULT, OPT_TIMELEN_T, 0, FLDSET(struct test_item, timelenopt4), TIMELEN_HOURS);
  1388. aco_option_register(&cfg_info, "doubleopt", ACO_EXACT, config_test_conf.types, DOUBLE_DEFAULT, OPT_DOUBLE_T, 0, FLDSET(struct test_item, doubleopt));
  1389. aco_option_register(&cfg_info, "sockaddropt", ACO_EXACT, config_test_conf.types, SOCKADDR_DEFAULT, OPT_SOCKADDR_T, 0, FLDSET(struct test_item, sockaddropt));
  1390. aco_option_register(&cfg_info, "boolopt", ACO_EXACT, config_test_conf.types, BOOL_DEFAULT, OPT_BOOL_T, 1, FLDSET(struct test_item, boolopt));
  1391. aco_option_register(&cfg_info, "boolflag1", ACO_EXACT, config_test_conf.types, BOOLFLAG1_DEFAULT, OPT_BOOLFLAG_T, 1, FLDSET(struct test_item, flags), BOOLFLAG1);
  1392. aco_option_register(&cfg_info, "boolflag2", ACO_EXACT, config_test_conf.types, BOOLFLAG2_DEFAULT, OPT_BOOLFLAG_T, 1, FLDSET(struct test_item, flags), BOOLFLAG2);
  1393. aco_option_register(&cfg_info, "boolflag3", ACO_EXACT, config_test_conf.types, BOOLFLAG3_DEFAULT, OPT_BOOLFLAG_T, 1, FLDSET(struct test_item, flags), BOOLFLAG3);
  1394. aco_option_register(&cfg_info, "aclpermitopt", ACO_EXACT, config_test_conf.types, ACL_DEFAULT, OPT_ACL_T, 1, FLDSET(struct test_item, aclopt));
  1395. aco_option_register(&cfg_info, "acldenyopt", ACO_EXACT, config_test_conf.types, ACL_DEFAULT, OPT_ACL_T, 0, FLDSET(struct test_item, aclopt));
  1396. aco_option_register(&cfg_info, "codecopt", ACO_EXACT, config_test_conf.types, CODEC_DEFAULT, OPT_CODEC_T, 1, FLDSET(struct test_item, codeccapopt));
  1397. aco_option_register(&cfg_info, "stropt", ACO_EXACT, config_test_conf.types, STR_DEFAULT, OPT_STRINGFIELD_T, 0, STRFLDSET(struct test_item, stropt));
  1398. aco_option_register_custom(&cfg_info, "customopt", ACO_EXACT, config_test_conf.types, CUSTOM_DEFAULT, customopt_handler, 0);
  1399. aco_option_register_deprecated(&cfg_info, "permit", config_test_conf.types, "aclpermitopt");
  1400. aco_option_register_deprecated(&cfg_info, "deny", config_test_conf.types, "acldenyopt");
  1401. if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
  1402. ast_test_status_update(test, "Could not parse config\n");
  1403. return AST_TEST_FAIL;
  1404. }
  1405. ast_parse_arg(INT_DEFAULT, PARSE_INT32, &defaults.intopt);
  1406. ast_parse_arg(INT_CONFIG, PARSE_INT32, &configs.intopt);
  1407. ast_parse_arg(TIMELEN_DEFAULT, PARSE_TIMELEN, &defaults.timelenopt1, TIMELEN_MILLISECONDS);
  1408. ast_parse_arg(TIMELEN_CONFIG, PARSE_TIMELEN, &configs.timelenopt1, TIMELEN_MILLISECONDS);
  1409. ast_parse_arg(TIMELEN_DEFAULT, PARSE_TIMELEN, &defaults.timelenopt2, TIMELEN_SECONDS);
  1410. ast_parse_arg(TIMELEN_CONFIG, PARSE_TIMELEN, &configs.timelenopt2, TIMELEN_SECONDS);
  1411. ast_parse_arg(TIMELEN_DEFAULT, PARSE_TIMELEN, &defaults.timelenopt3, TIMELEN_MINUTES);
  1412. ast_parse_arg(TIMELEN_CONFIG, PARSE_TIMELEN, &configs.timelenopt3, TIMELEN_MINUTES);
  1413. ast_parse_arg(TIMELEN_DEFAULT, PARSE_TIMELEN, &defaults.timelenopt4, TIMELEN_HOURS);
  1414. ast_parse_arg(TIMELEN_CONFIG, PARSE_TIMELEN, &configs.timelenopt4, TIMELEN_HOURS);
  1415. ast_parse_arg(UINT_DEFAULT, PARSE_UINT32, &defaults.uintopt);
  1416. ast_parse_arg(UINT_CONFIG, PARSE_UINT32, &configs.uintopt);
  1417. ast_parse_arg(DOUBLE_DEFAULT, PARSE_DOUBLE, &defaults.doubleopt);
  1418. ast_parse_arg(DOUBLE_CONFIG, PARSE_DOUBLE, &configs.doubleopt);
  1419. ast_parse_arg(SOCKADDR_DEFAULT, PARSE_ADDR, &defaults.sockaddropt);
  1420. ast_parse_arg(SOCKADDR_CONFIG, PARSE_ADDR, &configs.sockaddropt);
  1421. defaults.boolopt = ast_true(BOOL_DEFAULT);
  1422. configs.boolopt = ast_true(BOOL_CONFIG);
  1423. ast_set2_flag(&defaults, ast_true(BOOLFLAG1_DEFAULT), BOOLFLAG1);
  1424. ast_set2_flag(&defaults, ast_true(BOOLFLAG2_DEFAULT), BOOLFLAG2);
  1425. ast_set2_flag(&defaults, ast_true(BOOLFLAG3_DEFAULT), BOOLFLAG3);
  1426. ast_set2_flag(&configs, ast_true(BOOLFLAG1_CONFIG), BOOLFLAG1);
  1427. ast_set2_flag(&configs, ast_true(BOOLFLAG2_CONFIG), BOOLFLAG2);
  1428. ast_set2_flag(&configs, ast_true(BOOLFLAG3_CONFIG), BOOLFLAG3);
  1429. defaults.aclopt = NULL;
  1430. configs.aclopt = ast_append_ha("deny", ACL_CONFIG_DENY, configs.aclopt, &error);
  1431. configs.aclopt = ast_append_ha("permit", ACL_CONFIG_PERMIT, configs.aclopt, &error);
  1432. ast_sockaddr_parse(&acl_allow, "1.2.3.4", PARSE_PORT_FORBID);
  1433. ast_sockaddr_parse(&acl_fail, "1.1.1.1", PARSE_PORT_FORBID);
  1434. defaults.codeccapopt = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
  1435. ast_format_cap_update_by_allow_disallow(defaults.codeccapopt, CODEC_DEFAULT, 1);
  1436. configs.codeccapopt = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
  1437. ast_format_cap_update_by_allow_disallow(configs.codeccapopt, CODEC_CONFIG, 1);
  1438. ast_string_field_init(&defaults, 128);
  1439. ast_string_field_init(&configs, 128);
  1440. ast_string_field_set(&defaults, stropt, STR_DEFAULT);
  1441. ast_string_field_set(&configs, stropt, STR_CONFIG);
  1442. defaults.customopt = ast_true(CUSTOM_DEFAULT);
  1443. configs.customopt = ast_true(CUSTOM_CONFIG);
  1444. cfg = ao2_global_obj_ref(global_obj);
  1445. if (!(item = ao2_find(cfg->items, "item", OBJ_KEY))) {
  1446. ast_test_status_update(test, "could not look up 'item'\n");
  1447. return AST_TEST_FAIL;
  1448. }
  1449. if (!(item_defaults = ao2_find(cfg->items, "item_defaults", OBJ_KEY))) {
  1450. ast_test_status_update(test, "could not look up 'item_defaults'\n");
  1451. return AST_TEST_FAIL;
  1452. }
  1453. arr[0] = cfg->global;
  1454. arr[1] = item;
  1455. arr[2] = cfg->global_defaults;
  1456. arr[3] = item_defaults;
  1457. /* Test global and item against configs, global_defaults and item_defaults against defaults */
  1458. #define NOT_EQUAL_FAIL(field, format) \
  1459. if (arr[x]->field != control->field) { \
  1460. ast_test_status_update(test, "%s did not match: " format " != " format " with x = %d\n", #field, arr[x]->field, control->field, x); \
  1461. res = AST_TEST_FAIL; \
  1462. }
  1463. for (x = 0; x < 4; x++) {
  1464. struct test_item *control = x < 2 ? &configs : &defaults;
  1465. NOT_EQUAL_FAIL(intopt, "%d");
  1466. NOT_EQUAL_FAIL(uintopt, "%u");
  1467. NOT_EQUAL_FAIL(timelenopt1, "%d");
  1468. NOT_EQUAL_FAIL(timelenopt2, "%d");
  1469. NOT_EQUAL_FAIL(timelenopt3, "%d");
  1470. NOT_EQUAL_FAIL(timelenopt4, "%d");
  1471. NOT_EQUAL_FAIL(boolopt, "%d");
  1472. NOT_EQUAL_FAIL(flags, "%u");
  1473. NOT_EQUAL_FAIL(customopt, "%d");
  1474. if (fabs(arr[x]->doubleopt - control->doubleopt) > 0.001) {
  1475. ast_test_status_update(test, "doubleopt did not match: %f vs %f on loop %d\n", arr[x]->doubleopt, control->doubleopt, x);
  1476. res = AST_TEST_FAIL;
  1477. }
  1478. if (ast_sockaddr_cmp(&arr[x]->sockaddropt, &control->sockaddropt)) {
  1479. ast_test_status_update(test, "sockaddr did not match on loop %d\n", x);
  1480. res = AST_TEST_FAIL;
  1481. }
  1482. if (!ast_format_cap_identical(arr[x]->codeccapopt, control->codeccapopt)) {
  1483. struct ast_str *codec_buf1 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
  1484. struct ast_str *codec_buf2 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
  1485. ast_test_status_update(test, "format did not match: '%s' vs '%s' on loop %d\n",
  1486. ast_format_cap_get_names(arr[x]->codeccapopt, &codec_buf1),
  1487. ast_format_cap_get_names(control->codeccapopt, &codec_buf2),
  1488. x);
  1489. res = AST_TEST_FAIL;
  1490. }
  1491. if (strcasecmp(arr[x]->stropt, control->stropt)) {
  1492. ast_test_status_update(test, "stropt did not match: '%s' vs '%s' on loop %d\n", arr[x]->stropt, control->stropt, x);
  1493. res = AST_TEST_FAIL;
  1494. }
  1495. if (arr[x]->aclopt != control->aclopt && (ast_apply_ha(arr[x]->aclopt, &acl_allow) != ast_apply_ha(control->aclopt, &acl_allow) ||
  1496. ast_apply_ha(arr[x]->aclopt, &acl_fail) != ast_apply_ha(control->aclopt, &acl_fail))) {
  1497. ast_test_status_update(test, "acl not match: on loop %d\n", x);
  1498. res = AST_TEST_FAIL;
  1499. }
  1500. }
  1501. ast_free_ha(configs.aclopt);
  1502. ao2_cleanup(defaults.codeccapopt);
  1503. defaults.codeccapopt = NULL;
  1504. ao2_cleanup(configs.codeccapopt);
  1505. configs.codeccapopt = NULL;
  1506. ast_string_field_free_memory(&defaults);
  1507. ast_string_field_free_memory(&configs);
  1508. aco_info_destroy(&cfg_info);
  1509. ao2_global_obj_release(global_obj);
  1510. return res;
  1511. }
  1512. AST_TEST_DEFINE(config_dialplan_function)
  1513. {
  1514. enum ast_test_result_state res = AST_TEST_PASS;
  1515. FILE *config_file;
  1516. char filename[PATH_MAX];
  1517. struct ast_str *buf;
  1518. switch (cmd) {
  1519. case TEST_INIT:
  1520. info->name = "config_dialplan_function";
  1521. info->category = "/main/config/";
  1522. info->summary = "Test AST_CONFIG dialplan function";
  1523. info->description = "Test AST_CONFIG dialplan function";
  1524. return AST_TEST_NOT_RUN;
  1525. case TEST_EXECUTE:
  1526. break;
  1527. }
  1528. snprintf(filename, sizeof(filename), "%s/%s",
  1529. ast_config_AST_CONFIG_DIR, CONFIG_FILE);
  1530. config_file = fopen(filename, "w");
  1531. if (!config_file) {
  1532. return AST_TEST_FAIL;
  1533. }
  1534. fputs(
  1535. "[c1t](!)\n"
  1536. "var1=val1\n"
  1537. "var1=val2\n"
  1538. "var2=val21\n"
  1539. "\n"
  1540. "[c1](c1t)\n"
  1541. "var1=val3\n"
  1542. "var1=val4\n"
  1543. , config_file);
  1544. fclose(config_file);
  1545. if (!(buf = ast_str_create(32))) {
  1546. ast_test_status_update(test, "Failed to allocate return buffer\n");
  1547. res = AST_TEST_FAIL;
  1548. goto out;
  1549. }
  1550. if (ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var1)", &buf, 32)) {
  1551. ast_test_status_update(test, "Failed to retrieve field 'var1'\n");
  1552. res = AST_TEST_FAIL;
  1553. goto out;
  1554. }
  1555. if (strcmp(ast_str_buffer(buf), "val1")) {
  1556. ast_test_status_update(test, "Got '%s', should be '%s'\n",
  1557. ast_str_buffer(buf), "val1");
  1558. res = AST_TEST_FAIL;
  1559. goto out;
  1560. }
  1561. ast_str_reset(buf);
  1562. if (ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var1,0)", &buf, 32)) {
  1563. ast_test_status_update(test, "Failed to retrieve field 'var1'\n");
  1564. res = AST_TEST_FAIL;
  1565. goto out;
  1566. }
  1567. if (strcmp(ast_str_buffer(buf), "val1")) {
  1568. ast_test_status_update(test, "Got '%s', should be '%s'\n",
  1569. ast_str_buffer(buf), "val1");
  1570. res = AST_TEST_FAIL;
  1571. goto out;
  1572. }
  1573. ast_str_reset(buf);
  1574. if (ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var1,1)", &buf, 32)) {
  1575. ast_test_status_update(test, "Failed to retrieve field 'var1'\n");
  1576. res = AST_TEST_FAIL;
  1577. goto out;
  1578. }
  1579. if (strcmp(ast_str_buffer(buf), "val2")) {
  1580. ast_test_status_update(test, "Got '%s', should be '%s'\n",
  1581. ast_str_buffer(buf), "val2");
  1582. res = AST_TEST_FAIL;
  1583. goto out;
  1584. }
  1585. ast_str_reset(buf);
  1586. if (ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var1,2)", &buf, 32)) {
  1587. ast_test_status_update(test, "Failed to retrieve field 'var1'\n");
  1588. res = AST_TEST_FAIL;
  1589. goto out;
  1590. }
  1591. if (strcmp(ast_str_buffer(buf), "val3")) {
  1592. ast_test_status_update(test, "Got '%s', should be '%s'\n",
  1593. ast_str_buffer(buf), "val3");
  1594. res = AST_TEST_FAIL;
  1595. goto out;
  1596. }
  1597. ast_str_reset(buf);
  1598. if (ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var1,3)", &buf, 32)) {
  1599. ast_test_status_update(test, "Failed to retrieve field 'var1'\n");
  1600. res = AST_TEST_FAIL;
  1601. goto out;
  1602. }
  1603. if (strcmp(ast_str_buffer(buf), "val4")) {
  1604. ast_test_status_update(test, "Got '%s', should be '%s'\n",
  1605. ast_str_buffer(buf), "val4");
  1606. res = AST_TEST_FAIL;
  1607. goto out;
  1608. }
  1609. ast_str_reset(buf);
  1610. if (ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var1,-1)", &buf, 32)) {
  1611. ast_test_status_update(test, "Failed to retrieve field 'var1'\n");
  1612. res = AST_TEST_FAIL;
  1613. goto out;
  1614. }
  1615. if (strcmp(ast_str_buffer(buf), "val4")) {
  1616. ast_test_status_update(test, "Got '%s', should be '%s'\n",
  1617. ast_str_buffer(buf), "val4");
  1618. res = AST_TEST_FAIL;
  1619. goto out;
  1620. }
  1621. ast_str_reset(buf);
  1622. if (ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var2,-1)", &buf, 32)) {
  1623. ast_test_status_update(test, "Failed to retrieve field 'var2'\n");
  1624. res = AST_TEST_FAIL;
  1625. goto out;
  1626. }
  1627. if (strcmp(ast_str_buffer(buf), "val21")) {
  1628. ast_test_status_update(test, "Got '%s', should be '%s'\n",
  1629. ast_str_buffer(buf), "val21");
  1630. res = AST_TEST_FAIL;
  1631. goto out;
  1632. }
  1633. ast_str_reset(buf);
  1634. if (!ast_func_read2(NULL, "AST_CONFIG("CONFIG_FILE",c1,var1,5)", &buf, 32)) {
  1635. ast_test_status_update(test, "Should not have retrieved a value\n");
  1636. res = AST_TEST_FAIL;
  1637. goto out;
  1638. }
  1639. out:
  1640. if (buf) {
  1641. ast_free(buf);
  1642. }
  1643. delete_config_file();
  1644. return res;
  1645. }
  1646. AST_TEST_DEFINE(variable_lists_match)
  1647. {
  1648. RAII_VAR(struct ast_variable *, left, NULL, ast_variables_destroy);
  1649. RAII_VAR(struct ast_variable *, right, NULL, ast_variables_destroy);
  1650. struct ast_variable *var;
  1651. switch (cmd) {
  1652. case TEST_INIT:
  1653. info->name = "variable_lists_match";
  1654. info->category = "/main/config/";
  1655. info->summary = "Test ast_variable_lists_match";
  1656. info->description = "Test ast_variable_lists_match";
  1657. return AST_TEST_NOT_RUN;
  1658. case TEST_EXECUTE:
  1659. break;
  1660. }
  1661. var = ast_variable_new("aaa", "111", "");
  1662. ast_test_validate(test, var);
  1663. left = var;
  1664. var = ast_variable_new("bbb", "222", "");
  1665. ast_test_validate(test, var);
  1666. ast_variable_list_append(&left, var);
  1667. var = ast_variable_new("aaa", "111", "");
  1668. ast_test_validate(test, var);
  1669. right = var;
  1670. ast_test_validate(test, ast_variable_lists_match(left, right, 0));
  1671. ast_test_validate(test, !ast_variable_lists_match(left, right, 1));
  1672. var = ast_variable_new("bbb", "222", "");
  1673. ast_test_validate(test, var);
  1674. ast_variable_list_append(&right, var);
  1675. ast_test_validate(test, ast_variable_lists_match(left, right, 0));
  1676. ast_test_validate(test, ast_variable_lists_match(left, right, 1));
  1677. var = ast_variable_new("ccc >", "333", "");
  1678. ast_test_validate(test, var);
  1679. ast_variable_list_append(&right, var);
  1680. ast_test_validate(test, !ast_variable_lists_match(left, right, 0));
  1681. ast_test_validate(test, !ast_variable_lists_match(left, right, 1));
  1682. var = ast_variable_new("ccc", "444", "");
  1683. ast_test_validate(test, var);
  1684. ast_variable_list_append(&left, var);
  1685. ast_test_validate(test, ast_variable_lists_match(left, right, 0));
  1686. ast_test_validate(test, !ast_variable_lists_match(left, right, 1));
  1687. ast_test_validate(test, !ast_variable_lists_match(left, NULL, 0));
  1688. ast_test_validate(test, ast_variable_lists_match(NULL, NULL, 0));
  1689. ast_test_validate(test, !ast_variable_lists_match(NULL, right, 0));
  1690. ast_test_validate(test, ast_variable_lists_match(left, left, 0));
  1691. return AST_TEST_PASS;
  1692. }
  1693. static int unload_module(void)
  1694. {
  1695. AST_TEST_UNREGISTER(config_save);
  1696. AST_TEST_UNREGISTER(config_basic_ops);
  1697. AST_TEST_UNREGISTER(config_filtered_ops);
  1698. AST_TEST_UNREGISTER(config_template_ops);
  1699. AST_TEST_UNREGISTER(copy_config);
  1700. AST_TEST_UNREGISTER(config_hook);
  1701. AST_TEST_UNREGISTER(ast_parse_arg_test);
  1702. AST_TEST_UNREGISTER(config_options_test);
  1703. AST_TEST_UNREGISTER(config_dialplan_function);
  1704. AST_TEST_UNREGISTER(variable_lists_match);
  1705. return 0;
  1706. }
  1707. static int load_module(void)
  1708. {
  1709. AST_TEST_REGISTER(config_save);
  1710. AST_TEST_REGISTER(config_basic_ops);
  1711. AST_TEST_REGISTER(config_filtered_ops);
  1712. AST_TEST_REGISTER(config_template_ops);
  1713. AST_TEST_REGISTER(copy_config);
  1714. AST_TEST_REGISTER(config_hook);
  1715. AST_TEST_REGISTER(ast_parse_arg_test);
  1716. AST_TEST_REGISTER(config_options_test);
  1717. AST_TEST_REGISTER(config_dialplan_function);
  1718. AST_TEST_REGISTER(variable_lists_match);
  1719. return AST_MODULE_LOAD_SUCCESS;
  1720. }
  1721. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Config test module");