您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

403 行
15 KiB

10 年前
10 年前
10 年前
10 年前
10 年前
10 年前
  1. -module(rebar_compile_SUITE).
  2. -export([suite/0,
  3. init_per_suite/1,
  4. end_per_suite/1,
  5. init_per_testcase/2,
  6. end_per_testcase/2,
  7. all/0,
  8. build_basic_app/1,
  9. build_release_apps/1,
  10. build_checkout_apps/1,
  11. build_checkout_deps/1,
  12. build_all_srcdirs/1,
  13. recompile_when_hrl_changes/1,
  14. recompile_when_opts_change/1,
  15. dont_recompile_when_opts_dont_change/1,
  16. dont_recompile_yrl_or_xrl/1,
  17. deps_in_path/1,
  18. checkout_priority/1,
  19. compile_plugins/1]).
  20. -include_lib("common_test/include/ct.hrl").
  21. -include_lib("eunit/include/eunit.hrl").
  22. -include_lib("kernel/include/file.hrl").
  23. suite() ->
  24. [].
  25. init_per_suite(Config) ->
  26. Config.
  27. end_per_suite(_Config) ->
  28. ok.
  29. init_per_testcase(_, Config) ->
  30. rebar_test_utils:init_rebar_state(Config).
  31. end_per_testcase(_, _Config) ->
  32. catch meck:unload().
  33. all() ->
  34. [build_basic_app, build_release_apps,
  35. build_checkout_apps, build_checkout_deps,
  36. build_all_srcdirs, recompile_when_hrl_changes,
  37. recompile_when_opts_change, dont_recompile_when_opts_dont_change,
  38. dont_recompile_yrl_or_xrl, deps_in_path, checkout_priority, compile_plugins].
  39. build_basic_app(Config) ->
  40. AppDir = ?config(apps, Config),
  41. Name = rebar_test_utils:create_random_name("app1_"),
  42. Vsn = rebar_test_utils:create_random_vsn(),
  43. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  44. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}).
  45. build_release_apps(Config) ->
  46. AppDir = ?config(apps, Config),
  47. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  48. Vsn1 = rebar_test_utils:create_random_vsn(),
  49. rebar_test_utils:create_app(filename:join([AppDir,Name1]), Name1, Vsn1, [kernel, stdlib]),
  50. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  51. Vsn2 = rebar_test_utils:create_random_vsn(),
  52. rebar_test_utils:create_app(filename:join([AppDir,Name2]), Name2, Vsn2, [kernel, stdlib]),
  53. rebar_test_utils:run_and_check(
  54. Config, [], ["compile"],
  55. {ok, [{app, Name1}, {app, Name2}]}
  56. ).
  57. build_checkout_apps(Config) ->
  58. AppDir = ?config(apps, Config),
  59. CheckoutsDir = ?config(checkouts, Config),
  60. Name1 = rebar_test_utils:create_random_name("checkapp1_"),
  61. Vsn1 = rebar_test_utils:create_random_vsn(),
  62. rebar_test_utils:create_app(filename:join([AppDir,Name1]), Name1, Vsn1, [kernel, stdlib]),
  63. Name2 = rebar_test_utils:create_random_name("checkapp2_"),
  64. Vsn2 = rebar_test_utils:create_random_vsn(),
  65. rebar_test_utils:create_app(filename:join([CheckoutsDir,Name2]), Name2, Vsn2, [kernel, stdlib]),
  66. rebar_test_utils:run_and_check(
  67. Config, [], ["compile"],
  68. {ok, [{app, Name1}, {checkout, Name2}]}
  69. ).
  70. build_checkout_deps(Config) ->
  71. AppDir = ?config(apps, Config),
  72. CheckoutsDir = ?config(checkouts, Config),
  73. DepsDir = filename:join([AppDir, "_build", "default", "lib"]),
  74. Name1 = rebar_test_utils:create_random_name("checkapp1_"),
  75. Vsn1 = rebar_test_utils:create_random_vsn(),
  76. rebar_test_utils:create_app(filename:join([AppDir,Name1]), Name1, Vsn1, [kernel, stdlib]),
  77. Name2 = rebar_test_utils:create_random_name("checkapp2_"),
  78. Vsn2 = rebar_test_utils:create_random_vsn(),
  79. rebar_test_utils:create_app(filename:join([CheckoutsDir,Name2]), Name2, Vsn2, [kernel, stdlib]),
  80. rebar_test_utils:create_app(filename:join([DepsDir,Name2]), Name2, Vsn1, [kernel, stdlib]),
  81. Deps = [{list_to_atom(Name2), Vsn2, {git, "", ""}}],
  82. {ok, RebarConfig} = file:consult(rebar_test_utils:create_config(AppDir, [{deps, Deps}])),
  83. rebar_test_utils:run_and_check(
  84. Config, RebarConfig, ["compile"],
  85. {ok, [{app, Name1}, {checkout, Name2}]}
  86. ),
  87. ok = application:load(list_to_atom(Name2)),
  88. Loaded = application:loaded_applications(),
  89. {_, _, Vsn2} = lists:keyfind(list_to_atom(Name2), 1, Loaded).
  90. build_all_srcdirs(Config) ->
  91. AppDir = ?config(apps, Config),
  92. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  93. Name = rebar_test_utils:create_random_name("app1_"),
  94. Vsn = rebar_test_utils:create_random_vsn(),
  95. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  96. ExtraSrc = <<"-module(extra_src).\n"
  97. "-export([ok/0]).\n"
  98. "ok() -> ok.\n">>,
  99. ok = filelib:ensure_dir(filename:join([AppDir, "extra", "dummy"])),
  100. ok = file:write_file(filename:join([AppDir, "extra", "extra_src.erl"]), ExtraSrc),
  101. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  102. %% check a beam corresponding to the src in the extra src_dir exists in ebin
  103. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  104. true = filelib:is_file(filename:join([EbinDir, "extra_src.beam"])),
  105. %% check the extra src_dir was linked into the _build dir
  106. true = filelib:is_dir(filename:join([AppDir, "_build", "default", "lib", Name, "extra"])).
  107. recompile_when_hrl_changes(Config) ->
  108. AppDir = ?config(apps, Config),
  109. Name = rebar_test_utils:create_random_name("app1_"),
  110. Vsn = rebar_test_utils:create_random_vsn(),
  111. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  112. ExtraSrc = <<"-module(test_header_include).\n"
  113. "-export([main/0]).\n"
  114. "-include(\"test_header_include.hrl\").\n"
  115. "main() -> ?SOME_DEFINE.\n">>,
  116. ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>,
  117. HeaderFile = filename:join([AppDir, "src", "test_header_include.hrl"]),
  118. ok = file:write_file(filename:join([AppDir, "src", "test_header_include.erl"]), ExtraSrc),
  119. ok = file:write_file(HeaderFile, ExtraHeader),
  120. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  121. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  122. {ok, Files} = file:list_dir(EbinDir),
  123. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  124. || F <- Files, filename:extension(F) == ".beam"],
  125. timer:sleep(1000),
  126. os:cmd("touch " ++ HeaderFile),
  127. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  128. {ok, NewFiles} = file:list_dir(EbinDir),
  129. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  130. || F <- NewFiles, filename:extension(F) == ".beam"],
  131. ?assert(ModTime =/= NewModTime).
  132. recompile_when_opts_change(Config) ->
  133. AppDir = ?config(apps, Config),
  134. Name = rebar_test_utils:create_random_name("app1_"),
  135. Vsn = rebar_test_utils:create_random_vsn(),
  136. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  137. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  138. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  139. {ok, Files} = file:list_dir(EbinDir),
  140. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  141. || F <- Files, filename:extension(F) == ".beam"],
  142. timer:sleep(1000),
  143. rebar_test_utils:create_config(AppDir, [{erl_opts, [{d, some_define}]}]),
  144. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  145. {ok, NewFiles} = file:list_dir(EbinDir),
  146. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  147. || F <- NewFiles, filename:extension(F) == ".beam"],
  148. ?assert(ModTime =/= NewModTime).
  149. dont_recompile_when_opts_dont_change(Config) ->
  150. AppDir = ?config(apps, Config),
  151. Name = rebar_test_utils:create_random_name("app1_"),
  152. Vsn = rebar_test_utils:create_random_vsn(),
  153. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  154. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  155. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  156. {ok, Files} = file:list_dir(EbinDir),
  157. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  158. || F <- Files, filename:extension(F) == ".beam"],
  159. timer:sleep(1000),
  160. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  161. {ok, NewFiles} = file:list_dir(EbinDir),
  162. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  163. || F <- NewFiles, filename:extension(F) == ".beam"],
  164. ?assert(ModTime == NewModTime).
  165. dont_recompile_yrl_or_xrl(Config) ->
  166. AppDir = ?config(apps, Config),
  167. Name = rebar_test_utils:create_random_name("app1_"),
  168. Vsn = rebar_test_utils:create_random_vsn(),
  169. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  170. Xrl = filename:join([AppDir, "src", "not_a_real_xrl_" ++ Name ++ ".xrl"]),
  171. ok = filelib:ensure_dir(Xrl),
  172. XrlBody =
  173. "Definitions."
  174. "\n\n"
  175. "D = [0-9]"
  176. "\n\n"
  177. "Rules."
  178. "\n\n"
  179. "{D}+ :"
  180. " {token,{integer,TokenLine,list_to_integer(TokenChars)}}."
  181. "\n\n"
  182. "{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :"
  183. " {token,{float,TokenLine,list_to_float(TokenChars)}}."
  184. "\n\n"
  185. "Erlang code.",
  186. ok = ec_file:write(Xrl, XrlBody),
  187. XrlBeam = filename:join([AppDir, "ebin", filename:basename(Xrl, ".xrl") ++ ".beam"]),
  188. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  189. ModTime = filelib:last_modified(XrlBeam),
  190. timer:sleep(1000),
  191. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  192. NewModTime = filelib:last_modified(XrlBeam),
  193. ?assert(ModTime == NewModTime).
  194. deps_in_path(Config) ->
  195. AppDir = ?config(apps, Config),
  196. StartPaths = code:get_path(),
  197. Name = rebar_test_utils:create_random_name("app1_"),
  198. Vsn = rebar_test_utils:create_random_vsn(),
  199. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  200. DepName = rebar_test_utils:create_random_name("dep1_"),
  201. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  202. mock_git_resource:mock([]),
  203. mock_pkg_resource:mock([
  204. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  205. ]),
  206. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  207. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  208. {list_to_atom(PkgName), Vsn}
  209. ]}]),
  210. {ok, RConf} = file:consult(RConfFile),
  211. %% Make sure apps we look for are not visible
  212. %% Hope not to find src name
  213. ?assertEqual([], [Path || Path <- code:get_path(),
  214. {match, _} <- [re:run(Path, DepName)]]),
  215. %% Hope not to find pkg name in there
  216. ?assertEqual([], [Path || Path <- code:get_path(),
  217. {match, _} <- [re:run(Path, PkgName)]]),
  218. %% Build things
  219. rebar_test_utils:run_and_check(
  220. Config, RConf, ["compile"],
  221. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  222. ),
  223. %% Find src name in there
  224. ?assertNotEqual([], [Path || Path <- code:get_path(),
  225. {match, _} <- [re:run(Path, DepName)]]),
  226. %% find pkg name in there
  227. ?assertNotEqual([], [Path || Path <- code:get_path(),
  228. {match, _} <- [re:run(Path, PkgName)]]),
  229. code:set_path(StartPaths),
  230. %% Make sure apps we look for are not visible again
  231. %% Hope not to find src name
  232. ?assertEqual([], [Path || Path <- code:get_path(),
  233. {match, _} <- [re:run(Path, DepName)]]),
  234. %% Hope not to find pkg name in there
  235. ?assertEqual([], [Path || Path <- code:get_path(),
  236. {match, _} <- [re:run(Path, PkgName)]]),
  237. %% Rebuild
  238. rebar_test_utils:run_and_check(
  239. Config, RConf, ["compile"],
  240. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  241. ),
  242. %% Find src name in there
  243. ?assertNotEqual([], [Path || Path <- code:get_path(),
  244. {match, _} <- [re:run(Path, DepName)]]),
  245. %% find pkg name in there
  246. ?assertNotEqual([], [Path || Path <- code:get_path(),
  247. {match, _} <- [re:run(Path, PkgName)]]).
  248. checkout_priority(Config) ->
  249. AppDir = ?config(apps, Config),
  250. CheckoutsDir = ?config(checkouts, Config),
  251. StartPaths = code:get_path(),
  252. Name = rebar_test_utils:create_random_name("app1_"),
  253. Vsn = rebar_test_utils:create_random_vsn(),
  254. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  255. DepName = rebar_test_utils:create_random_name("dep1_"),
  256. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  257. mock_git_resource:mock([]),
  258. mock_pkg_resource:mock([
  259. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  260. ]),
  261. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  262. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  263. {list_to_atom(PkgName), Vsn}
  264. ]}]),
  265. {ok, RConf} = file:consult(RConfFile),
  266. %% Build with deps.
  267. rebar_test_utils:run_and_check(
  268. Config, RConf, ["compile"],
  269. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  270. ),
  271. %% Build two checkout apps similar to dependencies to be fetched,
  272. %% but on a different version
  273. Vsn2 = rebar_test_utils:create_random_vsn(),
  274. rebar_test_utils:create_app(filename:join([CheckoutsDir,DepName]), DepName, Vsn2, [kernel, stdlib]),
  275. rebar_test_utils:create_app(filename:join([CheckoutsDir,PkgName]), PkgName, Vsn2, [kernel, stdlib]),
  276. %% Rebuild and make sure the checkout apps are in path
  277. code:set_path(StartPaths),
  278. rebar_test_utils:run_and_check(
  279. Config, RConf, ["compile"],
  280. {ok, [{app, Name}, {checkout, DepName}, {checkout, PkgName}]}
  281. ),
  282. [DepPath] = [Path || Path <- code:get_path(),
  283. {match, _} <- [re:run(Path, DepName)]],
  284. [PkgPath] = [Path || Path <- code:get_path(),
  285. {match, _} <- [re:run(Path, PkgName)]],
  286. {ok, [DepApp]} = file:consult(filename:join([DepPath, DepName ++ ".app"])),
  287. {ok, [PkgApp]} = file:consult(filename:join([PkgPath, PkgName ++ ".app"])),
  288. {application, _, DepProps} = DepApp,
  289. {application, _, PkgProps} = PkgApp,
  290. ?assertEqual(Vsn2, proplists:get_value(vsn, DepProps)),
  291. ?assertEqual(Vsn2, proplists:get_value(vsn, PkgProps)).
  292. %% Tests that compiling a project installs and compiles the plugins of deps
  293. compile_plugins(Config) ->
  294. AppDir = ?config(apps, Config),
  295. PluginsDir = filename:join([?config(base_dir, Config), "default", "plugins"]),
  296. Name = rebar_test_utils:create_random_name("app1_"),
  297. Vsn = rebar_test_utils:create_random_vsn(),
  298. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  299. DepName = rebar_test_utils:create_random_name("dep1_"),
  300. PluginName = rebar_test_utils:create_random_name("plugin1_"),
  301. mock_git_resource:mock([{config, [{plugins, [
  302. {list_to_atom(PluginName), Vsn}
  303. ]}]}]),
  304. mock_pkg_resource:mock([
  305. {pkgdeps, [{{iolist_to_binary(PluginName), iolist_to_binary(Vsn)}, []}]}
  306. ]),
  307. RConfFile =
  308. rebar_test_utils:create_config(AppDir,
  309. [{deps, [
  310. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}}
  311. ]}]),
  312. {ok, RConf} = file:consult(RConfFile),
  313. %% Build with deps.
  314. rebar_test_utils:run_and_check(
  315. Config, RConf, ["compile"],
  316. {ok, [{app, Name}, {plugin, PluginName}, {dep, DepName}]}
  317. ).