You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

669 lines
23 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}, novsn_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_cj, tree_ac, tree_all,
  11. delete_d, promote, stable_lock, fwd_lock,
  12. compile_upgrade_parity, umbrella_config]},
  13. {git, [], [{group, all}]},
  14. {pkg, [], [{group, all}]}].
  15. init_per_suite(Config) ->
  16. application:start(meck),
  17. Config.
  18. end_per_suite(_Config) ->
  19. application:stop(meck).
  20. init_per_group(git, Config) ->
  21. [{deps_type, git} | Config];
  22. init_per_group(pkg, Config) ->
  23. [{deps_type, pkg} | Config];
  24. init_per_group(_, Config) ->
  25. Config.
  26. end_per_group(_, Config) ->
  27. Config.
  28. init_per_testcase(novsn_pkg, Config0) ->
  29. Config = rebar_test_utils:init_rebar_state(Config0, "novsn_pkg_"),
  30. AppDir = ?config(apps, Config),
  31. RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [fakeapp]}]),
  32. Deps = [{{<<"fakeapp">>, <<"1.0.0">>}, []}],
  33. UpDeps = [{{<<"fakeapp">>, <<"1.1.0">>}, []}],
  34. Upgrades = ["fakeapp"],
  35. [{rebarconfig, RebarConf},
  36. {mock, fun() ->
  37. catch mock_pkg_resource:unmock(),
  38. mock_pkg_resource:mock([{pkgdeps, Deps}, {upgrade, []}])
  39. end},
  40. {mock_update, fun() ->
  41. catch mock_pkg_resource:unmock(),
  42. mock_pkg_resource:mock([{pkgdeps, UpDeps++Deps}, {upgrade, Upgrades}])
  43. end},
  44. {expected, {ok, [{dep, "fakeapp", "1.1.0"}, {lock, "fakeapp", "1.1.0"}]}}
  45. | Config];
  46. init_per_testcase(Case, Config) ->
  47. DepsType = ?config(deps_type, Config),
  48. {Deps, UpDeps, ToUp, Expectations} = upgrades(Case),
  49. Expanded = rebar_test_utils:expand_deps(DepsType, Deps),
  50. UpExpanded = rebar_test_utils:expand_deps(DepsType, UpDeps),
  51. [{expected, normalize_unlocks(Expectations)},
  52. {mock, fun() -> mock_deps(DepsType, Expanded, []) end},
  53. {mock_update, fun() -> mock_deps(DepsType, Expanded, UpExpanded, ToUp) end}
  54. | setup_project(Case, Config, Expanded, UpExpanded)].
  55. end_per_testcase(_, Config) ->
  56. meck:unload(),
  57. Config.
  58. setup_project(Case=umbrella_config, Config0, Deps, UpDeps) ->
  59. DepsType = ?config(deps_type, Config0),
  60. NameRoot = atom_to_list(Case)++"_"++atom_to_list(DepsType),
  61. Config = rebar_test_utils:init_rebar_state(Config0, NameRoot++"_"),
  62. AppDir = filename:join([?config(apps, Config), "apps", NameRoot]),
  63. rebar_test_utils:create_app(AppDir, "Root", "0.0.0", [kernel, stdlib]),
  64. TopDeps = rebar_test_utils:top_level_deps(Deps),
  65. TopConf = rebar_test_utils:create_config(AppDir, [{deps, []}]),
  66. RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
  67. [{rebarconfig, TopConf},
  68. {rebarumbrella, RebarConf},
  69. {next_top_deps, rebar_test_utils:top_level_deps(UpDeps)} | Config];
  70. setup_project(Case, Config0, Deps, UpDeps) ->
  71. DepsType = ?config(deps_type, Config0),
  72. Config = rebar_test_utils:init_rebar_state(
  73. Config0,
  74. atom_to_list(Case)++"_"++atom_to_list(DepsType)++"_"
  75. ),
  76. AppDir = ?config(apps, Config),
  77. rebar_test_utils:create_app(AppDir, "Root", "0.0.0", [kernel, stdlib]),
  78. TopDeps = rebar_test_utils:top_level_deps(Deps),
  79. RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
  80. [{rebarconfig, RebarConf},
  81. {next_top_deps, rebar_test_utils:top_level_deps(UpDeps)} | Config].
  82. upgrades(top_a) ->
  83. %% Original tree
  84. {[{"A", "1", [{"B", [{"D", "1", []}]},
  85. {"C", [{"D", "2", []}]}]}
  86. ],
  87. %% Updated tree
  88. [{"A", "1", [{"B", [{"D", "3", []}]},
  89. {"C", [{"D", "2", []}]}]}
  90. ],
  91. %% Modified apps, gobally
  92. ["A","B","D"],
  93. %% upgrade vs. new tree
  94. {"A", [{"A","1"}, "B", "C", {"D","3"}]}};
  95. upgrades(top_b) ->
  96. %% Original tree
  97. {[{"A", "1", [{"B", [{"D", "1", []}]},
  98. {"C", [{"D", "2", []}]}]}
  99. ],
  100. %% Updated tree
  101. [{"A", "1", [{"B", [{"D", "3", []}]},
  102. {"C", [{"D", "2", []}]}]}
  103. ],
  104. %% Modified apps, gobally
  105. ["A","B","D"],
  106. %% upgrade vs. new tree
  107. {"B", {error, {rebar_prv_upgrade, {transitive_dependency, <<"B">>}}}}};
  108. upgrades(top_c) ->
  109. %% Original tree
  110. {[{"A", "1", [{"B", [{"D", "1", []}]},
  111. {"C", [{"D", "2", []}]}]}
  112. ],
  113. %% Updated tree
  114. [{"A", "1", [{"B", [{"D", "3", []}]},
  115. {"C", [{"D", "2", []}]}]}
  116. ],
  117. %% Modified apps, gobally
  118. ["A","B","D"],
  119. %% upgrade vs. new tree
  120. {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}};
  121. upgrades(top_d1) ->
  122. %% Original tree
  123. {[{"A", "1", [{"B", [{"D", "1", []}]},
  124. {"C", [{"D", "2", []}]}]}
  125. ],
  126. %% Updated tree
  127. [{"A", "1", [{"B", [{"D", "3", []}]},
  128. {"C", [{"D", "2", []}]}]}
  129. ],
  130. %% Modified apps, gobally
  131. ["A","B","D"],
  132. %% upgrade vs. new tree
  133. {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}};
  134. upgrades(top_d2) ->
  135. %% Original tree
  136. {[{"A", "1", [{"B", [{"D", "1", []}]},
  137. {"C", [{"D", "2", []}]}]}
  138. ],
  139. %% Updated tree
  140. [{"A", "1", [{"B", [{"D", "3", []}]},
  141. {"C", [{"D", "2", []}]}]}
  142. ],
  143. %% Modified apps, gobally
  144. ["A","B","D"],
  145. %% upgrade vs. new tree
  146. {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}};
  147. upgrades(top_e) ->
  148. %% Original tree
  149. {[{"A", "1", [{"B", [{"D", "1", []}]},
  150. {"C", [{"D", "2", []}]}]}
  151. ],
  152. %% Updated tree
  153. [{"A", "1", [{"B", [{"D", "3", []}]},
  154. {"C", [{"D", "2", []}]}]}
  155. ],
  156. %% Modified apps, gobally
  157. ["A","B","D"],
  158. %% upgrade vs. new tree
  159. {"E", {error, {rebar_prv_upgrade, {unknown_dependency, <<"E">>}}}}};
  160. upgrades(pair_a) ->
  161. {[{"A", "1", [{"C", "1", []}]},
  162. {"B", "1", [{"D", "1", []}]}
  163. ],
  164. [{"A", "2", [{"C", "2", []}]},
  165. {"B", "2", [{"D", "2", []}]}
  166. ],
  167. ["A","B","C","D"],
  168. {"A", [{"A","2"},{"C","2"},{"B","1"},{"D","1"}]}};
  169. upgrades(pair_b) ->
  170. {[{"A", "1", [{"C", "1", []}]},
  171. {"B", "1", [{"D", "1", []}]}
  172. ],
  173. [{"A", "2", [{"C", "2", []}]},
  174. {"B", "2", [{"D", "2", []}]}
  175. ],
  176. ["A","B","C","D"],
  177. {"B", [{"A","1"},{"C","1"},{"B","2"},{"D","2"}]}};
  178. upgrades(pair_ab) ->
  179. {[{"A", "1", [{"C", "1", []}]},
  180. {"B", "1", [{"D", "1", []}]}
  181. ],
  182. [{"A", "2", [{"C", "2", []}]},
  183. {"B", "2", [{"D", "2", []}]}
  184. ],
  185. ["A","B","C","D"],
  186. {"A,B", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}};
  187. upgrades(pair_c) ->
  188. {[{"A", "1", [{"C", "1", []}]},
  189. {"B", "1", [{"D", "1", []}]}
  190. ],
  191. [{"A", "2", [{"C", "2", []}]},
  192. {"B", "2", [{"D", "2", []}]}
  193. ],
  194. ["A","B","C","D"],
  195. {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}};
  196. upgrades(pair_all) ->
  197. {[{"A", "1", [{"C", "1", []}]},
  198. {"B", "1", [{"D", "1", []}]}
  199. ],
  200. [{"A", "2", [{"C", "2", []}]},
  201. {"B", "2", [{"D", "2", []}]}
  202. ],
  203. ["A","B","C","D"],
  204. {"", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}};
  205. upgrades(triplet_a) ->
  206. {[{"A", "1", [{"D",[]},
  207. {"E","3",[]}]},
  208. {"B", "1", [{"F","1",[]},
  209. {"G",[]}]},
  210. {"C", "0", [{"H","3",[]},
  211. {"I",[]}]}],
  212. [{"A", "1", [{"D",[]},
  213. {"E","2",[]}]},
  214. {"B", "1", [{"F","1",[]},
  215. {"G",[]}]},
  216. {"C", "1", [{"H","4",[]},
  217. {"I",[]}]}],
  218. ["A","C","E","H"],
  219. {"A", [{"A","1"}, "D", {"E","2"},
  220. {"B","1"}, {"F","1"}, "G",
  221. {"C","0"}, {"H","3"}, "I"]}};
  222. upgrades(triplet_b) ->
  223. {[{"A", "1", [{"D",[]},
  224. {"E","3",[]}]},
  225. {"B", "1", [{"F","1",[]},
  226. {"G",[]}]},
  227. {"C", "0", [{"H","3",[]},
  228. {"I",[]}]}],
  229. [{"A", "2", [{"D",[]},
  230. {"E","2",[]}]},
  231. {"B", "1", [{"F","1",[]},
  232. {"G",[]}]},
  233. {"C", "1", [{"H","4",[]},
  234. {"I",[]}]}],
  235. ["A","C","E","H"],
  236. {"B", [{"A","1"}, "D", {"E","3"},
  237. {"B","1"}, {"F","1"}, "G",
  238. {"C","0"}, {"H","3"}, "I"]}};
  239. upgrades(triplet_c) ->
  240. {[{"A", "1", [{"D",[]},
  241. {"E","3",[]}]},
  242. {"B", "1", [{"F","1",[]},
  243. {"G",[]}]},
  244. {"C", "0", [{"H","3",[]},
  245. {"I",[]}]}],
  246. [{"A", "2", [{"D",[]},
  247. {"E","2",[]}]},
  248. {"B", "1", [{"F","1",[]},
  249. {"G",[]}]},
  250. {"C", "1", [{"H","4",[]},
  251. {"I",[]}]}],
  252. ["A","C","E","H"],
  253. {"C", [{"A","1"}, "D", {"E","3"},
  254. {"B","1"}, {"F","1"}, "G",
  255. {"C","1"}, {"H","4"}, "I"]}};
  256. upgrades(tree_a) ->
  257. {[{"A", "1", [{"D",[{"J",[]}]},
  258. {"E",[{"I","1",[]}]}]},
  259. {"B", "1", [{"F",[]},
  260. {"G",[]}]},
  261. {"C", "1", [{"H",[]},
  262. {"I","2",[]}]}
  263. ],
  264. [{"A", "1", [{"D",[{"J",[]}]},
  265. {"E",[{"I","1",[]}]}]},
  266. {"B", "1", [{"F",[]},
  267. {"G",[]}]},
  268. {"C", "2", [{"H",[]}]}
  269. ],
  270. ["C"],
  271. {"A", [{"A","1"}, "D", "J", "E",
  272. {"B","1"}, "F", "G",
  273. {"C","1"}, "H", {"I","2"}]}};
  274. upgrades(tree_b) ->
  275. {[{"A", "1", [{"D",[{"J",[]}]},
  276. {"E",[{"I","1",[]}]}]},
  277. {"B", "1", [{"F",[]},
  278. {"G",[]}]},
  279. {"C", "1", [{"H",[]},
  280. {"I","2",[]}]}
  281. ],
  282. [{"A", "1", [{"D",[{"J",[]}]},
  283. {"E",[{"I","1",[]}]}]},
  284. {"B", "1", [{"F",[]},
  285. {"G",[]}]},
  286. {"C", "2", [{"H",[]}]}
  287. ],
  288. ["C"],
  289. {"B", [{"A","1"}, "D", "J", "E",
  290. {"B","1"}, "F", "G",
  291. {"C","1"}, "H", {"I","2"}]}};
  292. upgrades(tree_c) ->
  293. {[{"A", "1", [{"D",[{"J",[]}]},
  294. {"E",[{"I","1",[]}]}]},
  295. {"B", "1", [{"F",[]},
  296. {"G",[]}]},
  297. {"C", "1", [{"H",[]},
  298. {"I","2",[]}]}
  299. ],
  300. [{"A", "1", [{"D",[{"J",[]}]},
  301. {"E",[{"I","1",[]}]}]},
  302. {"B", "1", [{"F",[]},
  303. {"G",[]}]},
  304. {"C", "1", [{"H",[]}]}
  305. ],
  306. ["C","I"],
  307. {"C", [{"A","1"}, "D", "J", "E", {"I","1"},
  308. {"B","1"}, "F", "G",
  309. {"C","1"}, "H"]}};
  310. upgrades(tree_c2) ->
  311. {[{"A", "1", [{"D",[{"J",[]}]},
  312. {"E",[{"I","1",[]}]}]},
  313. {"B", "1", [{"F",[]},
  314. {"G",[]}]},
  315. {"C", "1", [{"H",[]},
  316. {"I","2",[]}]}
  317. ],
  318. [{"A", "1", [{"D",[{"J",[]}]},
  319. {"E",[{"I","1",[]}]}]},
  320. {"B", "1", [{"F",[]},
  321. {"G",[]}]},
  322. {"C", "1", [{"H",[{"K",[]}]},
  323. {"I","2",[]}]}
  324. ],
  325. ["C", "H"],
  326. {"C", [{"A","1"}, "D", "J", "E",
  327. {"B","1"}, "F", "G",
  328. {"C","1"}, "H", {"I", "2"}, "K"]}};
  329. upgrades(tree_cj) ->
  330. {[{"A", "1", [{"D",[{"J", "1",[]}]},
  331. {"E",[{"I","1",[]}]}]},
  332. {"B", "1", [{"F",[]},
  333. {"G",[]}]},
  334. {"C", "1", [{"H",[]},
  335. {"I","1",[]}]}
  336. ],
  337. [{"A", "1", [{"D",[{"J", "2", []}]},
  338. {"E",[{"I","1",[]}]}]},
  339. {"B", "1", [{"F",[]},
  340. {"G",[]}]},
  341. {"C", "1", [{"H",[]},
  342. {"I","1",[]}]}
  343. ],
  344. ["C","J"],
  345. {"C", [{"A","1"}, "D", {"J", "1"}, "E", {"I","1"},
  346. {"B","1"}, "F", "G",
  347. {"C","1"}, "H"]}};
  348. upgrades(tree_ac) ->
  349. {[{"A", "1", [{"D",[{"J",[]}]},
  350. {"E",[{"I","1",[]}]}]},
  351. {"B", "1", [{"F",[]},
  352. {"G",[]}]},
  353. {"C", "1", [{"H",[]},
  354. {"I","2",[]}]}
  355. ],
  356. [{"A", "1", [{"D",[{"J",[]}]},
  357. {"E",[{"I","1",[]}]}]},
  358. {"B", "1", [{"F",[]},
  359. {"G",[]}]},
  360. {"C", "1", [{"H",[]}]}
  361. ],
  362. ["C","I"],
  363. {"C, A", [{"A","1"}, "D", "J", "E", {"I","1"},
  364. {"B","1"}, "F", "G",
  365. {"C","1"}, "H"]}};
  366. upgrades(tree_all) ->
  367. {[{"A", "1", [{"D",[{"J",[]}]},
  368. {"E",[{"I","1",[]}]}]},
  369. {"B", "1", [{"F",[]},
  370. {"G",[]}]},
  371. {"C", "1", [{"H",[]},
  372. {"I","2",[]}]}
  373. ],
  374. [{"A", "1", [{"D",[{"J",[]}]},
  375. {"E",[{"I","1",[]}]}]},
  376. {"B", "1", [{"F",[]},
  377. {"G",[]}]},
  378. {"C", "1", [{"H",[]}]}
  379. ],
  380. ["C","I"],
  381. {"", [{"A","1"}, "D", "J", "E", {"I","1"},
  382. {"B","1"}, "F", "G",
  383. {"C","1"}, "H"]}};
  384. upgrades(delete_d) ->
  385. {[{"A", "1", [{"B", [{"D", "1", []}]},
  386. {"C", [{"D", "2", []}]}]}
  387. ],
  388. [{"A", "2", [{"B", []},
  389. {"C", []}]}
  390. ],
  391. ["A","B", "C"],
  392. %% upgrade vs. new tree
  393. {"", [{"A","2"}, "B", "C"]}};
  394. upgrades(promote) ->
  395. {[{"A", "1", [{"C", "1", []}]},
  396. {"B", "1", [{"D", "1", []}]}
  397. ],
  398. [{"A", "2", [{"C", "2", []}]},
  399. {"B", "2", [{"D", "2", []}]},
  400. {"C", "3", []}
  401. ],
  402. ["A","B","C","D"],
  403. {"C", [{"A","1"},{"C","3"},{"B","1"},{"D","1"}]}};
  404. upgrades(stable_lock) ->
  405. {[{"A", "1", [{"C", "1", []}]},
  406. {"B", "1", [{"D", "1", []}]}
  407. ], % lock after this
  408. [{"A", "2", [{"C", "2", []}]},
  409. {"B", "2", [{"D", "2", []}]}
  410. ],
  411. [],
  412. %% Run a regular lock and no app should be upgraded
  413. {"any", [{"A","1"},{"C","1"},{"B","1"},{"D","1"}]}};
  414. upgrades(fwd_lock) ->
  415. {[{"A", "1", [{"C", "1", []}]},
  416. {"B", "1", [{"D", "1", []}]}
  417. ],
  418. [{"A", "2", [{"C", "2", []}]},
  419. {"B", "2", [{"D", "2", []}]}
  420. ],
  421. ["A","B","C","D"],
  422. %% For this one, we should build, rewrite the lock
  423. %% file to include the result post-upgrade, and then
  424. %% run a regular lock to see that the lock file is respected
  425. %% in deps.
  426. {"any", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}};
  427. upgrades(compile_upgrade_parity) ->
  428. {[{"A", "1", [{"D",[{"J",[]}]},
  429. {"E",[{"I","1",[]}]}]},
  430. {"B", "1", [{"F",[]},
  431. {"G",[]}]},
  432. {"C", "1", [{"H",[]},
  433. {"I","2",[]}]}
  434. ],
  435. [],
  436. [],
  437. {"", [{"A","1"}, "D", "J", "E", {"I","1"},
  438. {"B","1"}, "F", "G",
  439. {"C","1"}, "H"]}};
  440. upgrades(umbrella_config) ->
  441. {[{"A", "1", []}],
  442. [{"A", "2", []}],
  443. ["A"],
  444. {"A", [{"A","2"}]}}.
  445. %% TODO: add a test that verifies that unlocking files and then
  446. %% running the upgrade code is enough to properly upgrade things.
  447. mock_deps(git, Deps, Upgrades) ->
  448. catch mock_git_resource:unmock(),
  449. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  450. mock_git_resource:mock([{deps, SrcDeps}, {upgrade, Upgrades}]);
  451. mock_deps(pkg, Deps, Upgrades) ->
  452. catch mock_pkg_resource:unmock(),
  453. {_, PkgDeps} = rebar_test_utils:flat_deps(Deps),
  454. mock_pkg_resource:mock([{pkgdeps, PkgDeps}, {upgrade, Upgrades}]).
  455. mock_deps(git, OldDeps, Deps, Upgrades) ->
  456. catch mock_git_resource:unmock(),
  457. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps++OldDeps),
  458. mock_git_resource:mock([{deps, SrcDeps}, {upgrade, Upgrades}]);
  459. mock_deps(pkg, OldDeps, Deps, Upgrades) ->
  460. catch mock_pkg_resource:unmock(),
  461. {_, PkgDeps} = rebar_test_utils:flat_deps(Deps++OldDeps),
  462. mock_pkg_resource:mock([{pkgdeps, PkgDeps}, {upgrade, Upgrades}]).
  463. normalize_unlocks({App, Locks}) ->
  464. {iolist_to_binary(App),
  465. normalize_unlocks_expect(Locks)};
  466. normalize_unlocks({App, Vsn, Locks}) ->
  467. {iolist_to_binary(App), iolist_to_binary(Vsn),
  468. normalize_unlocks_expect(Locks)}.
  469. normalize_unlocks_expect({error, Reason}) ->
  470. {error, Reason};
  471. normalize_unlocks_expect([]) ->
  472. [];
  473. normalize_unlocks_expect([{App,Vsn} | Rest]) ->
  474. [{dep, App, Vsn},
  475. {lock, App, Vsn}
  476. | normalize_unlocks_expect(Rest)];
  477. normalize_unlocks_expect([App | Rest]) ->
  478. [{dep, App},
  479. {lock, App} | normalize_unlocks_expect(Rest)].
  480. top_a(Config) -> run(Config).
  481. top_b(Config) -> run(Config).
  482. top_c(Config) -> run(Config).
  483. top_d1(Config) -> run(Config).
  484. top_d2(Config) -> run(Config).
  485. top_e(Config) -> run(Config).
  486. pair_a(Config) -> run(Config).
  487. pair_b(Config) -> run(Config).
  488. pair_ab(Config) -> run(Config).
  489. pair_c(Config) -> run(Config).
  490. pair_all(Config) -> run(Config).
  491. triplet_a(Config) -> run(Config).
  492. triplet_b(Config) -> run(Config).
  493. triplet_c(Config) -> run(Config).
  494. tree_a(Config) -> run(Config).
  495. tree_b(Config) -> run(Config).
  496. tree_c(Config) -> run(Config).
  497. tree_c2(Config) -> run(Config).
  498. tree_cj(Config) -> run(Config).
  499. tree_ac(Config) -> run(Config).
  500. tree_all(Config) -> run(Config).
  501. promote(Config) -> run(Config).
  502. delete_d(Config) ->
  503. meck:new(rebar_log, [no_link, passthrough]),
  504. run(Config),
  505. Infos = [{Str, Args}
  506. || {_, {rebar_log, log, [info, Str, Args]}, _} <- meck:history(rebar_log)],
  507. meck:unload(rebar_log),
  508. ?assertNotEqual([],
  509. [1 || {"App ~ts is no longer needed and can be deleted.",
  510. [<<"D">>]} <- Infos]).
  511. stable_lock(Config) ->
  512. apply(?config(mock, Config), []),
  513. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  514. %% Install dependencies before re-mocking for an upgrade
  515. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  516. {App, Unlocks} = ?config(expected, Config),
  517. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  518. Expectation = case Unlocks of
  519. {error, Term} -> {error, Term};
  520. _ -> {ok, Unlocks}
  521. end,
  522. apply(?config(mock_update, Config), []),
  523. NewRebarConf = rebar_test_utils:create_config(?config(apps, Config),
  524. [{deps, ?config(next_top_deps, Config)}]),
  525. {ok, NewRebarConfig} = file:consult(NewRebarConf),
  526. rebar_test_utils:run_and_check(
  527. Config, NewRebarConfig, ["lock", App], Expectation
  528. ).
  529. fwd_lock(Config) ->
  530. apply(?config(mock, Config), []),
  531. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  532. %% Install dependencies before re-mocking for an upgrade
  533. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  534. {App, Unlocks} = ?config(expected, Config),
  535. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  536. Expectation = case Unlocks of
  537. {error, Term} -> {error, Term};
  538. _ -> {ok, Unlocks}
  539. end,
  540. rewrite_locks(Expectation, Config),
  541. apply(?config(mock_update, Config), []),
  542. NewRebarConf = rebar_test_utils:create_config(?config(apps, Config),
  543. [{deps, ?config(next_top_deps, Config)}]),
  544. {ok, NewRebarConfig} = file:consult(NewRebarConf),
  545. rebar_test_utils:run_and_check(
  546. Config, NewRebarConfig, ["lock", App], Expectation
  547. ).
  548. compile_upgrade_parity(Config) ->
  549. AppDir = ?config(apps, Config),
  550. apply(?config(mock, Config), []),
  551. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  552. %% compiling and upgrading should generate the same lockfiles when
  553. %% deps are identical
  554. Lockfile = filename:join([AppDir, "rebar.lock"]),
  555. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, []}),
  556. {ok, CompileLockData1} = file:read_file(Lockfile),
  557. rebar_test_utils:run_and_check(Config, RebarConfig, ["upgrade"], {ok, []}),
  558. {ok, UpgradeLockData} = file:read_file(Lockfile),
  559. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, []}),
  560. {ok, CompileLockData2} = file:read_file(Lockfile),
  561. ?assertEqual(CompileLockData1, CompileLockData2),
  562. ?assertEqual(CompileLockData1, UpgradeLockData).
  563. umbrella_config(Config) ->
  564. apply(?config(mock, Config), []),
  565. {ok, TopConfig} = file:consult(?config(rebarconfig, Config)),
  566. %% Install dependencies before re-mocking for an upgrade
  567. rebar_test_utils:run_and_check(Config, TopConfig, ["lock"], {ok, []}),
  568. {App, Unlocks} = ?config(expected, Config),
  569. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  570. Expectation = case Unlocks of
  571. {error, Term} -> {error, Term};
  572. _ -> {ok, Unlocks}
  573. end,
  574. meck:new(rebar_prv_upgrade, [passthrough]),
  575. meck:expect(rebar_prv_upgrade, do, fun(S) ->
  576. apply(?config(mock_update, Config), []),
  577. meck:passthrough([S])
  578. end),
  579. _NewRebarConf = rebar_test_utils:create_config(filename:dirname(?config(rebarumbrella, Config)),
  580. [{deps, ?config(next_top_deps, Config)}]),
  581. %% re-run from the top-level with the old config still in place;
  582. %% detection must happen when going for umbrella apps!
  583. rebar_test_utils:run_and_check(
  584. Config, TopConfig, ["upgrade", App], Expectation
  585. ),
  586. meck:unload(rebar_prv_upgrade).
  587. run(Config) ->
  588. apply(?config(mock, Config), []),
  589. ConfigPath = ?config(rebarconfig, Config),
  590. {ok, RebarConfig} = file:consult(ConfigPath),
  591. %% Install dependencies before re-mocking for an upgrade
  592. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  593. {App, Unlocks} = ?config(expected, Config),
  594. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  595. Expectation = case Unlocks of
  596. {error, Term} -> {error, Term};
  597. _ -> {ok, Unlocks}
  598. end,
  599. meck:new(rebar_prv_upgrade, [passthrough]),
  600. meck:expect(rebar_prv_upgrade, do, fun(S) ->
  601. apply(?config(mock_update, Config), []),
  602. meck:passthrough([S])
  603. end),
  604. NewRebarConf = rebar_test_utils:create_config(filename:dirname(ConfigPath),
  605. [{deps, ?config(next_top_deps, Config)}]),
  606. {ok, NewRebarConfig} = file:consult(NewRebarConf),
  607. rebar_test_utils:run_and_check(
  608. Config, NewRebarConfig, ["upgrade", App], Expectation
  609. ),
  610. meck:unload(rebar_prv_upgrade).
  611. novsn_pkg(Config) ->
  612. apply(?config(mock, Config), []),
  613. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  614. %% Install dependencies before re-mocking for an upgrade
  615. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  616. Expectation = ?config(expected, Config),
  617. apply(?config(mock_update, Config), []),
  618. rebar_test_utils:run_and_check(
  619. Config, RebarConfig, ["upgrade"], Expectation
  620. ),
  621. ok.
  622. rewrite_locks({ok, Expectations}, Config) ->
  623. AppDir = ?config(apps, Config),
  624. LockFile = filename:join([AppDir, "rebar.lock"]),
  625. {ok, [Locks]} = file:consult(LockFile),
  626. ExpLocks = [{list_to_binary(Name), Vsn}
  627. || {lock, Name, Vsn} <- Expectations],
  628. NewLocks = lists:foldl(
  629. fun({App, {pkg, Name, _}, Lvl}, Acc) ->
  630. Vsn = list_to_binary(proplists:get_value(App,ExpLocks)),
  631. [{App, {pkg, Name, Vsn}, Lvl} | Acc]
  632. ; ({App, {git, URL, {ref, _}}, Lvl}, Acc) ->
  633. Vsn = proplists:get_value(App,ExpLocks),
  634. [{App, {git, URL, {ref, Vsn}}, Lvl} | Acc]
  635. end, [], Locks),
  636. ct:pal("rewriting locks from ~p to~n~p", [Locks, NewLocks]),
  637. file:write_file(LockFile, io_lib:format("~p.~n", [NewLocks])).