facile-it / paraunit

Run PHPUnit tests in parallel
https://engineering.facile.it/paraunit/
Apache License 2.0
140 stars 15 forks source link

Generating Phars with Box #62

Closed Jean85 closed 7 years ago

Jean85 commented 7 years ago

This is WIP, to address #5

I'm trying to use Box to generate a PHAR version of Paraunit.

It seems to work, up until the point of running the tests. The single PHPUnit process doesn't seem to use the correct autoloader, instead it uses the one inside the PHPUnit package.

@jwage can I ask your help about this? How did you work this out with PHPChunkit?

Jean85 commented 7 years ago

Nevermind, it seems that I've fixed it with 6c4de1c. This makes me think that the PHAR is calling the PHPUnit bin from the vendor folder of the project who's running the PHAR, not from inside the PHAR!

Is this the right way? @jwage this seems the same thing that your PHPChunkit is doing, is this right? Is it intentional?

taueres commented 7 years ago

@Jean85 What you are saying it's correct. The PHAR executable is spawning the child processes using the installed version of PHPUnit in the external project. It's not using the embedded vendor folder. This means that the PHAR is not completely standalone, which is bad (PHARs are good due to their versatility). In my previous implementation the subprocesses were executing the ParaUnit PHAR in a "special mode" (the PHAR was basically executing itself over and over again). ParaUnit was then simply forwarding the control to the embedded PHPUnit library.

You just need to detect "normal" executions of ParaUnit vs "subprocess" executions.

taueres commented 7 years ago

The problem is that PHAR archives create a virtual filesystem which is known only to PHARs. Since we are spawning processes with the OS, we cannot access directly those files.

Jean85 commented 7 years ago

Ok, understood! I'll look into your previous PR to address this issue. Did your approach work well in regards of the autoloader too?

taueres commented 7 years ago

Since the subprocesses are executing the PHAR file, they're using the ParaUnit's autoload system.

Jean85 commented 7 years ago

Ok, great. Re-reading your PR I'm still missing something BTW. How you achieved re-running the PHAR? My code was calling for realpath(phpunit)...

Jean85 commented 7 years ago

@taueres I've done all that I could, and the PHAR is able to launch Paraunit correctly; now I'm having issues with the subprocesses, since PHPUnit is launched, but I get this fatal:

Fatal error: Cannot redeclare composerRequirefb0b96d737bbd313c0c715a28d4d7f4c() (previously declared in phar:///home/paraunit/projects/paraunit.phar/vendor/composer/autoload_real.php:63) in /home/paraunit/projects/vendor/composer/autoload_real.php on line 70

Call Stack:
    0.0180    1152256   1. {main}() /home/paraunit/projects/paraunit.phar:0
    0.0184    1157016   2. require('phar:///home/paraunit/projects/paraunit.phar/src/Paraunit/Bin/phar') /home/paraunit/projects/paraunit.phar:10
    0.0187    1165784   3. require('phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/phpunit') phar:///home/paraunit/projects/paraunit.phar/src/Paraunit/Bin/phar:17
    0.0328    1733816   4. PHPUnit_TextUI_Command::main() phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/phpunit:47
    0.0328    1734592   5. PHPUnit_TextUI_Command->run() phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/src/TextUI/Command.php:115
    0.0328    1737760   6. PHPUnit_TextUI_Command->handleArguments() phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/src/TextUI/Command.php:126
    0.0412    2174432   7. PHPUnit_TextUI_Command->handleBootstrap() phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/src/TextUI/Command.php:731
    0.0414    2182744   8. PHPUnit_Util_Fileloader::checkAndLoad() phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/src/TextUI/Command.php:902
    0.0415    2182912   9. PHPUnit_Util_Fileloader::load() phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/src/Util/Fileloader.php:38
    0.0415    2185248  10. include_once('/home/paraunit/projects/vendor/autoload.php') phar:///home/paraunit/projects/paraunit.phar/vendor/phpunit/phpunit/src/Util/Fileloader.php:56

Basically the autoloader inside the PHAR is triggered somewhere (maybe in the Box stub?), and PHPUnit tries to load the autoloader of the project, colliding. I don't know how to solve this now. I think I will try to circumvent this altogether.

taueres commented 7 years ago

Humm... weird. Please make sure that you are not running the ParaUnit tests with ParaUnit itself. If so, the autoloader will be executed twice. As an alternative, you could remove the bootstrap configuration in the phpunit.xml.

Jean85 commented 7 years ago

Yes, I imagined that reloading the same autoloader would give me those issues. I'm trying to produce a working PHAR that would run on a different testsuite, but as of f6c648e I get this strange error:

$ ./paraunit.phar phpunit         
#!/usr/bin/env php
Cannot open file "phpunit.php".
Jean85 commented 7 years ago

Finally, this is no longer a WIP! The mistake that I was doing was very simple, I was unsetting only $argv (like @taueres) but PHPUnit uses $_SERVER['argv'], so now I array_shift both!

I've also added a release guide, for myself at least!