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

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