From 92e6997cf128382f7596fcc546caceee9d10a428 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 27 Jan 2017 10:56:22 -0500 Subject: Fix mv command on windows Requires changing a bunch of arguments for xerocopy since it does not allow to rename while copying. Lots of tests added --- test/rebar_file_utils_SUITE.erl | 186 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl index 7285e13..949001d 100644 --- a/test/rebar_file_utils_SUITE.erl +++ b/test/rebar_file_utils_SUITE.erl @@ -4,6 +4,8 @@ groups/0, init_per_group/2, end_per_group/2, + init_per_testcase/2, + end_per_testcase/2, raw_tmpdir/1, empty_tmpdir/1, simple_tmpdir/1, @@ -15,7 +17,13 @@ canonical_path/1, resolve_link/1, split_dirname/1, - mv_warning_is_ignored/1]). + mv_warning_is_ignored/1, + mv_dir/1, + mv_file_same/1, + mv_file_diff/1, + mv_file_dir_same/1, + mv_file_dir_diff/1, + mv_no_clobber/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -25,6 +33,7 @@ all() -> [{group, tmpdir}, {group, reset_dir}, + {group, mv}, path_from_ancestor, canonical_path, resolve_link, @@ -33,7 +42,9 @@ all() -> groups() -> [{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]}, - {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]}]. + {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]}, + {mv, [], [mv_dir, mv_file_same, mv_file_diff, + mv_file_dir_same, mv_file_dir_diff, mv_no_clobber]}]. init_per_group(reset_dir, Config) -> TmpDir = rebar_file_utils:system_tmpdir(["rebar_file_utils_SUITE", "resetable"]), @@ -41,6 +52,20 @@ init_per_group(reset_dir, Config) -> init_per_group(_, Config) -> Config. end_per_group(_, Config) -> Config. +init_per_testcase(Test, Config) -> + case os:type() of + {win32, _} -> + case lists:member(Test, [resolve_link, mv_warning_is_ignored]) of + true -> {skip, "broken in windows"}; + false -> Config + end; + _ -> + Config + end. + +end_per_testcase(_Test, Config) -> + Config. + raw_tmpdir(_Config) -> case rebar_file_utils:system_tmpdir() of "/tmp" -> ok; @@ -143,3 +168,160 @@ mv_warning_is_ignored(_Config) -> meck:expect(rebar_utils, sh, fun("mv ding dong", _) -> {ok, "Warning"} end), ok = rebar_file_utils:mv("ding", "dong"), meck:unload(rebar_utils). + +%%% Ensure Windows & Unix operations to move files + +mv_dir(Config) -> + %% Move a directory to another one location + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_dir), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + %% empty dir movement + DstDir1 = filename:join(BaseDir, "dst1/"), + ?assertNot(filelib:is_dir(DstDir1)), + ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir1)), + ?assert(filelib:is_dir(DstDir1)), + + %% move files from dir to empty dir + F1 = filename:join(SrcDir, "file1"), + F2 = filename:join(SrcDir, "subdir/file2"), + ec_file:mkdir_p(F2), + file:write_file(F1, "hello"), + file:write_file(F2, "world"), + DstDir2 = filename:join(BaseDir, "dst2/"), + D2F1 = filename:join(DstDir2, "file1"), + D2F2 = filename:join(DstDir2, "subdir/file2"), + ?assertNot(filelib:is_dir(DstDir2)), + ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir2)), + ?assert(filelib:is_file(D2F1)), + ?assert(filelib:is_file(D2F2)), + + %% move files from dir to existing dir + ec_file:mkdir_p(F2), + file:write_file(F1, "hello"), + file:write_file(F2, "world"), + DstDir3 = filename:join(BaseDir, "dst3/"), + D3F1 = filename:join(DstDir3, "file1"), + D3F2 = filename:join(DstDir3, "subdir/file2"), + ec_file:mkdir_p(DstDir3), + ?assert(filelib:is_dir(DstDir3)), + ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir3)), + ?assert(filelib:is_file(D3F1)), + ?assert(filelib:is_file(D3F2)), + ?assertNot(filelib:is_dir(SrcDir)), + ok. + +mv_file_same(Config) -> + %% Move a file from a directory to the other without renaming + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_same), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file"), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_file_diff(Config) -> + %% Move a file from a directory to another one while renaming + %% into a pre-existing file + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_diff), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file-rename"), + file:write_file(Dst, "not-the-right-content"), + ?assert(filelib:is_file(Dst)), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_file_dir_same(Config) -> + %% Move a file to a directory without renaming + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_dir_same), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file"), + ?assert(filelib:is_dir(DstDir)), + ?assertEqual(ok, rebar_file_utils:mv(F, DstDir)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_file_dir_diff(Config) -> + %% Move a file to a directory while renaming + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_dir_diff), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + Dst = filename:join(DstDir, "file-rename"), + ?assertNot(filelib:is_dir(DstDir)), + ?assertNot(filelib:is_file(Dst)), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_no_clobber(Config) -> + %% Moving a file while renaming does not clobber other files + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_no_clobber), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + FBad = filename:join(SrcDir, "file-alt"), + file:write_file(FBad, "wrong-data"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file-alt"), + DstBad = filename:join(DstDir, "file"), + file:write_file(DstBad, "wrong-data"), + ?assert(filelib:is_file(F)), + ?assert(filelib:is_file(FBad)), + ?assert(filelib:is_dir(DstDir)), + ?assertNot(filelib:is_file(Dst)), + ?assert(filelib:is_file(DstBad)), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ?assert(filelib:is_file(DstBad)), + ?assert(filelib:is_file(FBad)), + ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)), + ?assertEqual({ok, <<"wrong-data">>}, file:read_file(FBad)), + ?assertEqual({ok, <<"wrong-data">>}, file:read_file(DstBad)), + ok. + + +mk_base_dir(BasePath, Name) -> + {_,_,Micro} = os:timestamp(), + Index = integer_to_list(Micro), + Path = filename:join(BasePath, atom_to_list(Name) ++ Index), + ec_file:mkdir_p(Path), + Path. -- cgit v1.1