Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

331 wiersze
12 KiB

  1. -module(rebar_file_utils_SUITE).
  2. -export([all/0,
  3. groups/0,
  4. init_per_group/2,
  5. end_per_group/2,
  6. init_per_testcase/2,
  7. end_per_testcase/2,
  8. raw_tmpdir/1,
  9. empty_tmpdir/1,
  10. simple_tmpdir/1,
  11. multi_tmpdir/1,
  12. reset_nonexistent_dir/1,
  13. reset_empty_dir/1,
  14. reset_dir/1,
  15. path_from_ancestor/1,
  16. canonical_path/1,
  17. resolve_link/1,
  18. split_dirname/1,
  19. mv_warning_is_ignored/1,
  20. mv_dir/1,
  21. mv_file_same/1,
  22. mv_file_diff/1,
  23. mv_file_dir_same/1,
  24. mv_file_dir_diff/1,
  25. mv_no_clobber/1]).
  26. -include_lib("common_test/include/ct.hrl").
  27. -include_lib("eunit/include/eunit.hrl").
  28. -include_lib("kernel/include/file.hrl").
  29. all() ->
  30. [{group, tmpdir},
  31. {group, reset_dir},
  32. {group, mv},
  33. path_from_ancestor,
  34. canonical_path,
  35. resolve_link,
  36. split_dirname,
  37. mv_warning_is_ignored].
  38. groups() ->
  39. [{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]},
  40. {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]},
  41. {mv, [], [mv_dir, mv_file_same, mv_file_diff,
  42. mv_file_dir_same, mv_file_dir_diff, mv_no_clobber]}].
  43. init_per_group(reset_dir, Config) ->
  44. TmpDir = rebar_file_utils:system_tmpdir(["rebar_file_utils_SUITE", "resetable"]),
  45. [{tmpdir, TmpDir}|Config];
  46. init_per_group(_, Config) -> Config.
  47. end_per_group(_, Config) -> Config.
  48. init_per_testcase(Test, Config) ->
  49. case os:type() of
  50. {win32, _} ->
  51. case lists:member(Test, [resolve_link, mv_warning_is_ignored]) of
  52. true -> {skip, "broken in windows"};
  53. false -> Config
  54. end;
  55. _ ->
  56. Config
  57. end.
  58. end_per_testcase(_Test, Config) ->
  59. Config.
  60. raw_tmpdir(_Config) ->
  61. case rebar_file_utils:system_tmpdir() of
  62. "/tmp" -> ok;
  63. "./tmp" -> ok
  64. end.
  65. empty_tmpdir(_Config) ->
  66. case rebar_file_utils:system_tmpdir([]) of
  67. "/tmp" -> ok;
  68. "./tmp" -> ok
  69. end.
  70. simple_tmpdir(_Config) ->
  71. case rebar_file_utils:system_tmpdir(["test"]) of
  72. "/tmp/test" -> ok;
  73. "./tmp/test" -> ok
  74. end.
  75. multi_tmpdir(_Config) ->
  76. case rebar_file_utils:system_tmpdir(["a", "b", "c"]) of
  77. "/tmp/a/b/c" -> ok;
  78. "./tmp/a/b/c" -> ok
  79. end.
  80. reset_nonexistent_dir(Config) ->
  81. TmpDir = ?config(tmpdir, Config),
  82. _ = ec_file:remove(TmpDir, [recursive]),
  83. ?assertNot(filelib:is_dir(TmpDir)),
  84. ok = rebar_file_utils:reset_dir(TmpDir),
  85. ?assert(filelib:is_dir(TmpDir)),
  86. {ok, []} = rebar_utils:list_dir(TmpDir).
  87. reset_empty_dir(Config) ->
  88. TmpDir = ?config(tmpdir, Config),
  89. _ = ec_file:remove(TmpDir, [recursive]),
  90. _ = filelib:ensure_dir(filename:join([TmpDir, "dummy.beam"])),
  91. ?assert(filelib:is_dir(TmpDir)),
  92. ok = rebar_file_utils:reset_dir(TmpDir),
  93. ?assert(filelib:is_dir(TmpDir)),
  94. {ok, []} = rebar_utils:list_dir(TmpDir).
  95. reset_dir(Config) ->
  96. TmpDir = ?config(tmpdir, Config),
  97. _ = ec_file:remove(TmpDir, [recursive]),
  98. _ = filelib:ensure_dir(filename:join([TmpDir, "dummy.beam"])),
  99. ?assert(filelib:is_dir(TmpDir)),
  100. lists:foreach(fun(Name) -> file:write_file(filename:join([TmpDir, Name]), <<>>) end,
  101. ["a", "b", "c"]),
  102. lists:foreach(fun(File) -> ?assert(filelib:is_file(filename:join([TmpDir, File]))) end,
  103. ["a", "b", "c"]),
  104. ok = rebar_file_utils:reset_dir(TmpDir),
  105. ?assert(filelib:is_dir(TmpDir)),
  106. {ok, []} = rebar_utils:list_dir(TmpDir).
  107. path_from_ancestor(_Config) ->
  108. ?assertEqual({ok, "foo/bar/baz"}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/")),
  109. ?assertEqual({ok, "bar/baz"}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/foo")),
  110. ?assertEqual({ok, "bar"}, rebar_file_utils:path_from_ancestor("foo/bar", "foo")),
  111. ?assertEqual({ok, "bar"}, rebar_file_utils:path_from_ancestor("foo/bar/", "foo/")),
  112. ?assertEqual({error, badparent}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/qux")),
  113. ?assertEqual({error, badparent}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/foo/bar/baz/qux")).
  114. canonical_path(_Config) ->
  115. %% We find the root so that the name works both on unix-likes and
  116. %% with Windows.
  117. Root = case os:type() of
  118. {win32, _} -> filename:nativename(filename:absname("/")); % C:\, with proper drive
  119. _ -> "/"
  120. end,
  121. ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/")),
  122. ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/../../..")),
  123. ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/bar/..")),
  124. ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/../foo")),
  125. ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/.")),
  126. ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/./.")),
  127. ?assertEqual(filename:nativename(Root ++ "foo/bar"),
  128. rebar_file_utils:canonical_path("/foo/./bar")).
  129. resolve_link(_Config) ->
  130. TmpDir = rebar_file_utils:system_tmpdir(
  131. ["rebar_file_utils_SUITE", "resolve_link"]),
  132. Link = filename:join(TmpDir, "link"),
  133. Target = filename:join(TmpDir, "link-target"),
  134. ec_file:remove(TmpDir, [recursive]),
  135. ok = filelib:ensure_dir(Target),
  136. ok = file:write_file(Target, <<>>),
  137. ok = file:make_symlink(Target, Link),
  138. ?assertEqual(Target, rebar_file_utils:resolve_link(Link)).
  139. split_dirname(_Config) ->
  140. ?assertEqual({".", ""}, rebar_file_utils:split_dirname("")),
  141. ?assertEqual({"/", ""}, rebar_file_utils:split_dirname("/")),
  142. ?assertEqual({"/", "foo"}, rebar_file_utils:split_dirname("/foo")),
  143. ?assertEqual({".", "foo"}, rebar_file_utils:split_dirname("foo")),
  144. ?assertEqual({"/foo", "bar"}, rebar_file_utils:split_dirname("/foo/bar")),
  145. ?assertEqual({"foo", "bar"}, rebar_file_utils:split_dirname("foo/bar")).
  146. mv_warning_is_ignored(_Config) ->
  147. meck:new(rebar_utils, [passthrough]),
  148. meck:expect(rebar_utils, sh, fun("mv ding dong", _) -> {ok, "Warning"} end),
  149. ok = rebar_file_utils:mv("ding", "dong"),
  150. meck:unload(rebar_utils).
  151. %%% Ensure Windows & Unix operations to move files
  152. mv_dir(Config) ->
  153. %% Move a directory to another one location
  154. PrivDir = ?config(priv_dir, Config),
  155. BaseDir = mk_base_dir(PrivDir, mv_dir),
  156. SrcDir = filename:join(BaseDir, "src/"),
  157. ec_file:mkdir_p(SrcDir),
  158. ?assert(filelib:is_dir(SrcDir)),
  159. %% empty dir movement
  160. DstDir1 = filename:join(BaseDir, "dst1/"),
  161. ?assertNot(filelib:is_dir(DstDir1)),
  162. ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir1)),
  163. ?assert(filelib:is_dir(DstDir1)),
  164. %% move files from dir to empty dir
  165. F1 = filename:join(SrcDir, "file1"),
  166. F2 = filename:join(SrcDir, "subdir/file2"),
  167. filelib:ensure_dir(F2),
  168. file:write_file(F1, "hello"),
  169. file:write_file(F2, "world"),
  170. DstDir2 = filename:join(BaseDir, "dst2/"),
  171. D2F1 = filename:join(DstDir2, "file1"),
  172. D2F2 = filename:join(DstDir2, "subdir/file2"),
  173. ?assertNot(filelib:is_dir(DstDir2)),
  174. ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir2)),
  175. ?assert(filelib:is_file(D2F1)),
  176. ?assert(filelib:is_file(D2F2)),
  177. %% move files from dir to existing dir moves it to
  178. %% a subdir
  179. filelib:ensure_dir(F2),
  180. file:write_file(F1, "hello"),
  181. file:write_file(F2, "world"),
  182. DstDir3 = filename:join(BaseDir, "dst3/"),
  183. D3F1 = filename:join(DstDir3, "src/file1"),
  184. D3F2 = filename:join(DstDir3, "src/subdir/file2"),
  185. ec_file:mkdir_p(DstDir3),
  186. ?assert(filelib:is_dir(DstDir3)),
  187. ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir3)),
  188. ?assertNot(filelib:is_file(F1)),
  189. ?assertNot(filelib:is_file(F2)),
  190. ?assert(filelib:is_file(D3F1)),
  191. ?assert(filelib:is_file(D3F2)),
  192. ?assertNot(filelib:is_dir(SrcDir)),
  193. ok.
  194. mv_file_same(Config) ->
  195. %% Move a file from a directory to the other without renaming
  196. PrivDir = ?config(priv_dir, Config),
  197. BaseDir = mk_base_dir(PrivDir, mv_file_same),
  198. SrcDir = filename:join(BaseDir, "src/"),
  199. ec_file:mkdir_p(SrcDir),
  200. ?assert(filelib:is_dir(SrcDir)),
  201. F = filename:join(SrcDir, "file"),
  202. file:write_file(F, "hello"),
  203. DstDir = filename:join(BaseDir, "dst/"),
  204. ec_file:mkdir_p(DstDir),
  205. Dst = filename:join(DstDir, "file"),
  206. ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
  207. ?assert(filelib:is_file(Dst)),
  208. ?assertNot(filelib:is_file(F)),
  209. ok.
  210. mv_file_diff(Config) ->
  211. %% Move a file from a directory to another one while renaming
  212. %% into a pre-existing file
  213. PrivDir = ?config(priv_dir, Config),
  214. BaseDir = mk_base_dir(PrivDir, mv_file_diff),
  215. SrcDir = filename:join(BaseDir, "src/"),
  216. ec_file:mkdir_p(SrcDir),
  217. ?assert(filelib:is_dir(SrcDir)),
  218. F = filename:join(SrcDir, "file"),
  219. file:write_file(F, "hello"),
  220. DstDir = filename:join(BaseDir, "dst/"),
  221. ec_file:mkdir_p(DstDir),
  222. Dst = filename:join(DstDir, "file-rename"),
  223. file:write_file(Dst, "not-the-right-content"),
  224. ?assert(filelib:is_file(Dst)),
  225. ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
  226. ?assert(filelib:is_file(Dst)),
  227. ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)),
  228. ?assertNot(filelib:is_file(F)),
  229. ok.
  230. mv_file_dir_same(Config) ->
  231. %% Move a file to a directory without renaming
  232. PrivDir = ?config(priv_dir, Config),
  233. BaseDir = mk_base_dir(PrivDir, mv_file_dir_same),
  234. SrcDir = filename:join(BaseDir, "src/"),
  235. ec_file:mkdir_p(SrcDir),
  236. ?assert(filelib:is_dir(SrcDir)),
  237. F = filename:join(SrcDir, "file"),
  238. file:write_file(F, "hello"),
  239. DstDir = filename:join(BaseDir, "dst/"),
  240. ec_file:mkdir_p(DstDir),
  241. Dst = filename:join(DstDir, "file"),
  242. ?assert(filelib:is_dir(DstDir)),
  243. ?assertEqual(ok, rebar_file_utils:mv(F, DstDir)),
  244. ?assert(filelib:is_file(Dst)),
  245. ?assertNot(filelib:is_file(F)),
  246. ok.
  247. mv_file_dir_diff(Config) ->
  248. %% Move a file to a directory while renaming
  249. PrivDir = ?config(priv_dir, Config),
  250. BaseDir = mk_base_dir(PrivDir, mv_file_dir_diff),
  251. SrcDir = filename:join(BaseDir, "src/"),
  252. ec_file:mkdir_p(SrcDir),
  253. ?assert(filelib:is_dir(SrcDir)),
  254. F = filename:join(SrcDir, "file"),
  255. file:write_file(F, "hello"),
  256. DstDir = filename:join(BaseDir, "dst/"),
  257. ec_file:mkdir_p(DstDir),
  258. Dst = filename:join(DstDir, "file-rename"),
  259. ?assert(filelib:is_dir(DstDir)),
  260. ?assertNot(filelib:is_file(Dst)),
  261. ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
  262. ?assert(filelib:is_file(Dst)),
  263. ?assertNot(filelib:is_file(F)),
  264. ok.
  265. mv_no_clobber(Config) ->
  266. %% Moving a file while renaming does not clobber other files
  267. PrivDir = ?config(priv_dir, Config),
  268. BaseDir = mk_base_dir(PrivDir, mv_no_clobber),
  269. SrcDir = filename:join(BaseDir, "src/"),
  270. ec_file:mkdir_p(SrcDir),
  271. ?assert(filelib:is_dir(SrcDir)),
  272. F = filename:join(SrcDir, "file"),
  273. file:write_file(F, "hello"),
  274. FBad = filename:join(SrcDir, "file-alt"),
  275. file:write_file(FBad, "wrong-data"),
  276. DstDir = filename:join(BaseDir, "dst/"),
  277. ec_file:mkdir_p(DstDir),
  278. Dst = filename:join(DstDir, "file-alt"),
  279. DstBad = filename:join(DstDir, "file"),
  280. file:write_file(DstBad, "wrong-data"),
  281. ?assert(filelib:is_file(F)),
  282. ?assert(filelib:is_file(FBad)),
  283. ?assert(filelib:is_dir(DstDir)),
  284. ?assertNot(filelib:is_file(Dst)),
  285. ?assert(filelib:is_file(DstBad)),
  286. ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
  287. ?assert(filelib:is_file(Dst)),
  288. ?assertNot(filelib:is_file(F)),
  289. ?assert(filelib:is_file(DstBad)),
  290. ?assert(filelib:is_file(FBad)),
  291. ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)),
  292. ?assertEqual({ok, <<"wrong-data">>}, file:read_file(FBad)),
  293. ?assertEqual({ok, <<"wrong-data">>}, file:read_file(DstBad)),
  294. ok.
  295. mk_base_dir(BasePath, Name) ->
  296. {_,_,Micro} = os:timestamp(),
  297. Index = integer_to_list(Micro),
  298. Path = filename:join(BasePath, atom_to_list(Name) ++ Index),
  299. ec_file:mkdir_p(Path),
  300. Path.