Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

1627 rader
62 KiB

  1. -module(rebar_ct_SUITE).
  2. -export([all/0,
  3. groups/0,
  4. init_per_group/2,
  5. end_per_group/2]).
  6. -export([basic_app_default_dirs/1,
  7. basic_app_default_beams/1,
  8. basic_app_ct_macro/1,
  9. multi_app_default_dirs/1,
  10. multi_app_default_beams/1,
  11. multi_app_ct_macro/1,
  12. single_app_dir/1,
  13. single_extra_dir/1,
  14. single_unmanaged_dir/1,
  15. single_suite/1,
  16. single_extra_suite/1,
  17. single_unmanaged_suite/1,
  18. multi_suite/1,
  19. all_suite/1,
  20. single_dir_and_single_suite/1,
  21. suite_at_root/1,
  22. suite_at_app_root/1,
  23. data_dir_correct/1,
  24. cmd_label/1,
  25. cmd_config/1,
  26. cmd_spec/1,
  27. cmd_join_specs/1,
  28. cmd_allow_user_terms/1,
  29. cmd_logdir/1,
  30. cmd_logopts/1,
  31. cmd_verbosity/1,
  32. cmd_repeat/1,
  33. cmd_duration/1,
  34. cmd_until/1,
  35. cmd_force_stop/1,
  36. cmd_basic_html/1,
  37. cmd_stylesheet/1,
  38. cmd_decrypt_key/1,
  39. cmd_decrypt_file/1,
  40. cmd_abort_if_missing_suites/1,
  41. cmd_multiply_timetraps/1,
  42. cmd_scale_timetraps/1,
  43. cmd_create_priv_dir/1,
  44. cmd_include_dir/1,
  45. cmd_sys_config/1,
  46. cfg_opts/1,
  47. cfg_arbitrary_opts/1,
  48. cfg_cover_spec/1,
  49. cfg_atom_suites/1,
  50. cover_compiled/1,
  51. misspecified_ct_opts/1,
  52. misspecified_ct_compile_opts/1,
  53. misspecified_ct_first_files/1,
  54. testspec/1,
  55. testspec_at_root/1,
  56. testspec_parse_error/1,
  57. cmd_vs_cfg_opts/1,
  58. single_testspec_in_ct_opts/1,
  59. compile_only/1]).
  60. -include_lib("eunit/include/eunit.hrl").
  61. -include_lib("common_test/include/ct.hrl").
  62. all() -> [{group, basic_app},
  63. {group, multi_app},
  64. {group, dirs_and_suites},
  65. {group, data_dirs},
  66. {group, ct_opts},
  67. {group, cover},
  68. cfg_opts, cfg_arbitrary_opts,
  69. cfg_cover_spec,
  70. cfg_atom_suites,
  71. misspecified_ct_opts,
  72. misspecified_ct_compile_opts,
  73. misspecified_ct_first_files,
  74. testspec,
  75. testspec_at_root,
  76. testspec_parse_error,
  77. cmd_vs_cfg_opts,
  78. single_testspec_in_ct_opts,
  79. compile_only].
  80. groups() -> [{basic_app, [], [basic_app_default_dirs,
  81. basic_app_default_beams,
  82. basic_app_ct_macro]},
  83. {multi_app, [], [multi_app_default_dirs,
  84. multi_app_default_beams,
  85. multi_app_ct_macro]},
  86. {dirs_and_suites, [], [single_app_dir,
  87. single_extra_dir,
  88. single_unmanaged_dir,
  89. single_suite,
  90. single_extra_suite,
  91. single_unmanaged_suite,
  92. multi_suite,
  93. all_suite,
  94. single_dir_and_single_suite,
  95. suite_at_root,
  96. suite_at_app_root]},
  97. {data_dirs, [], [data_dir_correct]},
  98. {ct_opts, [], [cmd_label,
  99. cmd_config,
  100. cmd_spec,
  101. cmd_join_specs,
  102. cmd_allow_user_terms,
  103. cmd_logdir,
  104. cmd_logopts,
  105. cmd_verbosity,
  106. cmd_repeat,
  107. cmd_duration,
  108. cmd_until,
  109. cmd_force_stop,
  110. cmd_basic_html,
  111. cmd_stylesheet,
  112. cmd_decrypt_key,
  113. cmd_decrypt_file,
  114. cmd_abort_if_missing_suites,
  115. cmd_multiply_timetraps,
  116. cmd_scale_timetraps,
  117. cmd_create_priv_dir,
  118. cmd_include_dir,
  119. cmd_sys_config]},
  120. {cover, [], [cover_compiled]}].
  121. init_per_group(basic_app, Config) ->
  122. C = rebar_test_utils:init_rebar_state(Config, "ct_"),
  123. AppDir = ?config(apps, C),
  124. Name = rebar_test_utils:create_random_name(atom_to_list(basic_app) ++ "_"),
  125. Vsn = rebar_test_utils:create_random_vsn(),
  126. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  127. Suite = filename:join([AppDir, "test", Name ++ "_SUITE.erl"]),
  128. ok = filelib:ensure_dir(Suite),
  129. ok = file:write_file(Suite, test_suite(Name)),
  130. {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
  131. Tests = rebar_prv_common_test:prepare_tests(State),
  132. {ok, NewState} = rebar_prv_common_test:compile(State, Tests),
  133. {ok, T} = Tests,
  134. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  135. [{result, Opts}, {appnames, [Name]}, {compile_state, NewState}|C];
  136. init_per_group(multi_app, Config) ->
  137. C = rebar_test_utils:init_rebar_state(Config, "ct_"),
  138. AppDir = ?config(apps, C),
  139. Name1 = rebar_test_utils:create_random_name(atom_to_list(multi_app) ++ "_"),
  140. Vsn1 = rebar_test_utils:create_random_vsn(),
  141. AppDir1 = filename:join([AppDir, "apps", Name1]),
  142. rebar_test_utils:create_app(AppDir1, Name1, Vsn1, [kernel, stdlib]),
  143. Suite1 = filename:join([AppDir1, "test", Name1 ++ "_SUITE.erl"]),
  144. ok = filelib:ensure_dir(Suite1),
  145. ok = file:write_file(Suite1, test_suite(Name1)),
  146. Name2 = rebar_test_utils:create_random_name(atom_to_list(multi_app) ++ "_"),
  147. Vsn2 = rebar_test_utils:create_random_vsn(),
  148. AppDir2 = filename:join([AppDir, "apps", Name2]),
  149. rebar_test_utils:create_app(AppDir2, Name2, Vsn2, [kernel, stdlib]),
  150. Suite2 = filename:join([AppDir2, "test", Name2 ++ "_SUITE.erl"]),
  151. ok = filelib:ensure_dir(Suite2),
  152. ok = file:write_file(Suite2, test_suite(Name2)),
  153. Suite3 = filename:join([AppDir, "test", "extras_SUITE.erl"]),
  154. ok = filelib:ensure_dir(Suite3),
  155. ok = file:write_file(Suite3, test_suite("extras")),
  156. {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
  157. Tests = rebar_prv_common_test:prepare_tests(State),
  158. {ok, NewState} = rebar_prv_common_test:compile(State, Tests),
  159. {ok, T} = Tests,
  160. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  161. [{result, Opts}, {appnames, [Name1, Name2]}, {compile_state, NewState}|C];
  162. init_per_group(dirs_and_suites, Config) ->
  163. C = rebar_test_utils:init_rebar_state(Config, "ct_"),
  164. AppDir = ?config(apps, C),
  165. Name1 = rebar_test_utils:create_random_name(atom_to_list(dirs_and_suites) ++ "_"),
  166. Vsn1 = rebar_test_utils:create_random_vsn(),
  167. AppDir1 = filename:join([AppDir, "apps", Name1]),
  168. rebar_test_utils:create_app(AppDir1, Name1, Vsn1, [kernel, stdlib]),
  169. Suite1 = filename:join([AppDir1, "test", Name1 ++ "_SUITE.erl"]),
  170. ok = filelib:ensure_dir(Suite1),
  171. ok = file:write_file(Suite1, test_suite(Name1)),
  172. Name2 = rebar_test_utils:create_random_name(atom_to_list(dir_and_suites) ++ "_"),
  173. Vsn2 = rebar_test_utils:create_random_vsn(),
  174. AppDir2 = filename:join([AppDir, "apps", Name2]),
  175. rebar_test_utils:create_app(AppDir2, Name2, Vsn2, [kernel, stdlib]),
  176. Suite2 = filename:join([AppDir2, "test", Name2 ++ "_SUITE.erl"]),
  177. ok = filelib:ensure_dir(Suite2),
  178. ok = file:write_file(Suite2, test_suite(Name2)),
  179. Suite3 = filename:join([AppDir, "test", "extras_SUITE.erl"]),
  180. ok = filelib:ensure_dir(Suite3),
  181. ok = file:write_file(Suite3, test_suite("extras")),
  182. Suite4 = filename:join([AppDir, "root_SUITE.erl"]),
  183. ok = file:write_file(Suite4, test_suite("root")),
  184. ok = file:write_file(filename:join([AppDir, "root_SUITE.hrl"]), <<>>),
  185. ok = filelib:ensure_dir(filename:join([AppDir, "root_SUITE_data", "dummy.txt"])),
  186. ok = file:write_file(filename:join([AppDir, "root_SUITE_data", "some_data.txt"]), <<>>),
  187. Suite5 = filename:join([AppDir, "apps", Name2, "app_root_SUITE.erl"]),
  188. ok = file:write_file(Suite5, test_suite("app_root")),
  189. ok = file:write_file(filename:join([AppDir, "apps", Name2, "app_root_SUITE.hrl"]), <<>>),
  190. ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name2, "app_root_SUITE_data", "dummy.txt"])),
  191. ok = file:write_file(filename:join([AppDir, "apps", Name2, "app_root_SUITE_data", "some_data.txt"]), <<>>),
  192. {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
  193. [{s, State}, {appnames, [Name1, Name2]}|C];
  194. init_per_group(ct_opts, Config) ->
  195. C = rebar_test_utils:init_rebar_state(Config, "ct_opts"),
  196. AppDir = ?config(apps, C),
  197. Name = rebar_test_utils:create_random_name("ct_opts_"),
  198. Vsn = rebar_test_utils:create_random_vsn(),
  199. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  200. {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
  201. [{result, State}, {name, Name}|C];
  202. init_per_group(cover, Config) ->
  203. C = rebar_test_utils:init_rebar_state(Config, "ct_opts"),
  204. AppDir = ?config(apps, C),
  205. Name = rebar_test_utils:create_random_name("ct_opts_"),
  206. Vsn = rebar_test_utils:create_random_vsn(),
  207. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  208. {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
  209. [{result, State}, {name, Name}|C];
  210. init_per_group(_, Config) -> Config.
  211. end_per_group(_Group, _Config) -> ok.
  212. basic_app_default_dirs(Config) ->
  213. AppDir = ?config(apps, Config),
  214. [Name] = ?config(appnames, Config),
  215. Result = ?config(result, Config),
  216. Expect = filename:join([AppDir, "_build", "test", "lib", Name, "test"]),
  217. Dir = proplists:get_value(dir, Result),
  218. [Expect] = Dir.
  219. basic_app_default_beams(Config) ->
  220. AppDir = ?config(apps, Config),
  221. [Name] = ?config(appnames, Config),
  222. File = filename:join([AppDir,
  223. "_build",
  224. "test",
  225. "lib",
  226. Name,
  227. "test",
  228. Name ++ "_SUITE.beam"]),
  229. true = filelib:is_file(File).
  230. basic_app_ct_macro(Config) ->
  231. State = ?config(compile_state, Config),
  232. [App] = rebar_state:project_apps(State),
  233. Opts = rebar_app_info:opts(App),
  234. ErlOpts = dict:fetch(erl_opts, Opts),
  235. true = lists:member({d, 'COMMON_TEST'}, ErlOpts).
  236. multi_app_default_dirs(Config) ->
  237. AppDir = ?config(apps, Config),
  238. [Name1, Name2] = ?config(appnames, Config),
  239. Result = ?config(result, Config),
  240. Expect1 = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1, "test"])),
  241. Expect2 = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name2, "test"])),
  242. Expect3 = filename:absname(filename:join([AppDir, "_build", "test", "extras", "test"])),
  243. Dirs = proplists:get_value(dir, Result),
  244. true = (lists:sort([Expect1, Expect2, Expect3]) == lists:sort(Dirs)).
  245. multi_app_default_beams(Config) ->
  246. AppDir = ?config(apps, Config),
  247. [Name1, Name2] = ?config(appnames, Config),
  248. File1 = filename:join([AppDir,
  249. "_build",
  250. "test",
  251. "lib",
  252. Name1,
  253. "test",
  254. Name1 ++ "_SUITE.beam"]),
  255. File2 = filename:join([AppDir,
  256. "_build",
  257. "test",
  258. "lib",
  259. Name2,
  260. "test",
  261. Name2 ++ "_SUITE.beam"]),
  262. File3 = filename:join([AppDir,
  263. "_build",
  264. "test",
  265. "extras",
  266. "test",
  267. "extras_SUITE.beam"]),
  268. true = filelib:is_file(File1),
  269. true = filelib:is_file(File2),
  270. true = filelib:is_file(File3).
  271. multi_app_ct_macro(Config) ->
  272. State = ?config(compile_state, Config),
  273. Apps = rebar_state:project_apps(State),
  274. lists:foreach(fun(App) ->
  275. Opts = rebar_app_info:opts(App),
  276. ErlOpts = dict:fetch(erl_opts, Opts),
  277. true = lists:member({d, 'COMMON_TEST'}, ErlOpts)
  278. end, Apps).
  279. single_app_dir(Config) ->
  280. AppDir = ?config(apps, Config),
  281. [Name1, _Name2] = ?config(appnames, Config),
  282. State = ?config(s, Config),
  283. LibDirs = rebar_dir:lib_dirs(State),
  284. State1 = rebar_app_discover:do(State, LibDirs),
  285. Providers = rebar_state:providers(State1),
  286. Namespace = rebar_state:namespace(State1),
  287. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  288. GetOptSpec = providers:opts(CommandProvider),
  289. {ok, GetOptResult} = getopt:parse(GetOptSpec,
  290. ["--dir=" ++ filename:join([AppDir,
  291. "apps",
  292. Name1,
  293. "test"])]),
  294. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  295. Tests = rebar_prv_common_test:prepare_tests(State2),
  296. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  297. {ok, T} = Tests,
  298. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  299. Expect = filename:join([AppDir, "_build", "test", "lib", Name1, "test"]),
  300. Dir = proplists:get_value(dir, Opts),
  301. [Expect] = Dir.
  302. single_extra_dir(Config) ->
  303. AppDir = ?config(apps, Config),
  304. State = ?config(s, Config),
  305. LibDirs = rebar_dir:lib_dirs(State),
  306. State1 = rebar_app_discover:do(State, LibDirs),
  307. Providers = rebar_state:providers(State1),
  308. Namespace = rebar_state:namespace(State1),
  309. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  310. GetOptSpec = providers:opts(CommandProvider),
  311. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--dir=" ++ filename:join([AppDir,
  312. "test"])]),
  313. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  314. Tests = rebar_prv_common_test:prepare_tests(State2),
  315. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  316. {ok, T} = Tests,
  317. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  318. Expect = filename:join([AppDir, "_build", "test", "extras", "test"]),
  319. Dir = proplists:get_value(dir, Opts),
  320. [Expect] = Dir.
  321. single_unmanaged_dir(Config) ->
  322. PrivDir = ?config(priv_dir, Config),
  323. State = ?config(s, Config),
  324. Suite = filename:join([PrivDir, "unmanaged_dir", "unmanaged_dir_SUITE.erl"]),
  325. ok = filelib:ensure_dir(Suite),
  326. ok = file:write_file(Suite, test_suite("unmanaged_dir")),
  327. LibDirs = rebar_dir:lib_dirs(State),
  328. State1 = rebar_app_discover:do(State, LibDirs),
  329. Providers = rebar_state:providers(State1),
  330. Namespace = rebar_state:namespace(State1),
  331. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  332. GetOptSpec = providers:opts(CommandProvider),
  333. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--dir=" ++ filename:absname(filename:join([PrivDir,
  334. "unmanaged_dir"]))]),
  335. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  336. Tests = rebar_prv_common_test:prepare_tests(State2),
  337. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  338. {ok, T} = Tests,
  339. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  340. Expect = filename:join([PrivDir, "unmanaged_dir"]),
  341. Dir = proplists:get_value(dir, Opts),
  342. [Expect] = Dir.
  343. single_suite(Config) ->
  344. AppDir = ?config(apps, Config),
  345. [Name1, _Name2] = ?config(appnames, Config),
  346. State = ?config(s, Config),
  347. LibDirs = rebar_dir:lib_dirs(State),
  348. State1 = rebar_app_discover:do(State, LibDirs),
  349. Providers = rebar_state:providers(State1),
  350. Namespace = rebar_state:namespace(State1),
  351. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  352. GetOptSpec = providers:opts(CommandProvider),
  353. {ok, GetOptResult} = getopt:parse(GetOptSpec,
  354. ["--suite=" ++ filename:join([AppDir,
  355. "apps",
  356. Name1,
  357. "test",
  358. Name1 ++ "_SUITE"])]),
  359. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  360. Tests = rebar_prv_common_test:prepare_tests(State2),
  361. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  362. {ok, T} = Tests,
  363. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  364. Expect = filename:join([AppDir,
  365. "_build",
  366. "test",
  367. "lib",
  368. Name1,
  369. "test",
  370. Name1 ++ "_SUITE"]),
  371. Suite = proplists:get_value(suite, Opts),
  372. [Expect] = Suite.
  373. single_extra_suite(Config) ->
  374. AppDir = ?config(apps, Config),
  375. [_Name1, _Name2] = ?config(appnames, Config),
  376. State = ?config(s, Config),
  377. LibDirs = rebar_dir:lib_dirs(State),
  378. State1 = rebar_app_discover:do(State, LibDirs),
  379. Providers = rebar_state:providers(State1),
  380. Namespace = rebar_state:namespace(State1),
  381. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  382. GetOptSpec = providers:opts(CommandProvider),
  383. {ok, GetOptResult} = getopt:parse(GetOptSpec,
  384. ["--suite=" ++ filename:join([AppDir,
  385. "test",
  386. "extra_SUITE"])]),
  387. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  388. Tests = rebar_prv_common_test:prepare_tests(State2),
  389. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  390. {ok, T} = Tests,
  391. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  392. Expect = filename:join([AppDir,
  393. "_build",
  394. "test",
  395. "extras",
  396. "test",
  397. "extra_SUITE"]),
  398. Suite = proplists:get_value(suite, Opts),
  399. [Expect] = Suite.
  400. single_unmanaged_suite(Config) ->
  401. PrivDir = ?config(priv_dir, Config),
  402. [_Name1, _Name2] = ?config(appnames, Config),
  403. State = ?config(s, Config),
  404. Suite = filename:join([PrivDir, "unmanaged", "unmanaged_SUITE.erl"]),
  405. ok = filelib:ensure_dir(Suite),
  406. ok = file:write_file(Suite, test_suite("unmanaged")),
  407. LibDirs = rebar_dir:lib_dirs(State),
  408. State1 = rebar_app_discover:do(State, LibDirs),
  409. Providers = rebar_state:providers(State1),
  410. Namespace = rebar_state:namespace(State1),
  411. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  412. GetOptSpec = providers:opts(CommandProvider),
  413. {ok, GetOptResult} = getopt:parse(GetOptSpec,
  414. ["--suite=" ++ filename:absname(filename:join([PrivDir,
  415. "unmanaged",
  416. "unmanaged_SUITE"]))]),
  417. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  418. Tests = rebar_prv_common_test:prepare_tests(State2),
  419. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  420. {ok, T} = Tests,
  421. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  422. Expect = filename:join([PrivDir,
  423. "unmanaged",
  424. "unmanaged_SUITE"]),
  425. SuitePath = proplists:get_value(suite, Opts),
  426. [Expect] = SuitePath.
  427. multi_suite(Config) ->
  428. AppDir = ?config(apps, Config),
  429. [Name1, Name2] = ?config(appnames, Config),
  430. State = ?config(s, Config),
  431. LibDirs = rebar_dir:lib_dirs(State),
  432. State1 = rebar_app_discover:do(State, LibDirs),
  433. Providers = rebar_state:providers(State1),
  434. Namespace = rebar_state:namespace(State1),
  435. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  436. GetOptSpec = providers:opts(CommandProvider),
  437. {ok, GetOptResult} = getopt:parse(GetOptSpec,
  438. ["--suite=" ++ filename:join([AppDir,
  439. "apps",
  440. Name1,
  441. "test",
  442. Name1 ++ "_SUITE," ++ AppDir,
  443. "apps",
  444. Name2,
  445. "test",
  446. Name2 ++ "_SUITE"])]),
  447. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  448. Tests = rebar_prv_common_test:prepare_tests(State2),
  449. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  450. {ok, T} = Tests,
  451. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  452. Expect1 = filename:join([AppDir,
  453. "_build",
  454. "test",
  455. "lib",
  456. Name1,
  457. "test",
  458. Name1 ++ "_SUITE"]),
  459. Expect2 = filename:join([AppDir,
  460. "_build",
  461. "test",
  462. "lib",
  463. Name2,
  464. "test",
  465. Name2 ++ "_SUITE"]),
  466. Suites = proplists:get_value(suite, Opts),
  467. true = (lists:sort([Expect1, Expect2]) == lists:sort(Suites)).
  468. all_suite(Config) ->
  469. AppDir = ?config(apps, Config),
  470. [Name1, Name2] = ?config(appnames, Config),
  471. State = ?config(s, Config),
  472. LibDirs = rebar_dir:lib_dirs(State),
  473. State1 = rebar_app_discover:do(State, LibDirs),
  474. Providers = rebar_state:providers(State1),
  475. Namespace = rebar_state:namespace(State1),
  476. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  477. GetOptSpec = providers:opts(CommandProvider),
  478. {ok, GetOptResult} = getopt:parse(GetOptSpec,
  479. ["--suite=" ++ filename:join([AppDir,
  480. "apps",
  481. Name1,
  482. "test",
  483. Name1 ++ "_SUITE," ++ AppDir,
  484. "apps",
  485. Name2,
  486. "test",
  487. Name2 ++ "_SUITE," ++ AppDir,
  488. "test",
  489. "extra_SUITE"])]),
  490. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  491. Tests = rebar_prv_common_test:prepare_tests(State2),
  492. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  493. {ok, T} = Tests,
  494. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  495. Expect1 = filename:join([AppDir,
  496. "_build",
  497. "test",
  498. "lib",
  499. Name1,
  500. "test",
  501. Name1 ++ "_SUITE"]),
  502. Expect2 = filename:join([AppDir,
  503. "_build",
  504. "test",
  505. "lib",
  506. Name2,
  507. "test",
  508. Name2 ++ "_SUITE"]),
  509. Expect3 = filename:join([AppDir,
  510. "_build",
  511. "test",
  512. "extras",
  513. "test",
  514. "extra_SUITE"]),
  515. Suites = proplists:get_value(suite, Opts),
  516. true = (lists:sort([Expect1, Expect2, Expect3]) == lists:sort(Suites)).
  517. single_dir_and_single_suite(Config) ->
  518. AppDir = ?config(apps, Config),
  519. [_Name1, _Name2] = ?config(appnames, Config),
  520. State = ?config(s, Config),
  521. LibDirs = rebar_dir:lib_dirs(State),
  522. State1 = rebar_app_discover:do(State, LibDirs),
  523. Providers = rebar_state:providers(State1),
  524. Namespace = rebar_state:namespace(State1),
  525. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  526. GetOptSpec = providers:opts(CommandProvider),
  527. {ok, GetOptResult} = getopt:parse(GetOptSpec,
  528. ["--dir=" ++ filename:join([AppDir, "test"]),
  529. "--suite=extra_SUITE"]),
  530. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  531. Tests = rebar_prv_common_test:prepare_tests(State2),
  532. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  533. {ok, T} = Tests,
  534. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  535. Expect = filename:join([AppDir,
  536. "_build",
  537. "test",
  538. "extras",
  539. "test"]),
  540. Dir = proplists:get_value(dir, Opts),
  541. [Expect] = Dir,
  542. Suite = proplists:get_value(suite, Opts),
  543. ["extra_SUITE"] = Suite.
  544. suite_at_root(Config) ->
  545. AppDir = ?config(apps, Config),
  546. State = ?config(s, Config),
  547. LibDirs = rebar_dir:lib_dirs(State),
  548. State1 = rebar_app_discover:do(State, LibDirs),
  549. Providers = rebar_state:providers(State1),
  550. Namespace = rebar_state:namespace(State1),
  551. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  552. GetOptSpec = providers:opts(CommandProvider),
  553. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--suite=" ++ filename:join([AppDir, "root_SUITE"])]),
  554. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  555. Tests = rebar_prv_common_test:prepare_tests(State2),
  556. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  557. {ok, T} = Tests,
  558. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  559. Suite = proplists:get_value(suite, Opts),
  560. Expected = filename:join([AppDir, "_build", "test", "extras", "root_SUITE"]),
  561. [Expected] = Suite,
  562. TestHrl = filename:join([AppDir, "_build", "test", "extras", "root_SUITE.hrl"]),
  563. true = filelib:is_file(TestHrl),
  564. TestBeam = filename:join([AppDir, "_build", "test", "extras", "root_SUITE.beam"]),
  565. true = filelib:is_file(TestBeam),
  566. DataDir = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data"]),
  567. true = filelib:is_dir(DataDir),
  568. DataFile = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data", "some_data.txt"]),
  569. true = filelib:is_file(DataFile),
  570. %% Same test again, but using relative path to the suite from the
  571. %% project root
  572. {ok,Cwd} = file:get_cwd(),
  573. ok = file:set_cwd(AppDir),
  574. rebar_file_utils:rm_rf("_build"),
  575. {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--suite=" ++ "root_SUITE"]),
  576. State3 = rebar_state:command_parsed_args(State1, GetOptResult2),
  577. Tests2 = rebar_prv_common_test:prepare_tests(State3),
  578. {ok, NewState2} = rebar_prv_common_test:compile(State3, Tests2),
  579. {ok, T2} = Tests2,
  580. Opts2 = rebar_prv_common_test:translate_paths(NewState2, T2),
  581. ok = file:set_cwd(Cwd),
  582. Suite2 = proplists:get_value(suite, Opts2),
  583. [Expected] = Suite2,
  584. true = filelib:is_file(TestHrl),
  585. true = filelib:is_file(TestBeam),
  586. true = filelib:is_dir(DataDir),
  587. true = filelib:is_file(DataFile),
  588. ok.
  589. suite_at_app_root(Config) ->
  590. AppDir = ?config(apps, Config),
  591. [_Name1, Name2] = ?config(appnames, Config),
  592. State = ?config(s, Config),
  593. LibDirs = rebar_dir:lib_dirs(State),
  594. State1 = rebar_app_discover:do(State, LibDirs),
  595. Providers = rebar_state:providers(State1),
  596. Namespace = rebar_state:namespace(State1),
  597. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  598. GetOptSpec = providers:opts(CommandProvider),
  599. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--suite=" ++ filename:join([AppDir, "apps", Name2, "app_root_SUITE"])]),
  600. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  601. Tests = rebar_prv_common_test:prepare_tests(State2),
  602. {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
  603. {ok, T} = Tests,
  604. Opts = rebar_prv_common_test:translate_paths(NewState, T),
  605. Suite = proplists:get_value(suite, Opts),
  606. Expected = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE"]),
  607. [Expected] = Suite,
  608. TestHrl = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE.hrl"]),
  609. true = filelib:is_file(TestHrl),
  610. TestBeam = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE.beam"]),
  611. true = filelib:is_file(TestBeam),
  612. DataDir = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE_data"]),
  613. true = filelib:is_dir(DataDir),
  614. DataFile = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE_data", "some_data.txt"]),
  615. true = filelib:is_file(DataFile),
  616. %% Same test again using relative path to the suite from the project root
  617. {ok,Cwd} = file:get_cwd(),
  618. ok = file:set_cwd(AppDir),
  619. rebar_file_utils:rm_rf("_build"),
  620. {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--suite=" ++ filename:join(["apps", Name2, "app_root_SUITE"])]),
  621. State3 = rebar_state:command_parsed_args(State1, GetOptResult2),
  622. Tests2 = rebar_prv_common_test:prepare_tests(State3),
  623. {ok, NewState2} = rebar_prv_common_test:compile(State3, Tests2),
  624. {ok, T2} = Tests2,
  625. Opts2 = rebar_prv_common_test:translate_paths(NewState2, T2),
  626. ok = file:set_cwd(Cwd),
  627. Suite2 = proplists:get_value(suite, Opts2),
  628. [Expected] = Suite2,
  629. true = filelib:is_file(TestHrl),
  630. true = filelib:is_file(TestBeam),
  631. true = filelib:is_dir(DataDir),
  632. true = filelib:is_file(DataFile),
  633. ok.
  634. %% this test probably only fails when this suite is run via rebar3 with the --cover flag
  635. data_dir_correct(Config) ->
  636. DataDir = ?config(data_dir, Config),
  637. Parts = filename:split(DataDir),
  638. ["rebar_ct_SUITE_data","test","rebar","lib",_,"_build"|_] = lists:reverse(Parts).
  639. cmd_label(Config) ->
  640. State = ?config(result, Config),
  641. Providers = rebar_state:providers(State),
  642. Namespace = rebar_state:namespace(State),
  643. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  644. GetOptSpec = providers:opts(CommandProvider),
  645. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--label=this_is_a_label"]),
  646. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  647. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  648. true = lists:member({label, "this_is_a_label"}, TestOpts).
  649. cmd_config(Config) ->
  650. State = ?config(result, Config),
  651. Providers = rebar_state:providers(State),
  652. Namespace = rebar_state:namespace(State),
  653. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  654. GetOptSpec = providers:opts(CommandProvider),
  655. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--config=config/foo,config/bar,config/baz"]),
  656. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  657. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  658. true = lists:member({config, ["config/foo", "config/bar", "config/baz"]}, TestOpts).
  659. cmd_spec(Config) ->
  660. State = ?config(result, Config),
  661. Providers = rebar_state:providers(State),
  662. Namespace = rebar_state:namespace(State),
  663. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  664. GetOptSpec = providers:opts(CommandProvider),
  665. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--spec=foo.spec,bar.spec,baz.spec"]),
  666. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  667. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  668. true = lists:member({spec, ["foo.spec", "bar.spec", "baz.spec"]}, TestOpts).
  669. cmd_join_specs(Config) ->
  670. State = ?config(result, Config),
  671. Providers = rebar_state:providers(State),
  672. Namespace = rebar_state:namespace(State),
  673. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  674. GetOptSpec = providers:opts(CommandProvider),
  675. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--join_specs=true"]),
  676. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  677. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  678. true = lists:member({join_specs, true}, TestOpts).
  679. cmd_allow_user_terms(Config) ->
  680. State = ?config(result, Config),
  681. Providers = rebar_state:providers(State),
  682. Namespace = rebar_state:namespace(State),
  683. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  684. GetOptSpec = providers:opts(CommandProvider),
  685. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--allow_user_terms=true"]),
  686. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  687. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  688. true = lists:member({allow_user_terms, true}, TestOpts).
  689. cmd_logdir(Config) ->
  690. State = ?config(result, Config),
  691. Providers = rebar_state:providers(State),
  692. Namespace = rebar_state:namespace(State),
  693. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  694. GetOptSpec = providers:opts(CommandProvider),
  695. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--logdir=/tmp/ct_logs"]),
  696. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  697. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  698. true = lists:member({logdir, "/tmp/ct_logs"}, TestOpts).
  699. cmd_logopts(Config) ->
  700. State = ?config(result, Config),
  701. Providers = rebar_state:providers(State),
  702. Namespace = rebar_state:namespace(State),
  703. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  704. GetOptSpec = providers:opts(CommandProvider),
  705. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--logopts=no_src,no_nl"]),
  706. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  707. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  708. true = lists:member({logopts, [no_src, no_nl]}, TestOpts).
  709. cmd_verbosity(Config) ->
  710. State = ?config(result, Config),
  711. Providers = rebar_state:providers(State),
  712. Namespace = rebar_state:namespace(State),
  713. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  714. GetOptSpec = providers:opts(CommandProvider),
  715. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--verbosity=43"]),
  716. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  717. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  718. true = lists:member({verbosity, 43}, TestOpts).
  719. cmd_repeat(Config) ->
  720. State = ?config(result, Config),
  721. Providers = rebar_state:providers(State),
  722. Namespace = rebar_state:namespace(State),
  723. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  724. GetOptSpec = providers:opts(CommandProvider),
  725. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--repeat=3"]),
  726. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  727. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  728. true = lists:member({repeat, 3}, TestOpts).
  729. cmd_duration(Config) ->
  730. State = ?config(result, Config),
  731. Providers = rebar_state:providers(State),
  732. Namespace = rebar_state:namespace(State),
  733. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  734. GetOptSpec = providers:opts(CommandProvider),
  735. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--duration=001500"]),
  736. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  737. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  738. true = lists:member({duration, "001500"}, TestOpts).
  739. cmd_until(Config) ->
  740. State = ?config(result, Config),
  741. Providers = rebar_state:providers(State),
  742. Namespace = rebar_state:namespace(State),
  743. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  744. GetOptSpec = providers:opts(CommandProvider),
  745. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--until=001500"]),
  746. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  747. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  748. true = lists:member({until, "001500"}, TestOpts).
  749. cmd_force_stop(Config) ->
  750. State = ?config(result, Config),
  751. Providers = rebar_state:providers(State),
  752. Namespace = rebar_state:namespace(State),
  753. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  754. GetOptSpec = providers:opts(CommandProvider),
  755. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--force_stop=skip_rest"]),
  756. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  757. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  758. true = lists:member({force_stop, skip_rest}, TestOpts).
  759. cmd_basic_html(Config) ->
  760. State = ?config(result, Config),
  761. Providers = rebar_state:providers(State),
  762. Namespace = rebar_state:namespace(State),
  763. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  764. GetOptSpec = providers:opts(CommandProvider),
  765. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--basic_html"]),
  766. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  767. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  768. true = lists:member({basic_html, true}, TestOpts).
  769. cmd_stylesheet(Config) ->
  770. State = ?config(result, Config),
  771. Providers = rebar_state:providers(State),
  772. Namespace = rebar_state:namespace(State),
  773. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  774. GetOptSpec = providers:opts(CommandProvider),
  775. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--stylesheet=resources/tests.css"]),
  776. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  777. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  778. true = lists:member({stylesheet, "resources/tests.css"}, TestOpts).
  779. cmd_decrypt_key(Config) ->
  780. State = ?config(result, Config),
  781. Providers = rebar_state:providers(State),
  782. Namespace = rebar_state:namespace(State),
  783. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  784. GetOptSpec = providers:opts(CommandProvider),
  785. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--decrypt_key==ac467e30"]),
  786. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  787. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  788. true = lists:member({decrypt_key, "=ac467e30"}, TestOpts).
  789. cmd_decrypt_file(Config) ->
  790. State = ?config(result, Config),
  791. Providers = rebar_state:providers(State),
  792. Namespace = rebar_state:namespace(State),
  793. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  794. GetOptSpec = providers:opts(CommandProvider),
  795. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--decrypt_file=../keyfile.pem"]),
  796. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  797. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  798. true = lists:member({decrypt_file, "../keyfile.pem"}, TestOpts).
  799. cmd_abort_if_missing_suites(Config) ->
  800. State = ?config(result, Config),
  801. Providers = rebar_state:providers(State),
  802. Namespace = rebar_state:namespace(State),
  803. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  804. GetOptSpec = providers:opts(CommandProvider),
  805. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--abort_if_missing_suites"]),
  806. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  807. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  808. true = lists:member({abort_if_missing_suites, true}, TestOpts).
  809. cmd_multiply_timetraps(Config) ->
  810. State = ?config(result, Config),
  811. Providers = rebar_state:providers(State),
  812. Namespace = rebar_state:namespace(State),
  813. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  814. GetOptSpec = providers:opts(CommandProvider),
  815. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--multiply_timetraps=3"]),
  816. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  817. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  818. true = lists:member({multiply_timetraps, 3}, TestOpts).
  819. cmd_scale_timetraps(Config) ->
  820. State = ?config(result, Config),
  821. Providers = rebar_state:providers(State),
  822. Namespace = rebar_state:namespace(State),
  823. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  824. GetOptSpec = providers:opts(CommandProvider),
  825. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--scale_timetraps"]),
  826. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  827. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  828. true = lists:member({scale_timetraps, true}, TestOpts).
  829. cmd_create_priv_dir(Config) ->
  830. State = ?config(result, Config),
  831. Providers = rebar_state:providers(State),
  832. Namespace = rebar_state:namespace(State),
  833. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  834. GetOptSpec = providers:opts(CommandProvider),
  835. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--create_priv_dir=manual_per_tc"]),
  836. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  837. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
  838. true = lists:member({create_priv_dir, manual_per_tc}, TestOpts).
  839. cmd_include_dir(Config) ->
  840. State = ?config(result, Config),
  841. AppDir = ?config(apps, Config),
  842. Providers = rebar_state:providers(State),
  843. Namespace = rebar_state:namespace(State),
  844. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  845. GetOptSpec = providers:opts(CommandProvider),
  846. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--include=foo/bar/baz,qux"]),
  847. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  848. Tests = rebar_prv_common_test:prepare_tests(NewState),
  849. {ok, _} = rebar_prv_common_test:compile(NewState, Tests),
  850. Name = ?config(name, Config),
  851. Beam = filename:join([AppDir, "_build", "test", "lib", Name, "ebin", Name ++ ".beam"]),
  852. {ok, {_, [{compile_info, Info}]}} = beam_lib:chunks(Beam, [compile_info]),
  853. CompileOpts = proplists:get_value(options, Info),
  854. true = lists:member({i, "foo/bar/baz"}, CompileOpts),
  855. true = lists:member({i, "qux"}, CompileOpts).
  856. cmd_sys_config(Config) ->
  857. State = ?config(result, Config),
  858. AppDir = ?config(apps, Config),
  859. Name = ?config(name, Config),
  860. AppName = list_to_atom(Name),
  861. {ok, _} = rebar_prv_common_test:prepare_tests(State),
  862. ?assertEqual(undefined, application:get_env(AppName, key)),
  863. CfgFile = filename:join([AppDir, "config", "cfg_sys.config"]),
  864. ok = filelib:ensure_dir(CfgFile),
  865. ok = file:write_file(CfgFile, cfg_sys_config_file(AppName)),
  866. OtherCfgFile = filename:join([AppDir, "config", "other.config"]),
  867. ok = filelib:ensure_dir(OtherCfgFile),
  868. ok = file:write_file(OtherCfgFile, other_sys_config_file(AppName)),
  869. RebarConfig = [{ct_opts, [{sys_config, CfgFile}]}],
  870. {ok, State1} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "test", "lock"], return),
  871. {ok, _} = rebar_prv_common_test:prepare_tests(State1),
  872. ?assertEqual({ok, cfg_value}, application:get_env(AppName, key)),
  873. ?assertEqual({ok, other_cfg_value}, application:get_env(AppName, other_key)),
  874. Providers = rebar_state:providers(State1),
  875. Namespace = rebar_state:namespace(State1),
  876. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  877. GetOptSpec = providers:opts(CommandProvider),
  878. CmdFile = filename:join([AppDir, "config", "cmd_sys.config"]),
  879. ok = filelib:ensure_dir(CmdFile),
  880. ok = file:write_file(CmdFile, cmd_sys_config_file(AppName)),
  881. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--sys_config="++CmdFile]),
  882. State2 = rebar_state:command_parsed_args(State1, GetOptResult),
  883. {ok, _} = rebar_prv_common_test:prepare_tests(State2),
  884. ?assertEqual({ok ,cmd_value}, application:get_env(AppName, key)).
  885. cfg_opts(Config) ->
  886. C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_opts_"),
  887. AppDir = ?config(apps, C),
  888. Name = rebar_test_utils:create_random_name("ct_cfg_opts_"),
  889. Vsn = rebar_test_utils:create_random_vsn(),
  890. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  891. RebarConfig = [{ct_opts, [{label, "this_is_a_label"}, {decrypt_file, "../keyfile.pem"}]}],
  892. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  893. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
  894. true = lists:member({label, "this_is_a_label"}, TestOpts),
  895. true = lists:member({decrypt_file, "../keyfile.pem"}, TestOpts).
  896. %% allow even nonsensical opts to be passed to ct_run for futureproofing
  897. cfg_arbitrary_opts(Config) ->
  898. C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_arbitrary_opts_"),
  899. AppDir = ?config(apps, C),
  900. Name = rebar_test_utils:create_random_name("ct_cfg_arbitrary_opts_"),
  901. Vsn = rebar_test_utils:create_random_vsn(),
  902. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  903. RebarConfig = [{ct_opts, [{foo, 1}, {bar, 2}, {baz, 3}]}],
  904. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  905. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
  906. true = lists:member({foo, 1}, TestOpts),
  907. true = lists:member({bar, 2}, TestOpts),
  908. true = lists:member({baz, 3}, TestOpts).
  909. cfg_cover_spec(Config) ->
  910. C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_cover_spec_opts_"),
  911. AppDir = ?config(apps, C),
  912. Name = rebar_test_utils:create_random_name("ct_cfg_cover_spec_opts_"),
  913. Vsn = rebar_test_utils:create_random_vsn(),
  914. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  915. RebarConfig = [{ct_opts, [Opt = {cover, "spec/foo.spec"}]}],
  916. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  917. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
  918. false = lists:member(Opt, TestOpts).
  919. cfg_atom_suites(Config) ->
  920. C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
  921. AppDir = ?config(apps, C),
  922. Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"),
  923. Vsn = rebar_test_utils:create_random_vsn(),
  924. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  925. RebarConfig = [{ct_opts, [{suite, [foo, bar, baz]}]}],
  926. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  927. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
  928. true = lists:member({suite, ["foo", "bar", "baz"]}, TestOpts).
  929. cover_compiled(Config) ->
  930. State = ?config(result, Config),
  931. Providers = rebar_state:providers(State),
  932. Namespace = rebar_state:namespace(State),
  933. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  934. GetOptSpec = providers:opts(CommandProvider),
  935. {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--cover"]),
  936. NewState = rebar_state:command_parsed_args(State, GetOptResult),
  937. Tests = rebar_prv_common_test:prepare_tests(NewState),
  938. {ok, _} = rebar_prv_common_test:compile(NewState, Tests),
  939. Name = ?config(name, Config),
  940. Mod = list_to_atom(Name),
  941. {file, _} = cover:is_compiled(Mod).
  942. misspecified_ct_opts(Config) ->
  943. C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
  944. AppDir = ?config(apps, C),
  945. Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"),
  946. Vsn = rebar_test_utils:create_random_vsn(),
  947. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  948. RebarConfig = [{ct_opts, {basic_html, false}}],
  949. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  950. {error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:prepare_tests(State),
  951. {badconfig, {"Value `~p' of option `~p' must be a list", {{basic_html, false}, ct_opts}}} = Error.
  952. misspecified_ct_compile_opts(Config) ->
  953. C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
  954. AppDir = ?config(apps, C),
  955. Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"),
  956. Vsn = rebar_test_utils:create_random_vsn(),
  957. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  958. RebarConfig = [{ct_compile_opts, {d, whatever}}],
  959. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  960. Tests = rebar_prv_common_test:prepare_tests(State),
  961. {error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:compile(State, Tests),
  962. {badconfig, {"Value `~p' of option `~p' must be a list", {{d, whatever}, ct_compile_opts}}} = Error.
  963. misspecified_ct_first_files(Config) ->
  964. C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
  965. AppDir = ?config(apps, C),
  966. Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"),
  967. Vsn = rebar_test_utils:create_random_vsn(),
  968. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  969. RebarConfig = [{ct_first_files, some_file}],
  970. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  971. Tests = rebar_prv_common_test:prepare_tests(State),
  972. {error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:compile(State, Tests),
  973. {badconfig, {"Value `~p' of option `~p' must be a list", {some_file, ct_first_files}}} = Error.
  974. testspec(Config) ->
  975. C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_"),
  976. AppDir = ?config(apps, C),
  977. Name = rebar_test_utils:create_random_name("ct_testspec_"),
  978. Vsn = rebar_test_utils:create_random_vsn(),
  979. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  980. Spec1 = filename:join([AppDir, "test", "some.spec"]),
  981. ok = filelib:ensure_dir(Spec1),
  982. ok = file:write_file(Spec1, "{suites,\".\",all}.\n"),
  983. Spec2 = filename:join([AppDir, "specs", "another.spec"]),
  984. ok = filelib:ensure_dir(Spec2),
  985. Suites2 = filename:join([AppDir,"suites","*"]),
  986. ok = filelib:ensure_dir(Suites2),
  987. ok = file:write_file(Spec2, "{suites,\"../suites/\",all}.\n"),
  988. {ok,Wd} = file:get_cwd(),
  989. ok = file:set_cwd(AppDir),
  990. {ok, State} = rebar_test_utils:run_and_check(C,
  991. [],
  992. ["as", "test", "lock"],
  993. return),
  994. Providers = rebar_state:providers(State),
  995. Namespace = rebar_state:namespace(State),
  996. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  997. GetOptSpec = providers:opts(CommandProvider),
  998. %% Testspec in "test" directory
  999. {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec","test/some.spec"]),
  1000. State1 = rebar_state:command_parsed_args(State, GetOptResult1),
  1001. Tests1 = rebar_prv_common_test:prepare_tests(State1),
  1002. {ok, NewState1} = rebar_prv_common_test:compile(State1, Tests1),
  1003. {ok, T1} = Tests1,
  1004. Opts1= rebar_prv_common_test:translate_paths(NewState1, T1),
  1005. %% check that extra src dir is added
  1006. [App1] = rebar_state:project_apps(NewState1),
  1007. ["test"] = rebar_dir:extra_src_dirs(rebar_app_info:opts(App1)),
  1008. %% check that path is translated
  1009. ExpectedSpec1 = filename:join([AppDir, "_build", "test", "lib", Name,
  1010. "test", "some.spec"]),
  1011. [ExpectedSpec1] = proplists:get_value(spec, Opts1),
  1012. %% Testspec in directory other than "test"
  1013. {ok, GetOptResult2} = getopt:parse(GetOptSpec,
  1014. ["--spec","specs/another.spec"]),
  1015. State2 = rebar_state:command_parsed_args(State, GetOptResult2),
  1016. Tests2 = {ok, T2} =rebar_prv_common_test:prepare_tests(State2),
  1017. {ok, NewState2} = rebar_prv_common_test:compile(State2, Tests2),
  1018. Opts2= rebar_prv_common_test:translate_paths(NewState2, T2),
  1019. %% check that extra src dirs are added
  1020. [App2] = rebar_state:project_apps(NewState2),
  1021. ["specs","suites","test"] =
  1022. lists:sort(rebar_dir:extra_src_dirs(rebar_app_info:opts(App2))),
  1023. %% check that paths are translated
  1024. ExpectedSpec2 = filename:join([AppDir, "_build", "test", "lib", Name,
  1025. "specs", "another.spec"]),
  1026. [ExpectedSpec2] = proplists:get_value(spec, Opts2),
  1027. ok = file:set_cwd(Wd),
  1028. ok.
  1029. testspec_at_root(Config) ->
  1030. C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_at_root_"),
  1031. AppDir = ?config(apps, C),
  1032. Name = rebar_test_utils:create_random_name("ct_testspec_at_root_"),
  1033. Vsn = rebar_test_utils:create_random_vsn(),
  1034. AppDir1 = filename:join([AppDir, "apps", Name]),
  1035. rebar_test_utils:create_app(AppDir1, Name, Vsn, [kernel, stdlib]),
  1036. Spec1 = filename:join([AppDir, "root.spec"]),
  1037. ok = filelib:ensure_dir(Spec1),
  1038. ok = file:write_file(Spec1, "{suites,\"test\",all}."),
  1039. Spec2 = filename:join([AppDir, "root1.spec"]),
  1040. ok = file:write_file(Spec2, "{suites,\".\",all}."),
  1041. Spec3 = filename:join([AppDir, "root2.spec"]),
  1042. ok = file:write_file(Spec3, "{suites,\"suites\",all}."),
  1043. Suite1 = filename:join(AppDir,"root_SUITE.erl"),
  1044. ok = file:write_file(Suite1, test_suite("root")),
  1045. Suite2 = filename:join([AppDir,"suites","test_SUITE.erl"]),
  1046. ok = filelib:ensure_dir(Suite2),
  1047. ok = file:write_file(Suite2, test_suite("test")),
  1048. {ok, State} = rebar_test_utils:run_and_check(C,
  1049. [],
  1050. ["as", "test", "lock"],
  1051. return),
  1052. Providers = rebar_state:providers(State),
  1053. Namespace = rebar_state:namespace(State),
  1054. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  1055. GetOptSpec = providers:opts(CommandProvider),
  1056. SpecArg1 = string:join([Spec1,Spec2,Spec3],","),
  1057. {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec",SpecArg1]),
  1058. State1 = rebar_state:command_parsed_args(State, GetOptResult1),
  1059. Tests1 = rebar_prv_common_test:prepare_tests(State1),
  1060. {ok, NewState1} = rebar_prv_common_test:compile(State1, Tests1),
  1061. {ok, T1} = Tests1,
  1062. Opts1= rebar_prv_common_test:translate_paths(NewState1, T1),
  1063. %% check that extra src dir is added
  1064. ExtraDir = filename:join([AppDir, "_build", "test", "extras"]),
  1065. [ExtraDir,"suites","test"] =
  1066. rebar_dir:extra_src_dirs(rebar_state:opts(NewState1)),
  1067. %% check that path is translated
  1068. ExpectedSpec1 = filename:join([AppDir, "_build", "test",
  1069. "extras", "root.spec"]),
  1070. ExpectedSpec2 = filename:join([AppDir, "_build", "test",
  1071. "extras", "root1.spec"]),
  1072. ExpectedSpec3 = filename:join([AppDir, "_build", "test",
  1073. "extras", "root2.spec"]),
  1074. [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] =
  1075. lists:sort(proplists:get_value(spec, Opts1)),
  1076. %% check that test specs are copied
  1077. [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] =
  1078. lists:sort(filelib:wildcard(filename:join([AppDir, "_build", "test",
  1079. "extras", "*.spec"]))),
  1080. %% Same test again, using relative path
  1081. {ok,Cwd} = file:get_cwd(),
  1082. ok = file:set_cwd(AppDir),
  1083. ok = rebar_file_utils:rm_rf("_build"),
  1084. SpecArg2 = "root.spec,root1.spec,root2.spec",
  1085. {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--spec",SpecArg2]),
  1086. State2 = rebar_state:command_parsed_args(State, GetOptResult2),
  1087. Tests2 = rebar_prv_common_test:prepare_tests(State2),
  1088. {ok, NewState2} = rebar_prv_common_test:compile(State2, Tests2),
  1089. {ok, T2} = Tests2,
  1090. Opts2= rebar_prv_common_test:translate_paths(NewState2, T2),
  1091. %% check that extra src dir is added
  1092. [ExtraDir,"suites","test"] =
  1093. rebar_dir:extra_src_dirs(rebar_state:opts(NewState2)),
  1094. %% check that path is translated
  1095. [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] =
  1096. lists:sort(proplists:get_value(spec, Opts2)),
  1097. %% check that test specs are copied
  1098. [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] =
  1099. lists:sort(filelib:wildcard(filename:join([AppDir, "_build", "test",
  1100. "extras", "root*.spec"]))),
  1101. ok = file:set_cwd(Cwd),
  1102. ok.
  1103. testspec_parse_error(Config) ->
  1104. C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_error"),
  1105. AppDir = ?config(apps, C),
  1106. Name = rebar_test_utils:create_random_name("ct_testspec_error"),
  1107. Vsn = rebar_test_utils:create_random_vsn(),
  1108. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1109. Spec1 = filename:join([AppDir, "test", "nonexisting.spec"]),
  1110. Spec2 = filename:join([AppDir, "test", "some.spec"]),
  1111. ok = filelib:ensure_dir(Spec2),
  1112. ok = file:write_file(Spec2, ".\n"),
  1113. {ok, State} = rebar_test_utils:run_and_check(C,
  1114. [],
  1115. ["as", "test", "lock"],
  1116. return),
  1117. Providers = rebar_state:providers(State),
  1118. Namespace = rebar_state:namespace(State),
  1119. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  1120. GetOptSpec = providers:opts(CommandProvider),
  1121. %% Non existing testspec
  1122. {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec",Spec1]),
  1123. State1 = rebar_state:command_parsed_args(State, GetOptResult1),
  1124. Tests1 = rebar_prv_common_test:prepare_tests(State1),
  1125. {error,
  1126. {rebar_prv_common_test,
  1127. {error_reading_testspec,
  1128. {Spec1,"no such file or directory"}}}} =
  1129. rebar_prv_common_test:compile(State1, Tests1),
  1130. %% Syntax error
  1131. {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--spec",Spec2]),
  1132. State2 = rebar_state:command_parsed_args(State, GetOptResult2),
  1133. Tests2 = rebar_prv_common_test:prepare_tests(State2),
  1134. {error,
  1135. {rebar_prv_common_test,
  1136. {error_reading_testspec,
  1137. {Spec2,"1: syntax error before: '.'"}}}} =
  1138. rebar_prv_common_test:compile(State2, Tests2),
  1139. ok.
  1140. cmd_vs_cfg_opts(Config) ->
  1141. C = rebar_test_utils:init_rebar_state(Config, "ct_cmd_vs_cfg_opts_"),
  1142. AppDir = ?config(apps, C),
  1143. Name = rebar_test_utils:create_random_name("ct_cmd_vs_cfg_opts_"),
  1144. Vsn = rebar_test_utils:create_random_vsn(),
  1145. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1146. RebarConfig = [{ct_opts, [{spec,"mytest.spec"},
  1147. {dir,"test"},
  1148. {suite,"some_SUITE"},
  1149. {group,"some_group"},
  1150. {testcase,"some_test"}]}],
  1151. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  1152. {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
  1153. true = lists:member({spec, "mytest.spec"}, TestOpts),
  1154. true = lists:member({dir, "test"}, TestOpts),
  1155. true = lists:member({suite, "some_SUITE"}, TestOpts),
  1156. true = lists:member({group, "some_group"}, TestOpts),
  1157. true = lists:member({testcase, "some_test"}, TestOpts),
  1158. Providers = rebar_state:providers(State),
  1159. Namespace = rebar_state:namespace(State),
  1160. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  1161. GetOptSpec = providers:opts(CommandProvider),
  1162. {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec","test/some.spec"]),
  1163. State1 = rebar_state:command_parsed_args(State, GetOptResult1),
  1164. {ok, TestOpts1} = rebar_prv_common_test:prepare_tests(State1),
  1165. true = lists:member({spec, ["test/some.spec"]}, TestOpts1),
  1166. false = lists:keymember(dir, 1, TestOpts1),
  1167. false = lists:keymember(suite, 1, TestOpts1),
  1168. false = lists:keymember(group, 1, TestOpts1),
  1169. false = lists:keymember(testcase, 1, TestOpts1),
  1170. {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--suite","test/some_SUITE"]),
  1171. State2 = rebar_state:command_parsed_args(State, GetOptResult2),
  1172. {ok, TestOpts2} = rebar_prv_common_test:prepare_tests(State2),
  1173. true = lists:member({suite, ["test/some_SUITE"]}, TestOpts2),
  1174. false = lists:keymember(spec, 1, TestOpts2),
  1175. false = lists:keymember(dir, 1, TestOpts2),
  1176. false = lists:keymember(group, 1, TestOpts2),
  1177. false = lists:keymember(testcase, 1, TestOpts2),
  1178. ok.
  1179. single_testspec_in_ct_opts(Config) ->
  1180. C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_"),
  1181. AppDir = ?config(apps, C),
  1182. Name = rebar_test_utils:create_random_name("ct_testspec_"),
  1183. Vsn = rebar_test_utils:create_random_vsn(),
  1184. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1185. Spec = filename:join([AppDir, "test", "some.spec"]),
  1186. ok = filelib:ensure_dir(Spec),
  1187. ok = file:write_file(Spec, "{suites,\".\",all}.\n"),
  1188. {ok,Wd} = file:get_cwd(),
  1189. ok = file:set_cwd(AppDir),
  1190. RebarConfig = [{ct_opts, [{spec,"test/some.spec"}]}],
  1191. {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
  1192. Providers = rebar_state:providers(State),
  1193. Namespace = rebar_state:namespace(State),
  1194. CommandProvider = providers:get_provider(ct, Providers, Namespace),
  1195. GetOptSpec = providers:opts(CommandProvider),
  1196. %% Testspec in "test" directory
  1197. {ok, GetOptResult1} = getopt:parse(GetOptSpec, []),
  1198. State1 = rebar_state:command_parsed_args(State, GetOptResult1),
  1199. Tests1 = rebar_prv_common_test:prepare_tests(State1),
  1200. {ok, T1} = Tests1,
  1201. "test/some.spec" = proplists:get_value(spec,T1),
  1202. {ok, _NewState} = rebar_prv_common_test:compile(State1, Tests1),
  1203. ok = file:set_cwd(Wd),
  1204. ok.
  1205. compile_only(Config) ->
  1206. C = rebar_test_utils:init_rebar_state(Config, "compile_only_"),
  1207. AppDir = ?config(apps, C),
  1208. Name = rebar_test_utils:create_random_name(atom_to_list(basic_app) ++ "_"),
  1209. Vsn = rebar_test_utils:create_random_vsn(),
  1210. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1211. Suite = filename:join([AppDir, "test", Name ++ "_SUITE.erl"]),
  1212. ok = filelib:ensure_dir(Suite),
  1213. ok = file:write_file(Suite, test_suite(Name)),
  1214. {ok, _State} = rebar_test_utils:run_and_check(C, [], ["ct", "--compile_only"], {ok, [{app,Name}], "test"}).
  1215. %% helper for generating test data
  1216. test_suite(Name) ->
  1217. io_lib:format("-module(~ts_SUITE).\n"
  1218. "-compile(export_all).\n"
  1219. "all() -> [some_test].\n"
  1220. "some_test(_) -> ok.\n", [Name]).
  1221. cmd_sys_config_file(AppName) ->
  1222. io_lib:format("[{~ts, [{key, cmd_value}]}].", [AppName]).
  1223. cfg_sys_config_file(AppName) ->
  1224. io_lib:format("[{~ts, [{key, cfg_value}]}, \"config/other\"].", [AppName]).
  1225. other_sys_config_file(AppName) ->
  1226. io_lib:format("[{~ts, [{other_key, other_cfg_value}]}].", [AppName]).