Test-More / Test2-Harness

Alternative to Test::Harness
Other
23 stars 26 forks source link

Include handling for Perl task #213

Closed ylavoie closed 3 years ago

ylavoie commented 3 years ago

I am trying to use a perl test which needs a directory added to INC. Using:

 ../Test2-Harness/scripts/yath --include old/lib t/06-blacklist.t

I get:

** Defaulting to the 'test' command **

( STDERR )  job  1    Cannot include persister class 'LedgerSMB::Workflow::Persister::Email': Can't locate LedgerSMB/User.pm in @INC (you may need to install the LedgerSMB::User module) (@INC contains: /srv/ledgersmb/utils/devel/../lib lib /var/www/perl5/lib/perl5/5.30.0/x86_64-linux-gnu-thread-multi /var/www/perl5/lib/perl5/5.30.0 /var/www/perl5/lib/perl5/x86_64-linux-gnu-thread-multi /var/www/perl5/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at lib/LedgerSMB/App_State.pm line 18.

where it is obvious that the olb/lib path was never added.

Looking at https://github.com/Test-More/Test2-Harness/blob/master/lib/Test2/Harness/Runner/Job.pm#L484, the code explicitly sets PERL5LIB for binary task or non-perl, both of which don't use it. Reversing the condition fixes this issue but makes t/includes.t fails

I'm hoping that the problem is behind my keyboard and that I just didn't invoked yath properly.

exodist commented 3 years ago

The PERL5LIB is only set for non-perl tests so that any perl they call will get the libs. For perl specific tests the libs are set with a perl -Ipath argument when the test is run, assuming you do not disable forking (forking is used by default). In fork mode the @INC var is modified post-fork in the test process, PERL5LIB has no effect since the process was created via fork, not from scratch. The tests to verify PERL5LIB is not modified are to prevent this mistake, so they did their job :-D

I wonder if --include is broken, try -Ipath and see if that works. I use custom paths all the time, so I would be surprised if it was really broken, but obviously something is not working for you, and we will have to figure it out.

exodist commented 3 years ago

https://github.com/Test-More/Test2-Harness/blob/117972c2a32b67cc71844a0aa5ddab56dd3cb738/lib/Test2/Harness/Runner/Job.pm#L124

The above file+line is for of you have forking disabled and perl is launched from scratch for each test. I will comment in a moment with the place it happens in the default/fork/preload mode

ylavoie commented 3 years ago

-I or --include both handle the directory, which reaches https://github.com/Test-More/Test2-Harness/blob/117972c2a32b67cc71844a0aa5ddab56dd3cb738/lib/Test2/Harness/Runner/Job.pm#L414

Running yath with or without --fork has no effect and line 124 is never called.

ylavoie commented 3 years ago

The PERL5LIB is only set for non-perl tests so that any perl they call will get the libs. For perl specific tests the libs are set with a perl -Ipath argument when the test is run, assuming you do not disable forking (forking is used by default). In fork mode the @inc var is modified post-fork in the test process, PERL5LIB has no effect since the process was created via fork, not from scratch. The tests to verify PERL5LIB is not modified are to prevent this mistake, so they did their job :-D

Doesn't that imply that perl specific tests need their components to explicitly refer to actual paths to get the libs because they won't be able to rely on PERL5LIB or INC? Or that the user need to fix INC himself before calling yath?

exodist commented 3 years ago

Sorry, an ice storm took out my power and internet while I was trying to explain this to you, it has been several days and I still have no power, however my internet came back up, so whenever my generator is on I have connectivity. I will try to explain:

Yath normally has a preload+fork model. You start yath and it launches a couple processes your main process does display, a secondary process becomes the runner, which then preloads things. When a test start the runner normally forks and then launches the test inside that process without calling exec or anything. That newly forked test process, before control is turned over to your actual test script, will set up @INC with the things you specified via -I and so on. the -I is not even processed until this point, so it would not be in PERL5LIB, and adding it would have no effect as the perl process is already running.

The place that SHOULD set your -I is https://metacpan.org/release/Test2-Harness/source/lib/App/Yath/Command/runner.pm#L324

Tests should not need to manually set @INC or set PERL5LIB or anything, passing -I to yath SHOULD cause it to set the @INC in the above line. -I is pretty commonly used by me and other yath users, so I am extremely flummoxed as to how it would be broken for you.

exodist commented 3 years ago

It is possible that the automatic selection of the 'test' command is the problem. Try yath test -I... ... (Make sure 'test' is the first word after 'yath' on your command line. It is possible the argument processing system is reading your -I and eating it before handing things off to the test command,

exodist commented 3 years ago

hmm, I am also noticing you are using ../Test2-Harness/script/yath to run it. Doing it this way could have yath use an older version of yath, whatever it is installed in your system, in conjunction with the newer script version. Try ../Test2-Harness/scripts/yath -D../Test2-Harness/lib ... to make sure it uses the correct set of libs. Make sure -D comes BEFORE the word 'test' if you use that to specify the test command instead of letting it default to test.

ylavoie commented 3 years ago

The -I argument is correctly handled.

Yath implements -I by properly setting @INC. prove does it by setting PERL5LIB and our tests were expecting that in a Perl submodule.

The issue is on my side, not yath. I'm closing this non-issue.