Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

567 řádky
19 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_ac, tree_all,
  11. delete_d, promote, stable_lock, fwd_lock]},
  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(novsn_pkg, Config0) ->
  28. Config = rebar_test_utils:init_rebar_state(Config0, "novsn_pkg_"),
  29. AppDir = ?config(apps, Config),
  30. RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [fakeapp]}]),
  31. Deps = [{{<<"fakeapp">>, <<"1.0.0">>}, []}],
  32. UpDeps = [{{<<"fakeapp">>, <<"1.1.0">>}, []}],
  33. Upgrades = ["fakeapp"],
  34. [{rebarconfig, RebarConf},
  35. {mock, fun() ->
  36. catch mock_pkg_resource:unmock(),
  37. mock_pkg_resource:mock([{pkgdeps, Deps}, {upgrade, []}])
  38. end},
  39. {mock_update, fun() ->
  40. catch mock_pkg_resource:unmock(),
  41. mock_pkg_resource:mock([{pkgdeps, UpDeps}, {upgrade, Upgrades}])
  42. end},
  43. {expected, {ok, [{dep, "fakeapp", "1.1.0"}, {lock, "fakeapp", "1.1.0"}]}}
  44. | Config];
  45. init_per_testcase(Case, Config) ->
  46. DepsType = ?config(deps_type, Config),
  47. {Deps, UpDeps, ToUp, Expectations} = upgrades(Case),
  48. Expanded = rebar_test_utils:expand_deps(DepsType, Deps),
  49. UpExpanded = rebar_test_utils:expand_deps(DepsType, UpDeps),
  50. [{expected, normalize_unlocks(Expectations)},
  51. {mock, fun() -> mock_deps(DepsType, Expanded, []) end},
  52. {mock_update, fun() -> mock_deps(DepsType, Expanded, UpExpanded, ToUp) end}
  53. | setup_project(Case, Config, Expanded, UpExpanded)].
  54. end_per_testcase(_, Config) ->
  55. meck:unload(),
  56. Config.
  57. setup_project(Case, Config0, Deps, UpDeps) ->
  58. DepsType = ?config(deps_type, Config0),
  59. Config = rebar_test_utils:init_rebar_state(
  60. Config0,
  61. atom_to_list(Case)++"_"++atom_to_list(DepsType)++"_"
  62. ),
  63. AppDir = ?config(apps, Config),
  64. rebar_test_utils:create_app(AppDir, "Root", "0.0.0", [kernel, stdlib]),
  65. TopDeps = rebar_test_utils:top_level_deps(Deps),
  66. RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
  67. [{rebarconfig, RebarConf},
  68. {next_top_deps, rebar_test_utils:top_level_deps(UpDeps)} | Config].
  69. upgrades(top_a) ->
  70. %% Original tree
  71. {[{"A", "1", [{"B", [{"D", "1", []}]},
  72. {"C", [{"D", "2", []}]}]}
  73. ],
  74. %% Updated tree
  75. [{"A", "1", [{"B", [{"D", "3", []}]},
  76. {"C", [{"D", "2", []}]}]}
  77. ],
  78. %% Modified apps, gobally
  79. ["A","B","D"],
  80. %% upgrade vs. new tree
  81. {"A", [{"A","1"}, "B", "C", {"D","3"}]}};
  82. upgrades(top_b) ->
  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. {"B", {error, {rebar_prv_upgrade, {transitive_dependency, <<"B">>}}}}};
  95. upgrades(top_c) ->
  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. {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}};
  108. upgrades(top_d1) ->
  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. {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}};
  121. upgrades(top_d2) ->
  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_e) ->
  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. {"E", {error, {rebar_prv_upgrade, {unknown_dependency, <<"E">>}}}}};
  147. upgrades(pair_a) ->
  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", [{"A","2"},{"C","2"},{"B","1"},{"D","1"}]}};
  156. upgrades(pair_b) ->
  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. {"B", [{"A","1"},{"C","1"},{"B","2"},{"D","2"}]}};
  165. upgrades(pair_ab) ->
  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,B", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}};
  174. upgrades(pair_c) ->
  175. {[{"A", "1", [{"C", "1", []}]},
  176. {"B", "1", [{"D", "1", []}]}
  177. ],
  178. [{"A", "2", [{"C", "2", []}]},
  179. {"B", "2", [{"D", "2", []}]}
  180. ],
  181. ["A","B","C","D"],
  182. {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}};
  183. upgrades(pair_all) ->
  184. {[{"A", "1", [{"C", "1", []}]},
  185. {"B", "1", [{"D", "1", []}]}
  186. ],
  187. [{"A", "2", [{"C", "2", []}]},
  188. {"B", "2", [{"D", "2", []}]}
  189. ],
  190. ["A","B","C","D"],
  191. {"", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}};
  192. upgrades(triplet_a) ->
  193. {[{"A", "1", [{"D",[]},
  194. {"E","3",[]}]},
  195. {"B", "1", [{"F","1",[]},
  196. {"G",[]}]},
  197. {"C", "0", [{"H","3",[]},
  198. {"I",[]}]}],
  199. [{"A", "1", [{"D",[]},
  200. {"E","2",[]}]},
  201. {"B", "1", [{"F","1",[]},
  202. {"G",[]}]},
  203. {"C", "1", [{"H","4",[]},
  204. {"I",[]}]}],
  205. ["A","C","E","H"],
  206. {"A", [{"A","1"}, "D", {"E","2"},
  207. {"B","1"}, {"F","1"}, "G",
  208. {"C","0"}, {"H","3"}, "I"]}};
  209. upgrades(triplet_b) ->
  210. {[{"A", "1", [{"D",[]},
  211. {"E","3",[]}]},
  212. {"B", "1", [{"F","1",[]},
  213. {"G",[]}]},
  214. {"C", "0", [{"H","3",[]},
  215. {"I",[]}]}],
  216. [{"A", "2", [{"D",[]},
  217. {"E","2",[]}]},
  218. {"B", "1", [{"F","1",[]},
  219. {"G",[]}]},
  220. {"C", "1", [{"H","4",[]},
  221. {"I",[]}]}],
  222. ["A","C","E","H"],
  223. {"B", [{"A","1"}, "D", {"E","3"},
  224. {"B","1"}, {"F","1"}, "G",
  225. {"C","0"}, {"H","3"}, "I"]}};
  226. upgrades(triplet_c) ->
  227. {[{"A", "1", [{"D",[]},
  228. {"E","3",[]}]},
  229. {"B", "1", [{"F","1",[]},
  230. {"G",[]}]},
  231. {"C", "0", [{"H","3",[]},
  232. {"I",[]}]}],
  233. [{"A", "2", [{"D",[]},
  234. {"E","2",[]}]},
  235. {"B", "1", [{"F","1",[]},
  236. {"G",[]}]},
  237. {"C", "1", [{"H","4",[]},
  238. {"I",[]}]}],
  239. ["A","C","E","H"],
  240. {"C", [{"A","1"}, "D", {"E","3"},
  241. {"B","1"}, {"F","1"}, "G",
  242. {"C","1"}, {"H","4"}, "I"]}};
  243. upgrades(tree_a) ->
  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. {"A", [{"A","1"}, "D", "J", "E",
  259. {"B","1"}, "F", "G",
  260. {"C","1"}, "H", {"I","2"}]}};
  261. upgrades(tree_b) ->
  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", "2", [{"H",[]}]}
  274. ],
  275. ["C"],
  276. {"B", [{"A","1"}, "D", "J", "E",
  277. {"B","1"}, "F", "G",
  278. {"C","1"}, "H", {"I","2"}]}};
  279. upgrades(tree_c) ->
  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",[]}]}
  292. ],
  293. ["C","I"],
  294. {"C", [{"A","1"}, "D", "J", "E", {"I","1"},
  295. {"B","1"}, "F", "G",
  296. {"C","1"}, "H"]}};
  297. upgrades(tree_c2) ->
  298. {[{"A", "1", [{"D",[{"J",[]}]},
  299. {"E",[{"I","1",[]}]}]},
  300. {"B", "1", [{"F",[]},
  301. {"G",[]}]},
  302. {"C", "1", [{"H",[]},
  303. {"I","2",[]}]}
  304. ],
  305. [{"A", "1", [{"D",[{"J",[]}]},
  306. {"E",[{"I","1",[]}]}]},
  307. {"B", "1", [{"F",[]},
  308. {"G",[]}]},
  309. {"C", "1", [{"H",[{"K",[]}]},
  310. {"I","2",[]}]}
  311. ],
  312. ["C", "H"],
  313. {"C", [{"A","1"}, "D", "J", "E",
  314. {"B","1"}, "F", "G",
  315. {"C","1"}, "H", {"I", "2"}, "K"]}};
  316. upgrades(tree_ac) ->
  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. {"C, A", [{"A","1"}, "D", "J", "E", {"I","1"},
  332. {"B","1"}, "F", "G",
  333. {"C","1"}, "H"]}};
  334. upgrades(tree_all) ->
  335. {[{"A", "1", [{"D",[{"J",[]}]},
  336. {"E",[{"I","1",[]}]}]},
  337. {"B", "1", [{"F",[]},
  338. {"G",[]}]},
  339. {"C", "1", [{"H",[]},
  340. {"I","2",[]}]}
  341. ],
  342. [{"A", "1", [{"D",[{"J",[]}]},
  343. {"E",[{"I","1",[]}]}]},
  344. {"B", "1", [{"F",[]},
  345. {"G",[]}]},
  346. {"C", "1", [{"H",[]}]}
  347. ],
  348. ["C","I"],
  349. {"", [{"A","1"}, "D", "J", "E", {"I","1"},
  350. {"B","1"}, "F", "G",
  351. {"C","1"}, "H"]}};
  352. upgrades(delete_d) ->
  353. {[{"A", "1", [{"B", [{"D", "1", []}]},
  354. {"C", [{"D", "2", []}]}]}
  355. ],
  356. [{"A", "2", [{"B", []},
  357. {"C", []}]}
  358. ],
  359. ["A","B", "C"],
  360. %% upgrade vs. new tree
  361. {"", [{"A","2"}, "B", "C"]}};
  362. upgrades(promote) ->
  363. {[{"A", "1", [{"C", "1", []}]},
  364. {"B", "1", [{"D", "1", []}]}
  365. ],
  366. [{"A", "2", [{"C", "2", []}]},
  367. {"B", "2", [{"D", "2", []}]},
  368. {"C", "3", []}
  369. ],
  370. ["A","B","C","D"],
  371. {"C", [{"A","1"},{"C","3"},{"B","1"},{"D","1"}]}};
  372. upgrades(stable_lock) ->
  373. {[{"A", "1", [{"C", "1", []}]},
  374. {"B", "1", [{"D", "1", []}]}
  375. ], % lock after this
  376. [{"A", "2", [{"C", "2", []}]},
  377. {"B", "2", [{"D", "2", []}]}
  378. ],
  379. [],
  380. %% Run a regular lock and no app should be upgraded
  381. {"any", [{"A","1"},{"C","1"},{"B","1"},{"D","1"}]}};
  382. upgrades(fwd_lock) ->
  383. {[{"A", "1", [{"C", "1", []}]},
  384. {"B", "1", [{"D", "1", []}]}
  385. ],
  386. [{"A", "2", [{"C", "2", []}]},
  387. {"B", "2", [{"D", "2", []}]}
  388. ],
  389. ["A","B","C","D"],
  390. %% For this one, we should build, rewrite the lock
  391. %% file to include the result post-upgrade, and then
  392. %% run a regular lock to see that the lock file is respected
  393. %% in deps.
  394. {"any", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}}.
  395. %% TODO: add a test that verifies that unlocking files and then
  396. %% running the upgrade code is enough to properly upgrade things.
  397. mock_deps(git, Deps, Upgrades) ->
  398. catch mock_git_resource:unmock(),
  399. mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}, {upgrade, Upgrades}]);
  400. mock_deps(pkg, Deps, Upgrades) ->
  401. catch mock_pkg_resource:unmock(),
  402. mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}, {upgrade, Upgrades}]).
  403. mock_deps(git, _OldDeps, Deps, Upgrades) ->
  404. catch mock_git_resource:unmock(),
  405. mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}, {upgrade, Upgrades}]);
  406. mock_deps(pkg, OldDeps, Deps, Upgrades) ->
  407. Merged = Deps ++ [Dep || Dep <- OldDeps,
  408. not lists:keymember(element(1, Dep), 1, Deps)],
  409. catch mock_pkg_resource:unmock(),
  410. mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Merged)}, {upgrade, Upgrades}]).
  411. normalize_unlocks({App, Locks}) ->
  412. {iolist_to_binary(App),
  413. normalize_unlocks_expect(Locks)};
  414. normalize_unlocks({App, Vsn, Locks}) ->
  415. {iolist_to_binary(App), iolist_to_binary(Vsn),
  416. normalize_unlocks_expect(Locks)}.
  417. normalize_unlocks_expect({error, Reason}) ->
  418. {error, Reason};
  419. normalize_unlocks_expect([]) ->
  420. [];
  421. normalize_unlocks_expect([{App,Vsn} | Rest]) ->
  422. [{dep, App, Vsn},
  423. {lock, App, Vsn}
  424. | normalize_unlocks_expect(Rest)];
  425. normalize_unlocks_expect([App | Rest]) ->
  426. [{dep, App},
  427. {lock, App} | normalize_unlocks_expect(Rest)].
  428. top_a(Config) -> run(Config).
  429. top_b(Config) -> run(Config).
  430. top_c(Config) -> run(Config).
  431. top_d1(Config) -> run(Config).
  432. top_d2(Config) -> run(Config).
  433. top_e(Config) -> run(Config).
  434. pair_a(Config) -> run(Config).
  435. pair_b(Config) -> run(Config).
  436. pair_ab(Config) -> run(Config).
  437. pair_c(Config) -> run(Config).
  438. pair_all(Config) -> run(Config).
  439. triplet_a(Config) -> run(Config).
  440. triplet_b(Config) -> run(Config).
  441. triplet_c(Config) -> run(Config).
  442. tree_a(Config) -> run(Config).
  443. tree_b(Config) -> run(Config).
  444. tree_c(Config) -> run(Config).
  445. tree_c2(Config) -> run(Config).
  446. tree_ac(Config) -> run(Config).
  447. tree_all(Config) -> run(Config).
  448. promote(Config) -> run(Config).
  449. delete_d(Config) ->
  450. meck:new(rebar_log, [no_link, passthrough]),
  451. run(Config),
  452. Infos = [{Str, Args}
  453. || {_, {rebar_log, log, [info, Str, Args]}, _} <- meck:history(rebar_log)],
  454. meck:unload(rebar_log),
  455. ?assertNotEqual([],
  456. [1 || {"App ~ts is no longer needed and can be deleted.",
  457. [<<"D">>]} <- Infos]).
  458. stable_lock(Config) ->
  459. apply(?config(mock, Config), []),
  460. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  461. %% Install dependencies before re-mocking for an upgrade
  462. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  463. {App, Unlocks} = ?config(expected, Config),
  464. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  465. Expectation = case Unlocks of
  466. {error, Term} -> {error, Term};
  467. _ -> {ok, Unlocks}
  468. end,
  469. apply(?config(mock_update, Config), []),
  470. NewRebarConf = rebar_test_utils:create_config(?config(apps, Config),
  471. [{deps, ?config(next_top_deps, Config)}]),
  472. {ok, NewRebarConfig} = file:consult(NewRebarConf),
  473. rebar_test_utils:run_and_check(
  474. Config, NewRebarConfig, ["lock", App], Expectation
  475. ).
  476. fwd_lock(Config) ->
  477. apply(?config(mock, Config), []),
  478. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  479. %% Install dependencies before re-mocking for an upgrade
  480. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  481. {App, Unlocks} = ?config(expected, Config),
  482. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  483. Expectation = case Unlocks of
  484. {error, Term} -> {error, Term};
  485. _ -> {ok, Unlocks}
  486. end,
  487. rewrite_locks(Expectation, Config),
  488. apply(?config(mock_update, Config), []),
  489. NewRebarConf = rebar_test_utils:create_config(?config(apps, Config),
  490. [{deps, ?config(next_top_deps, Config)}]),
  491. {ok, NewRebarConfig} = file:consult(NewRebarConf),
  492. rebar_test_utils:run_and_check(
  493. Config, NewRebarConfig, ["lock", App], Expectation
  494. ).
  495. run(Config) ->
  496. apply(?config(mock, Config), []),
  497. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  498. %% Install dependencies before re-mocking for an upgrade
  499. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  500. {App, Unlocks} = ?config(expected, Config),
  501. ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]),
  502. Expectation = case Unlocks of
  503. {error, Term} -> {error, Term};
  504. _ -> {ok, Unlocks}
  505. end,
  506. apply(?config(mock_update, Config), []),
  507. NewRebarConf = rebar_test_utils:create_config(?config(apps, Config),
  508. [{deps, ?config(next_top_deps, Config)}]),
  509. {ok, NewRebarConfig} = file:consult(NewRebarConf),
  510. rebar_test_utils:run_and_check(
  511. Config, NewRebarConfig, ["upgrade", App], Expectation
  512. ).
  513. novsn_pkg(Config) ->
  514. apply(?config(mock, Config), []),
  515. {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
  516. %% Install dependencies before re-mocking for an upgrade
  517. rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}),
  518. Expectation = ?config(expected, Config),
  519. apply(?config(mock_update, Config), []),
  520. rebar_test_utils:run_and_check(
  521. Config, RebarConfig, ["upgrade"], Expectation
  522. ),
  523. ok.
  524. rewrite_locks({ok, Expectations}, Config) ->
  525. AppDir = ?config(apps, Config),
  526. LockFile = filename:join([AppDir, "rebar.lock"]),
  527. {ok, [Locks]} = file:consult(LockFile),
  528. ExpLocks = [{list_to_binary(Name), Vsn}
  529. || {lock, Name, Vsn} <- Expectations],
  530. NewLocks = lists:foldl(
  531. fun({App, {pkg, Name, _}, Lvl}, Acc) ->
  532. Vsn = list_to_binary(proplists:get_value(App,ExpLocks)),
  533. [{App, {pkg, Name, Vsn}, Lvl} | Acc]
  534. ; ({App, {git, URL, {ref, _}}, Lvl}, Acc) ->
  535. Vsn = proplists:get_value(App,ExpLocks),
  536. [{App, {git, URL, {ref, Vsn}}, Lvl} | Acc]
  537. end, [], Locks),
  538. ct:pal("rewriting locks from ~p to~n~p", [Locks, NewLocks]),
  539. file:write_file(LockFile, io_lib:format("~p.~n", [NewLocks])).