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.

444 rader
14 KiB

  1. -module(rebar_upgrade_SUITE).
  2. -include_lib("common_test/include/ct.hrl").
  3. -include_lib("eunit/include/eunit.hrl").
  4. -compile(export_all).
  5. all() -> [{group, git}, {group, pkg}].
  6. groups() ->
  7. [{all, [], [top_a, top_b, top_c, top_d1, top_d2, top_e,
  8. pair_a, pair_b, pair_ab, pair_c, pair_all,
  9. triplet_a, triplet_b, triplet_c,
  10. tree_a, tree_b, tree_c, tree_c2, tree_ac, tree_all,
  11. delete_d]},
  12. {git, [], [{group, all}]},
  13. {pkg, [], [{group, all}]}].
  14. init_per_suite(Config) ->
  15. application:start(meck),
  16. Config.
  17. end_per_suite(_Config) ->
  18. application:stop(meck).
  19. init_per_group(git, Config) ->
  20. [{deps_type, git} | Config];
  21. init_per_group(pkg, Config) ->
  22. [{deps_type, pkg} | Config];
  23. init_per_group(_, Config) ->
  24. Config.
  25. end_per_group(_, Config) ->
  26. Config.
  27. init_per_testcase(Case, Config) ->
  28. DepsType = ?config(deps_type, Config),
  29. {Deps, UpDeps, ToUp, Expectations} = upgrades(Case),
  30. Expanded = rebar_test_utils:expand_deps(DepsType, Deps),
  31. UpExpanded = rebar_test_utils:expand_deps(DepsType, UpDeps),
  32. [{expected, normalize_unlocks(Expectations)},
  33. {mock, fun() -> mock_deps(DepsType, Expanded, []) end},
  34. {mock_update, fun() -> mock_deps(DepsType, Expanded, UpExpanded, ToUp) end}
  35. | setup_project(Case, Config, Expanded, UpExpanded)].
  36. end_per_testcase(_, Config) ->
  37. meck:unload(),
  38. Config.
  39. setup_project(Case, Config0, Deps, UpDeps) ->
  40. DepsType = ?config(deps_type, Config0),
  41. Config = rebar_test_utils:init_rebar_state(
  42. Config0,
  43. atom_to_list(Case)++"_"++atom_to_list(DepsType)++"_"
  44. ),
  45. AppDir = ?config(apps, Config),
  46. rebar_test_utils:create_app(AppDir, "Root", "0.0.0", [kernel, stdlib]),
  47. TopDeps = rebar_test_utils:top_level_deps(Deps),
  48. RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
  49. [{rebarconfig, RebarConf},
  50. {next_top_deps, rebar_test_utils:top_level_deps(UpDeps)} | Config].
  51. upgrades(top_a) ->
  52. %% Original tree
  53. {[{"A", "1", [{"B", [{"D", "1", []}]},
  54. {"C", [{"D", "2", []}]}]}
  55. ],
  56. %% Updated tree
  57. [{"A", "1", [{"B", [{"D", "3", []}]},
  58. {"C", [{"D", "2", []}]}]}
  59. ],
  60. %% Modified apps, gobally
  61. ["A","B","D"],
  62. %% upgrade vs. new tree
  63. {"A", [{"A","1"}, "B", "C", {"D","3"}]}};
  64. upgrades(top_b) ->
  65. %% Original tree
  66. {[{"A", "1", [{"B", [{"D", "1", []}]},
  67. {"C", [{"D", "2", []}]}]}
  68. ],
  69. %% Updated tree
  70. [{"A", "1", [{"B", [{"D", "3", []}]},
  71. {"C", [{"D", "2", []}]}]}
  72. ],
  73. %% Modified apps, gobally
  74. ["A","B","D"],
  75. %% upgrade vs. new tree
  76. {"B", {error, {rebar_prv_upgrade, {transitive_dependency, <<"B">>}}}}};
  77. upgrades(top_c) ->
  78. %% Original tree
  79. {[{"A", "1", [{"B", [{"D", "1", []}]},
  80. {"C", [{"D", "2", []}]}]}
  81. ],
  82. %% Updated tree
  83. [{"A", "1", [{"B", [{"D", "3", []}]},
  84. {"C", [{"D", "2", []}]}]}
  85. ],
  86. %% Modified apps, gobally
  87. ["A","B","D"],
  88. %% upgrade vs. new tree
  89. {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}};
  90. upgrades(top_d1) ->
  91. %% Original tree
  92. {[{"A", "1", [{"B", [{"D", "1", []}]},
  93. {"C", [{"D", "2", []}]}]}
  94. ],
  95. %% Updated tree
  96. [{"A", "1", [{"B", [{"D", "3", []}]},
  97. {"C", [{"D", "2", []}]}]}
  98. ],
  99. %% Modified apps, gobally
  100. ["A","B","D"],
  101. %% upgrade vs. new tree
  102. {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}};
  103. upgrades(top_d2) ->
  104. %% Original tree
  105. {[{"A", "1", [{"B", [{"D", "1", []}]},
  106. {"C", [{"D", "2", []}]}]}
  107. ],
  108. %% Updated tree
  109. [{"A", "1", [{"B", [{"D", "3", []}]},
  110. {"C", [{"D", "2", []}]}]}
  111. ],
  112. %% Modified apps, gobally
  113. ["A","B","D"],
  114. %% upgrade vs. new tree
  115. {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}};
  116. upgrades(top_e) ->
  117. %% Original tree
  118. {[{"A", "1", [{"B", [{"D", "1", []}]},
  119. {"C", [{"D", "2", []}]}]}
  120. ],
  121. %% Updated tree
  122. [{"A", "1", [{"B", [{"D", "3", []}]},
  123. {"C", [{"D", "2", []}]}]}
  124. ],
  125. %% Modified apps, gobally
  126. ["A","B","D"],
  127. %% upgrade vs. new tree
  128. {"E", {error, {rebar_prv_upgrade, {unknown_dependency, <<"E">>}}}}};
  129. upgrades(pair_a) ->
  130. {[{"A", "1", [{"C", "1", []}]},
  131. {"B", "1", [{"D", "1", []}]}
  132. ],
  133. [{"A", "2", [{"C", "2", []}]},
  134. {"B", "2", [{"D", "2", []}]}
  135. ],
  136. ["A","B","C","D"],
  137. {"A", [{"A","2"},{"C","2"},{"B","1"},{"D","1"}]}};
  138. upgrades(pair_b) ->
  139. {[{"A", "1", [{"C", "1", []}]},
  140. {"B", "1", [{"D", "1", []}]}
  141. ],
  142. [{"A", "2", [{"C", "2", []}]},
  143. {"B", "2", [{"D", "2", []}]}
  144. ],
  145. ["A","B","C","D"],
  146. {"B", [{"A","1"},{"C","1"},{"B","2"},{"D","2"}]}};
  147. upgrades(pair_ab) ->
  148. {[{"A", "1", [{"C", "1", []}]},
  149. {"B", "1", [{"D", "1", []}]}
  150. ],
  151. [{"A", "2", [{"C", "2", []}]},
  152. {"B", "2", [{"D", "2", []}]}
  153. ],
  154. ["A","B","C","D"],
  155. {"A,B", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}};
  156. upgrades(pair_c) ->
  157. {[{"A", "1", [{"C", "1", []}]},
  158. {"B", "1", [{"D", "1", []}]}
  159. ],
  160. [{"A", "2", [{"C", "2", []}]},
  161. {"B", "2", [{"D", "2", []}]}
  162. ],
  163. ["A","B","C","D"],
  164. {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}};
  165. upgrades(pair_all) ->
  166. {[{"A", "1", [{"C", "1", []}]},
  167. {"B", "1", [{"D", "1", []}]}
  168. ],
  169. [{"A", "2", [{"C", "2", []}]},
  170. {"B", "2", [{"D", "2", []}]}
  171. ],
  172. ["A","B","C","D"],
  173. {"", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}};
  174. upgrades(triplet_a) ->
  175. {[{"A", "1", [{"D",[]},
  176. {"E","3",[]}]},
  177. {"B", "1", [{"F","1",[]},
  178. {"G",[]}]},
  179. {"C", "0", [{"H","3",[]},
  180. {"I",[]}]}],
  181. [{"A", "1", [{"D",[]},
  182. {"E","2",[]}]},
  183. {"B", "1", [{"F","1",[]},
  184. {"G",[]}]},
  185. {"C", "1", [{"H","4",[]},
  186. {"I",[]}]}],
  187. ["A","C","E","H"],
  188. {"A", [{"A","1"}, "D", {"E","2"},
  189. {"B","1"}, {"F","1"}, "G",
  190. {"C","0"}, {"H","3"}, "I"]}};
  191. upgrades(triplet_b) ->
  192. {[{"A", "1", [{"D",[]},
  193. {"E","3",[]}]},
  194. {"B", "1", [{"F","1",[]},
  195. {"G",[]}]},
  196. {"C", "0", [{"H","3",[]},
  197. {"I",[]}]}],
  198. [{"A", "2", [{"D",[]},
  199. {"E","2",[]}]},
  200. {"B", "1", [{"F","1",[]},
  201. {"G",[]}]},
  202. {"C", "1", [{"H","4",[]},
  203. {"I",[]}]}],
  204. ["A","C","E","H"],
  205. {"B", [{"A","1"}, "D", {"E","3"},
  206. {"B","1"}, {"F","1"}, "G",
  207. {"C","0"}, {"H","3"}, "I"]}};
  208. upgrades(triplet_c) ->
  209. {[{"A", "1", [{"D",[]},
  210. {"E","3",[]}]},
  211. {"B", "1", [{"F","1",[]},
  212. {"G",[]}]},
  213. {"C", "0", [{"H","3",[]},
  214. {"I",[]}]}],
  215. [{"A", "2", [{"D",[]},
  216. {"E","2",[]}]},
  217. {"B", "1", [{"F","1",[]},
  218. {"G",[]}]},
  219. {"C", "1", [{"H","4",[]},
  220. {"I",[]}]}],
  221. ["A","C","E","H"],
  222. {"C", [{"A","1"}, "D", {"E","3"},
  223. {"B","1"}, {"F","1"}, "G",
  224. {"C","1"}, {"H","4"}, "I"]}};
  225. upgrades(tree_a) ->
  226. {[{"A", "1", [{"D",[{"J",[]}]},
  227. {"E",[{"I","1",[]}]}]},
  228. {"B", "1", [{"F",[]},
  229. {"G",[]}]},
  230. {"C", "1", [{"H",[]},
  231. {"I","2",[]}]}
  232. ],
  233. [{"A", "1", [{"D",[{"J",[]}]},
  234. {"E",[{"I","1",[]}]}]},
  235. {"B", "1", [{"F",[]},
  236. {"G",[]}]},
  237. {"C", "2", [{"H",[]}]}
  238. ],
  239. ["C"],
  240. {"A", [{"A","1"}, "D", "J", "E",
  241. {"B","1"}, "F", "G",
  242. {"C","1"}, "H", {"I","2"}]}};
  243. upgrades(tree_b) ->
  244. {[{"A", "1", [{"D",[{"J",[]}]},
  245. {"E",[{"I","1",[]}]}]},
  246. {"B", "1", [{"F",[]},
  247. {"G",[]}]},
  248. {"C", "1", [{"H",[]},
  249. {"I","2",[]}]}
  250. ],
  251. [{"A", "1", [{"D",[{"J",[]}]},
  252. {"E",[{"I","1",[]}]}]},
  253. {"B", "1", [{"F",[]},
  254. {"G",[]}]},
  255. {"C", "2", [{"H",[]}]}
  256. ],
  257. ["C"],
  258. {"B", [{"A","1"}, "D", "J", "E",
  259. {"B","1"}, "F", "G",
  260. {"C","1"}, "H", {"I","2"}]}};
  261. upgrades(tree_c) ->
  262. {[{"A", "1", [{"D",[{"J",[]}]},
  263. {"E",[{"I","1",[]}]}]},
  264. {"B", "1", [{"F",[]},
  265. {"G",[]}]},
  266. {"C", "1", [{"H",[]},
  267. {"I","2",[]}]}
  268. ],
  269. [{"A", "1", [{"D",[{"J",[]}]},
  270. {"E",[{"I","1",[]}]}]},
  271. {"B", "1", [{"F",[]},
  272. {"G",[]}]},
  273. {"C", "1", [{"H",[]}]}
  274. ],
  275. ["C","I"],
  276. {"C", [{"A","1"}, "D", "J", "E", {"I","1"},
  277. {"B","1"}, "F", "G",
  278. {"C","1"}, "H"]}};
  279. upgrades(tree_c2) ->
  280. {[{"A", "1", [{"D",[{"J",[]}]},
  281. {"E",[{"I","1",[]}]}]},
  282. {"B", "1", [{"F",[]},
  283. {"G",[]}]},
  284. {"C", "1", [{"H",[]},
  285. {"I","2",[]}]}
  286. ],
  287. [{"A", "1", [{"D",[{"J",[]}]},
  288. {"E",[{"I","1",[]}]}]},
  289. {"B", "1", [{"F",[]},
  290. {"G",[]}]},
  291. {"C", "1", [{"H",[{"K",[]}]},
  292. {"I","2",[]}]}
  293. ],
  294. ["C", "H"],
  295. {"C", [{"A","1"}, "D", "J", "E",
  296. {"B","1"}, "F", "G",
  297. {"C","1"}, "H", {"I", "2"}, "K"]}};
  298. upgrades(tree_ac) ->
  299. {[{"A", "1", [{"D",[{"J",[]}]},
  300. {"E",[{"I","1",[]}]}]},
  301. {"B", "1", [{"F",[]},
  302. {"G",[]}]},
  303. {"C", "1", [{"H",[]},
  304. {"I","2",[]}]}
  305. ],
  306. [{"A", "1", [{"D",[{"J",[]}]},
  307. {"E",[{"I","1",[]}]}]},
  308. {"B", "1", [{"F",[]},
  309. {"G",[]}]},
  310. {"C", "1", [{"H",[]}]}
  311. ],
  312. ["C","I"],
  313. {"C, A", [{"A","1"}, "D", "J", "E", {"I","1"},
  314. {"B","1"}, "F", "G",
  315. {"C","1"}, "H"]}};
  316. upgrades(tree_all) ->
  317. {[{"A", "1", [{"D",[{"J",[]}]},
  318. {"E",[{"I","1",[]}]}]},
  319. {"B", "1", [{"F",[]},
  320. {"G",[]}]},
  321. {"C", "1", [{"H",[]},
  322. {"I","2",[]}]}
  323. ],
  324. [{"A", "1", [{"D",[{"J",[]}]},
  325. {"E",[{"I","1",[]}]}]},
  326. {"B", "1", [{"F",[]},
  327. {"G",[]}]},
  328. {"C", "1", [{"H",[]}]}
  329. ],
  330. ["C","I"],
  331. {"", [{"A","1"}, "D", "J", "E", {"I","1"},
  332. {"B","1"}, "F", "G",
  333. {"C","1"}, "H"]}};
  334. upgrades(delete_d) ->
  335. {[{"A", "1", [{"B", [{"D", "1", []}]},
  336. {"C", [{"D", "2", []}]}]}
  337. ],
  338. [{"A", "2", [{"B", []},
  339. {"C", []}]}
  340. ],
  341. ["A","B", "C"],
  342. %% upgrade vs. new tree
  343. {"", [{"A","2"}, "B", "C"]}}.
  344. %% TODO: add a test that verifies that unlocking files and then
  345. %% running the upgrade code is enough to properly upgrade things.
  346. mock_deps(git, Deps, Upgrades) ->
  347. catch mock_git_resource:unmock(),
  348. mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}, {upgrade, Upgrades}]);
  349. mock_deps(pkg, Deps, Upgrades) ->
  350. catch mock_pkg_resource:unmock(),
  351. mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}, {upgrade, Upgrades}]).
  352. mock_deps(git, _OldDeps, Deps, Upgrades) ->
  353. catch mock_git_resource:unmock(),
  354. mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}, {upgrade, Upgrades}]);
  355. mock_deps(pkg, OldDeps, Deps, Upgrades) ->
  356. Merged = Deps ++ [Dep || Dep <- OldDeps,
  357. not lists:keymember(element(1, Dep), 1, Deps)],
  358. catch mock_pkg_resource:unmock(),
  359. mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Merged)}, {upgrade, Upgrades}]).
  360. normalize_unlocks({App, Locks}) ->
  361. {iolist_to_binary(App),
  362. normalize_unlocks_expect(Locks)};
  363. normalize_unlocks({App, Vsn, Locks}) ->
  364. {iolist_to_binary(App), iolist_to_binary(Vsn),
  365. normalize_unlocks_expect(Locks)}.
  366. normalize_unlocks_expect({error, Reason}) ->
  367. {error, Reason};
  368. normalize_unlocks_expect([]) ->
  369. [];
  370. normalize_unlocks_expect([{App,Vsn} | Rest]) ->
  371. [{dep, App, Vsn},
  372. {lock, App, Vsn}
  373. | normalize_unlocks_expect(Rest)];
  374. normalize_unlocks_expect([App | Rest]) ->
  375. [{dep, App},
  376. {lock, App} | normalize_unlocks_expect(Rest)].
  377. top_a(Config) -> run(Config).
  378. top_b(Config) -> run(Config).
  379. top_c(Config) -> run(Config).
  380. top_d1(Config) -> run(Config).
  381. top_d2(Config) -> run(Config).
  382. top_e(Config) -> run(Config).
  383. pair_a(Config) -> run(Config).
  384. pair_b(Config) -> run(Config).
  385. pair_ab(Config) -> run(Config).
  386. pair_c(Config) -> run(Config).
  387. pair_all(Config) -> run(Config).
  388. triplet_a(Config) -> run(Config).
  389. triplet_b(Config) -> run(Config).
  390. triplet_c(Config) -> run(Config).
  391. tree_a(Config) -> run(Config).
  392. tree_b(Config) -> run(Config).
  393. tree_c(Config) -> run(Config).
  394. tree_c2(Config) -> run(Config).
  395. tree_ac(Config) -> run(Config).
  396. tree_all(Config) -> run(Config).
  397. delete_d(Config) ->
  398. meck:new(rebar_log, [no_link, passthrough]),
  399. run(Config),
  400. Infos = [{Str, Args}
  401. || {_, {rebar_log, log, [info, Str, Args]}, _} <- meck:history(rebar_log)],
  402. meck:unload(rebar_log),
  403. ?assertNotEqual([],
  404. [1 || {"App ~ts is no longer needed and can be deleted.",
  405. [<<"D">>]} <- Infos]).
  406. run(Config) ->
  407. apply(?config(mock, Config), []),
  408. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  409. %% Install dependencies before re-mocking for an upgrade
  410. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  411. {App, Unlocks} = ?config(expected, Config),
  412. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  413. Expectation = case Unlocks of
  414. {error, Term} -> {error, Term};
  415. _ -> {ok, Unlocks}
  416. end,
  417. apply(?config(mock_update, Config), []),
  418. NewRebarConf = rebar_test_utils:create_config(?config(apps, Config),
  419. [{deps, ?config(next_top_deps, Config)}]),
  420. {ok, NewRebarConfig} = file:consult(NewRebarConf),
  421. rebar_test_utils:run_and_check(
  422. Config, NewRebarConfig, ["upgrade", App], Expectation
  423. ).