pjf / ipc-system-simple

Perl module to make running system commands and capturing errors as simple as possible.

Home Page:http://search.cpan.org/perldoc?IPC::System::Simple

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IPC-System-Simple-1.26-TRIAL: t/04_capture.t seems to hang on Strawberry Perl

twata1 opened this issue · comments

Hello,

It seems to me that t/04_capture.t hangs on Windows as follows.

Strawberry Perl 5.20.3 on Windows 8.1 (64bit)

C:\home\grapefruit\IPC-System-Simple-1.26>perl Makefile.PL
Checking if your kit is complete...
Looks good
Generating a dmake-style Makefile
Writing Makefile for IPC::System::Simple
Writing MYMETA.yml and MYMETA.json

C:\home\grapefruit\IPC-System-Simple-1.26>dmake
cp lib/IPC/System/Simple.pm blib\lib\IPC\System\Simple.pm

C:\home\grapefruit\IPC-System-Simple-1.26>prove -lv t\04_capture.t
t\04_capture.t ..
1..12
ok 1 - use IPC::System::Simple;
(hangs)

Strawberry Perl 5.30.0 on Windows 8.1 (64bit)

C:\home\sunlight\IPC-System-Simple-1.26>perl Makefile.PL
Checking if your kit is complete...
Looks good
Generating a gmake-style Makefile
Writing Makefile for IPC::System::Simple
Writing MYMETA.yml and MYMETA.json

C:\home\sunlight\IPC-System-Simple-1.26>gmake
cp lib/IPC/System/Simple.pm blib\lib\IPC\System\Simple.pm

C:\home\sunlight\IPC-System-Simple-1.26>prove -lv t\04_capture.t
t\04_capture.t ..
1..12
ok 1 - use IPC::System::Simple;
(hangs)

Thank you,

Same problem for me, Windows 10, Strawberry Perl 5.26.1. It gets to t/04_capture.t ........... 1/12 and just hangs there. I think I let it sit there for over 30 minutes, before killing it.

By the way, is there a reason that none of the automated testers have tried this on MSWIN32? It seems odd that there have not been any attempts. Is there something in the package that says, "do not run on Windows"?

[snip]

By the way, is there a reason that none of the automated testers have tried this on MSWIN32? It seems odd that there have not been any attempts. Is there something in the package that says, "do not run on Windows"?

In general, CPANtesters suffers from a shortage of Win32 testing rigs. So this is a problem far beyond IPC-System-Simple. Any assistance you can provide with this would be helpful.

Of course, there may be problems specific to IPC-System-Simple. For example, see this CPANtesters report on version 1.25 on mswin32 (perhaps a VM): http://www.cpantesters.org/cpan/report/85712b9a-6bfb-1014-ab2b-121f97dd93b5

I myself don't have access to, or familiarity with, Windows, so as a recently-assigned co-maintainer I've been focusing on those issues and pull requests that I can investigate on Unix. All Windows-related issues and p.r.s have been labelled as such.

Thank you very much.
Jim Keenan

I asked about Windows testing, as I don't think I've ever seen a test report without at least a few attempts at Windows (MSWIN32). Let's give it a few more days and see if anything shows up. I can't be an automated tester, but when I have troubles I do try to do some diagnostics and report it to the package owner.

The report you referenced complains about not finding Win32::Process, which does not appear to be prereq'd in 1.26. I happen to have it installed. Perhaps it should be listed as a required prereq, unless it's built into core?

I unpacked the install package, and ran perl t/04_capture.t in a CMD window (shell), against my v1.25 installation. All 12 tests ran OK! Either there must be something in the cpan installation environment that is much different than a normal Windows command line shell, or you made a change in 1.26 that broke those tests. All the other t-tests besides 7 and 10 (complaining about -T switch) were successful.

With luck, that might give you enough to go on. If you need me to test a revised package with diagnostics or revised code, I'll be happy to help out with testing it.

I believe this issue was introduced by 1d99f77 . 04_capture.t calls capture with a single parameter containing the executable (perl.exe) and the argument (output.pl). That commit quotes the entire first argument, so the Win32::Process::Create call starts a program named "perl.exe output.pl" with no arguments. This causes Perl to wait for input on stdin, which looks like it hangs. Manually sending EOF (ctrl-Z) moves on to the next test, but this has to be done multiple times as there are many affected tests.

All tests pass if I undo that commit, but I assume it was done to fix another problem. Probably with spaces in the executable name, e.g. "C:\Program Files\Perl\bin\Perl.exe". Quoting the executable name is probably fine if args is explicitly specified (unless the exe is already quoted...), but isn't safe in all situations.

It is a bit confusing. I'm wondering if some (or all) of this elaborate Windows code is for fixing a problem that no longer exists? Anyway, capture() expects 1 or more array elements: an optional valid returns sub-array, a command string, and optional argument(s) for the command. Now, is "perl.exe output.pl" to be considered a command + argument, or a single command? Most Windows installations need to tell the shell to use Perl for a .pl program, so I think "perl.exe output.pl" would be considered a single command. In test 1, output.pl has no arguments and prints a string "Hello\nGoodbye\n" and a return code of 0 (by default). Possibly, output.pl might need to be moved to the argument list, and the command just be "perl.exe", but I'm not sure about that. If there's a concern that the command is "blah blah/perl.exe" (embedded space), it should be easy enough to wrap it in escaped quotes: my $output_exe = "\"$perl_path\" output.pl";. Anyway, a single string fed to capture() should be legal, shouldn't it? At worst, capture("\"$perl_path\"", "output.pl").

I put in some debug to look at the valid_returns, command, and args. By breaking up command strings such as "$perl_path output.pl" into two arguments: "$perl_path", "output.pl" it appears to solve the hang problem. I left $perl_path enclosed in "" just in case it had an embedded space in it (mine doesn't). HOWEVER, there appear to be a number of tests specifically testing all-one-string versus broken up like I described above. So, I am probably changing what they're trying to test. Unfortunately, a hang (requiring ^Z input) is the result of the original tests.

04_capture.t, 07_taint, 11_newlines.t, 12_systemx.t, and win32.t all get past the hangs doing this. Just test 5 in 12_systemx.t fails now (but doesn't hang), but as I said before, I seem to be changing the meaning of some of the altered tests. So, I'm not sure where to go from here. Possibly the specific all-one-string tests could be skipped for Windows testing, and the rest broken up into Perl command and arguments?

Breaking up the arguments shouldn't be necessary. run (and the 'system' alias) and capture are intended to be drop-in replacements for CORE::system and backticks. CORE::system('perl output.pl') should have the same output as IPC::System::Simple::system('perl output.pl')

The tests should be failing, as the module code is not working correctly. The failures should be more graceful, but the tests should not be passing.

Some examples; I'm using tar because it errors immediately if no arguments are given.

CORE::system('tar')

tar: You must specify one of the -Acdtrux' options Try tar --help' for more information.

CORE::system('tar --version')

tar (GNU tar) 1.13

print `tar --version`

tar (GNU tar) 1.13

IPC::System::Simple::run('tar --version')

tar (GNU tar) 1.13

IPC::System::Simple::capture('tar --version')

tar --version: You must specify one of the -Acdtrux' options Try tar --version --help' for more information.

This is the issue: instead of passing the --version argument to the invoked program, it is treating the program name as "tar --version".

Splitting up the arguments does work, but shouldn't be necessary:
print IPC::System::Simple::capture('tar', '--version')

tar (GNU tar) 1.13

Can you try the following branch in the github repository and see if it reduces the number of test failures?
https://github.com/pjf/ipc-system-simple/tree/theory-win32quote

Thank you very much.
Jim Keenan

Looks pretty good. I first manually copied Simple.pm into \Strawberry\perl\site\lib\IPC\System and then ran all the ".t" tests in the new win32quote\t directory and they all passed. Then I copied over the Makefile.PL from the 1.26 (failed) installation and ran cpan . against the win32quote directory. It appears to have made a successful installation, with all the t-tests succeeding. cpan > i IPC::System::Simple claims that the installed version is "undef", so I'm not sure that the installation fully succeeded, but at least your new code seems to pass the tests. This is Windows 10 Strawberry Perl 5.26.1.

Something I forgot to mention... even though the cpan upgrade to 1.26 had failed, there was no "Simple.pm" under IPC\System\ when I manually copied over the new Simple.pm. Something strange must have happened during a failed install that wiped out the old (1.25) Simple.pm, which shouldn't have happened. The upgrade uses a temporary directory to hold everything until testing passes and the final install can be done. Anyway, odd.

Per my earlier question about why it wasn't tested on Windows (MSWin32), my guess is that it has been testing, but by hanging up, nothing was ever reported back to cpan.org and the MSWin32 column remained empty. That should probably be brought to the attention of the CPAN people, as it indicates a flaw in their testing system. A test system should probably send an "I am testing XXXXX" notice (as "in progress"), and if nothing further is heard after an hour or two, automatically turn it into a failure report.

Something I forgot to mention... even though the cpan upgrade to 1.26 had failed, there was no "Simple.pm" under IPC\System\ when I manually copied over the new Simple.pm. Something strange must have happened during a failed install that wiped out the old (1.25) Simple.pm, which shouldn't have happened. The upgrade uses a temporary directory to hold everything until testing passes and the final install can be done. Anyway, odd.

Per my earlier question about why it wasn't tested on Windows (MSWin32), my guess is that it has been testing, but by hanging up, nothing was ever reported back to cpan.org and the MSWin32 column remained empty. That should probably be brought to the attention of the CPAN people, as it indicates a flaw in their testing system. A test system should probably send an "I am testing XXXXX" notice (as "in progress"), and if nothing further is heard after an hour or two, automatically turn it into a failure report.

I probably should have clarified that what I was hoping people would do is to do a git checkout of the IPC-System-Simple github repository, then attempt to build and test the theory/win32quote branch. Something like this:

$ cd /tmp
$ git clone git@github.com:pjf/ipc-system-simple.git
$ cd ipc-system-simple
$ git checkout theory-win32quote
Branch 'theory-win32quote' set up to track remote branch 'theory-win32quote' from 'origin'.
Switched to a new branch 'theory-win32quote'
$ prove -Ilib t/*.t

(The IPC-System-Simple distribution is structured to be developed with Dist-Zilla -- which IMO is unfortunate. But if you have Dist::Zilla installed -- and I have no idea how well it works on Windows -- then for the prove command above you would substitute dzil test; dzil build.)

In other words, I'm not (yet) concerned with whether you can perform a version upgrade using cpan or cpanm. Until such time as I do a TRIAL release to CPAN, I'm only concerned with whether the tests pass when run against the revised code under lib/.

Once again, thanks for your efforts in investigating this.

Thank you very much.
Jim Keenan

I just ran the tests using dzil, on a fresh copy of strawberry perl (5.30.2)

The tests pass, up to t/win32.t. All 8 of the "test spaces in filename" tests fail with "The system cannot find the path specified". Manually extending the tests to also try qx with the same paths (quoted and not) gives the same error. I think this is because the exe is not bundled with the CPAN release and isn't being copied in to the .build dir. Manually copying in the files to one of the .build directories and running gmake passes all tests.

Additionally, the author tests in t/author-pod-coverage.t failed at first because there's a hidden dependency on Pod::Coverage::TrustPod and Test::Pod::Coverage. These two modules don't show up in "dzil authordeps"

I just ran the tests using dzil, on a fresh copy of strawberry perl (5.30.2)

The tests pass, up to t/win32.t. All 8 of the "test spaces in filename" tests fail with "The system cannot find the path specified". Manually extending the tests to also try qx with the same paths (quoted and not) gives the same error. I think this is because the exe is not bundled with the CPAN release and isn't being copied in to the .build dir. Manually copying in the files to one of the .build directories and running gmake passes all tests.

Which "exe" (that is not bundled with the CPAN release) are you referring to?

Additionally, the author tests in t/author-pod-coverage.t failed at first because there's a hidden dependency on Pod::Coverage::TrustPod and Test::Pod::Coverage. These two modules don't show up in "dzil authordeps"

Okay, for now let's not worry about the POD tests or authordeps. (That's my problem as comaint, but not a user's problem.) Can you paste or attach what you did to get t/win32.t to pass? (Feel free to send plain text files to my CPAN address, if not here.)

Thank you very much.
Jim Keenan
CPANID: jkeenan

The exe is "\ipc-system-simple\t\dir with spaces\hello.exe". "dir with spaces" is not part of the existing CPAN distributions, but the precompiled exe and hello.c are checked in to git.

I got it to run by copying "C:\Strawberry\ipc-system-simple\t\dir with spaces" to "C:\Strawberry\ipc-system-simple.build\oxuXWy_Df3\t". No code changes. The solution is to either mark the last 8 tests in win32.t as author only/skipped/TODO, or to include hello.c in the dist and build it as part of the module build. As this is otherwise a Pure Perl module, I don't think that's a good idea, but it still seems better than distributing the .exe directly.

(The IPC-System-Simple distribution is structured to be developed with Dist-Zilla -- which IMO is unfortunate. But if you have Dist::Zilla installed -- and I have no idea how well it works on Windows -- then for the prove command above you would substitute dzil test; dzil build.)

In other words, I'm not (yet) concerned with whether you can perform a version upgrade using cpan or cpanm. Until such time as I do a TRIAL release to CPAN, I'm only concerned with whether the tests pass when run against the revised code under lib/.

I don't have Dist::Zilla installed, and don't know if it works with Windows. Why is using git important? I did the .zip download and unzipped it, giving me a copy of your Github root on my desktop. For my first test, I just copied over Simple.pm to my existing \Strawberry installation and ran the [new] t-tests (all passed). For my second test, I built and installed by running cpan . in that desktop directory. I don't think it permanently updated \Strawberry, but it did show that all the t-tests ran OK. Isn't this ("whether the tests pass") what you're looking for? Or is something important missing?

I just ran the tests using dzil, on a fresh copy of strawberry perl (5.30.2)

The tests pass, up to t/win32.t. All 8 of the "test spaces in filename" tests fail with "The system cannot find the path specified". Manually extending the tests to also try qx with the same paths (quoted and not) gives the same error.

Would there be some Windows-appropriate command -- with spaces -- that we could use here instead of something which requires C-compiled code? That is, something different for this:

# These are used in the testing of commands in paths which contain spaces.
use constant CMD_WITH_SPACES        => 'dir with spaces\hello.exe';
use constant CMD_WITH_SPACES_OUTPUT => "Hello World\n";

Thank you very much.
Jim Keenan

I'm not sure. The problem is that most programs that exist in the base Windows installation are GUI, not command-line based. The command line tools are typically in system (e.g. the grep equivalent is C:\Windows\system32\findstr.EXE). There might be something that's installed by default in C:\Program Files\ that's usable on the command line, but I can't think of anything, and I don't have a clean install of Windows.

Is it something inherent in a .exe file's execution? If not, if all you need is something running on the command line, wouldn't a .pl file do? Or are you trying to test something where .exe behaves differently than .pl, or a basic DOS command? Is the problem that most Windows systems need "perl" explicitly given (.pl extension is not associated with perl.exe, as it is on my system), which interferes with whatever you're trying to test? How about a batch (script) file .bat? This would have to be a Windows-only t-test. Basically, what are you trying to test with something like hello.exe? I'm just trying to get the 50000 foot overview of the forest before dealing with individual trees.

It does need to be a .exe as the issue is with creating processes. Running a Perl script requires running Perl.exe and passing the script as an argument. Similarly, running a bat file requires running cmd.exe and passing that as an argument.

I believe this is related to issue #22. Spaces in a filepath can easily cause problems, and since many programs are installed in C:\Program Files, this comes up a lot on Windows.

I believe that we have addressed the hang in t/04_capture.t in CPAN versions 1.28 and later (currently, 1.29). Can you confirm?

Thank you very much.
Jim Keenan

Release 1.29 builds, tests, and installs OK (via cpan tool). Looks good from here. Windows 10, Strawberry Perl 5.26.1.

I confirmed t/04_capture.t did not hang in CPAN version 2.28 and 1.29.
I think you can close this issue.

Thank you for your help!

Thanks for the feedback! Closing.