erlang / rebar3

Erlang build tool that makes it easy to compile and test Erlang applications and releases.
http://www.rebar3.org
Apache License 2.0
1.7k stars 519 forks source link

rebar_prv_common_test screws sources #395

Closed kovyl2404 closed 9 years ago

kovyl2404 commented 9 years ago

Hi! Now I'm working on project with following sctructure:

[vkovalev@t30nix yalta]$ tree -L 2
.
|-- apps
|   |-- spark_emulator
|   `-- yalta_engine
|-- _build
|   |-- default
|   `-- test
|-- rebar.config
`-- rebar.lock

[vkovalev@t30nix yalta]$ cat rebar.config 
{deps, [
    {gen_serial, {git, "https://github.com/kovyl2404/gen_serial", {ref, "df9f3774ac"}}},
    {gproc, {git, "https://github.com/uwiger/gproc", {tag, "v0.2.10"}}},
    {cowboy, {git, "https://github.com/ninenines/cowboy", {tag, "1.0.1"}}}
]}.
{profiles, [
    {test, [
        {deps, [
            {meck, {git, "https://github.com/eproxus/meck", {tag, "0.8.2"}}}
        ]}
    ]}
]}.

I've just wanted to run common tests with rebar3 ct --dir=apps/spark_protocol/test, but mistyped and run rebar3 ct --dir=apps/spark_protocol. Notice _--dir=apps/sparkprotocol is application root, not test directory.

Result was surprising:

## Lets see the size of files in apps/spark_emulator/src/
[vkovalev@t30nix yalta]$ stat -c "%n %s" apps/spark_emulator/src/*
apps/spark_emulator/src/spark_transport.erl 0
apps/spark_emulator/src/spark_emulator.app.src 0
apps/spark_emulator/src/spark_emulator.erl 0
apps/spark_emulator/src/spark_protocol.erl 0

Oops... Seems my work just was thrown in trash. Okay, less code is better =) So I dug into rebar_prv_common_test and found this line. It tries to copy files from "apps/spark_emulator" to "/home/vkovalev/dev/yalta/_build/test/lib/spark_emulator". This directories are physically different, but "/home/vkovalev/dev/yalta/_build/test/lib/spark_emulator/src" is a symlink to "apps/spark_emulator/src". Not shure I'm understand what extactly gong on here, but it seems ec_file:copy/3 can't copy files properly when source and destination file are the same (but with different name).

ferd commented 9 years ago

@talentdeficit ? That sounds like the bug that prompted to forbid tests at the root of the project?

kovyl2404 commented 9 years ago

@ferd, I've just noticed that there was exactly same issue https://github.com/rebar/rebar3/issues/331, but I definitely do not understand why it was closed and how https://github.com/rebar/rebar3/issues/333 intended to resolve it.

ferd commented 9 years ago

@kovyl2404 it happened whenever someone submitted --suites=mysuite and mysuite existed on the project root. @talentdeficit then forbid the usage of suites at the root and it took care of that one. But yours is seeing that same problem, but at the app root rather than the project root, so the prior fix wasn't general enough.

talentdeficit commented 9 years ago

this looks like the same bug. i'll look into it

talentdeficit commented 9 years ago

so i think the problem is that the dir _build/test/lib/spark_emulator/src is a symlink and ec_file:copy (via the ct provider) attempts to copy spark_emulator/src over top of it. there's a check that the target directory of ec_file:copy is not a symlink but it doesn't extend to checking subdirs of that directory

proposed solutions:

check that the target directory has a prefix of $PROJECT_ROOT/_build/$PROFILE/ and always delete regardless of whether it is a symlink or not. you can still destroy data in subdirs of that prefix in that case but it should theoretically be rebuilt on the next command run. it should stop any further problems with copying directories into symlinks of themselves

i'll try to get a pr out by the end of the day tomorrow if no one has any other suggestions