How to test Output when using IPC::Open3

I'm having a more or less complicated code, that was simplified to this.

use strict;
use warnings;
use IPC::Open3;
use IO::Handle;
use Test::More;
use Test::Trap;

sub shell_run {
my ($stdin, $stdout, $stderr) = map {IO::Handle->new} (0..2);

print "YYYY";

open3($stdin, $stdout, $stderr, [at] _);

foreach my $line (<$stdout>, <$stderr>) {
print "read: $line";
}

print "ZZZZ";
}

trap {shell_run('perl', '-E', 'print "TEXT IN"')};

#is( $trap->stdout, "YYYYZZZZ");
is( $trap->stdout, "YYYYTEXT INZZZZ");

done_testing();


I would expect to have the test 'is( $trap->stdout, "YYYYTEXT
INZZZZ");' executing ok, instead of that I have the test 'is(
$trap->stdout, "YYYYZZZZ");'.

I need to test the output inside the loop in there, I have tried allot
of solution but I just don't get it

How do I do it?

Thanks for your help

Best Regards
Marcos Rebelo

--
Marcos Rebelo
http://oleber.freehostia.com
Milan Perl Mongers leader http://milan.pm.org
Webmaster of http://sites.google.com/site/oleberperlrecipes/

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
oleber [ Sa, 28 August 2010 09:45 ] [ ID #2046814 ]

Re: How to test Output when using IPC::Open3

On Aug 28, 12:45=A0am, ole... [at] gmail.com (marcos rebelo) wrote:
> I'm having a more or less complicated code, that was simplified to this.
>
> use strict;
> use warnings;
> use IPC::Open3;
> use IO::Handle;
> use Test::More;
> use Test::Trap;
>
> sub shell_run {
> =A0 =A0 my ($stdin, $stdout, $stderr) =3D map {IO::Handle->new} (0..2);
>
> =A0 =A0 print "YYYY";
>
> =A0 =A0 open3($stdin, $stdout, $stderr, [at] _);
>
> =A0 =A0 foreach my $line (<$stdout>, <$stderr>) {
> =A0 =A0 =A0 =A0 print "read: $line";
> =A0 =A0 }
>
> =A0 =A0 print "ZZZZ";
>
> }
>
> trap {shell_run('perl', '-E', 'print "TEXT IN"')};
>
> #is( $trap->stdout, "YYYYZZZZ");
> is( $trap->stdout, "YYYYTEXT INZZZZ");
>
> done_testing();
>
> I would expect to have the test 'is( $trap->stdout, "YYYYTEXT
> INZZZZ");' executing ok, instead of that I have the test 'is(
> $trap->stdout, "YYYYZZZZ");'.
>
> I need to test the output inside the loop in there, I have tried allot
> of solution but I just don't get it

Since you mention simplifying the code, do you actually
need IPC::Open3 ? In your sample code, you're only
reading process output.

If you don't need IPC::Open3 complexity, you could just
use magic open to read output :

sub shell_run
{
print "YYYY";
my $pid =3D open( my $fh, qq{ [at] _ | } ) or die "open: $!";
print for <$fh>;
close $fh or die "close: ", $? || $!;
print "ZZZZ";
}
trap { shell_run( 'perl', '-E', '"print \'TEXT IN\'"' ) };
is( $trap->stdout, "YYYYTEXT INZZZZ");
done_testing();

--> ok 1
1..1

--
Charles DeRykus


--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
derykus [ So, 29 August 2010 01:44 ] [ ID #2046821 ]

Re: How to test Output when using IPC::Open3

C.DeRykus wrote:
>
> Since you mention simplifying the code, do you actually
> need IPC::Open3 ? In your sample code, you're only
> reading process output.
>
> If you don't need IPC::Open3 complexity, you could just
> use magic open to read output :
>
> sub shell_run
> {
> print "YYYY";
> my $pid = open( my $fh, qq{ [at] _ | } ) or die "open: $!";

Probably better as:

my $pid = open my $fh, '-|', [at] _ or die "open: $!";

And you don't use $pid anywhere so why create it?

> print for<$fh>;

Probably better as:

print while <$fh>;

> close $fh or die "close: ", $? || $!;

Probably better as:

close $fh or die $! ? "Error closing pipe: $!"
: "Exit status $? from $_[0]";

> print "ZZZZ";
> }
> trap { shell_run( 'perl', '-E', '"print \'TEXT IN\'"' ) };
> is( $trap->stdout, "YYYYTEXT INZZZZ");
> done_testing();



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
jwkrahn [ So, 29 August 2010 06:08 ] [ ID #2046822 ]

Re: How to test Output when using IPC::Open3

the idea is to process the STDOUT ad the STDERR.

open don't do it

Best Regards
Marcos Rebelo

On Sun, Aug 29, 2010 at 6:08 AM, John W. Krahn <jwkrahn [at] shaw.ca> wrote:
> C.DeRykus wrote:
>>
>> Since you mention simplifying the code, do you actually
>> need IPC::Open3 ? =A0In your sample code, you're only
>> reading process output.
>>
>> If you don't need IPC::Open3 complexity, you could just
>> use magic open to read output :
>>
>> sub shell_run
>> {
>> =A0 =A0 print "YYYY";
>> =A0 =A0 my $pid =3D open( my $fh, qq{ [at] _ | } ) =A0or die "open: $!";
>
> Probably better as:
>
> =A0 =A0 =A0my $pid =3D open my $fh, '-|', [at] _ or die "open: $!";
>
> And you don't use $pid anywhere so why create it?
>
>> =A0 =A0 print for<$fh>;
>
> Probably better as:
>
> =A0 =A0 =A0print while <$fh>;
>
>> =A0 =A0 close $fh =A0or die "close: ", $? || $!;
>
> Probably better as:
>
> =A0 =A0 =A0close $fh or die $! ? "Error closing pipe: $!"
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0: "Exit status $? from=
$_[0]";
>
>> =A0 =A0 print "ZZZZ";
>> }
>> trap { shell_run( 'perl', '-E', '"print \'TEXT IN\'"' ) };
>> is( $trap->stdout, "YYYYTEXT INZZZZ");
>> done_testing();
>
>
>
> John
> --
> Any intelligent fool can make things bigger and
> more complex... It takes a touch of genius -
> and a lot of courage to move in the opposite
> direction. =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -- Albert Einstein
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
> For additional commands, e-mail: beginners-help [at] perl.org
> http://learn.perl.org/
>
>
>



--
Marcos Rebelo
http://oleber.freehostia.com
Milan Perl Mongers leader http://milan.pm.org
Webmaster of http://sites.google.com/site/oleberperlrecipes/

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
oleber [ So, 29 August 2010 07:42 ] [ ID #2046823 ]

Re: How to test Output when using IPC::Open3

On Aug 28, 10:42=A0pm, ole... [at] gmail.com (marcos rebelo) wrote:
> the idea is to process the STDOUT ad the STDERR.
>
> open don't do it
>

I was afraid you'd say that...

open3 is very liable to deadlock since you're trying to read from
both stderr and stdout. You'll very likely want to use IO::Select
to marshal when the read's occur and search for some sample
code.

>
> On Sun, Aug 29, 2010 at 6:08 AM, John W. Krahn <jwkr... [at] shaw.ca> wrote:
>
>
>
> > C.DeRykus wrote:
>
> >> Since you mention simplifying the code, do you actually
> >> need IPC::Open3 ? =A0In your sample code, you're only
> >> reading process output.
>
> >> If you don't need IPC::Open3 complexity, you could just
> >> use magic open to read output :
>
> >> sub shell_run
> >> {
> >> =A0 =A0 print "YYYY";
> >> =A0 =A0 my $pid =3D open( my $fh, qq{ [at] _ | } ) =A0or die "open: $!";
>
> > Probably better as:
>
> > =A0 =A0 =A0my $pid =3D open my $fh, '-|', [at] _ or die "open: $!";


In general yes but here I don't think there's a benefit.
I believe perl will bypass the shell in both cases since
a list is passed. And, IIRC, perl launches a shell only
after parsing to see if it's absolutely required.


>
> > And you don't use $pid anywhere so why create it?

Agreed, I was trying to guage the OP's intention more
than cleaning up all the code.

>
> >> =A0 =A0 print for<$fh>;
>
> > Probably better as:
>
> > =A0 =A0 =A0print while <$fh>;

Hm, I'd prefer 'while' as well but, though it may look odd, I
don't think there's been the penalty of 'for <$fh>' creating
and then iterating through a potentially large list for some
time.

>
> >> =A0 =A0 close $fh =A0or die "close: ", $? || $!;
>
> > Probably better as:
>
> > =A0 =A0 =A0close $fh or die $! ? "Error closing pipe: $!"
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0: "Exit status $? fr=
om $_[0]";

Definitely better. A child error might mask an
error for a full disk.

--
Charles DeRykus


--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
derykus [ Mo, 30 August 2010 06:32 ] [ ID #2046896 ]

Re: How to test Output when using IPC::Open3

We are out of contest in here.

I know how to run open3, but I don't know how to test it. Repeating

use strict;
use warnings;
use IPC::Open3;
use IO::Handle;
use Test::More;
use Test::Trap;

sub shell_run {
my ($stdin, $stdout, $stderr) =3D map {IO::Handle->new} (0..2);

print "YYYY";

open3($stdin, $stdout, $stderr, [at] _);

foreach my $line (<$stdout>, <$stderr>) {
print "read: $line";
}

print "ZZZZ";
}

trap {shell_run('perl', '-E', 'print "TEXT IN"')};

#is( $trap->stdout, "YYYYZZZZ");
is( $trap->stdout, "YYYYTEXT INZZZZ");

done_testing();

How do I make that test pass?




or this:

trap {shell_run('perl', '-E', 'print STDERR "TEXT IN"')};
is( $trap->stdout, "YYYYTEXT INZZZZ");


Thanks
Marcos

On Mon, Aug 30, 2010 at 6:32 AM, C.DeRykus <derykus [at] gmail.com> wrote:
> On Aug 28, 10:42=A0pm, ole... [at] gmail.com (marcos rebelo) wrote:
>> the idea is to process the STDOUT ad the STDERR.
>>
>> open don't do it
>>
>
> I was afraid you'd say that...
>
> open3 is very liable to deadlock since you're trying to read from
> both stderr and stdout. =A0You'll very likely want to use IO::Select
> to marshal when the read's occur and search for some sample
> code.
>
>>
>> On Sun, Aug 29, 2010 at 6:08 AM, John W. Krahn <jwkr... [at] shaw.ca> wrote:
>>
>>
>>
>> > C.DeRykus wrote:
>>
>> >> Since you mention simplifying the code, do you actually
>> >> need IPC::Open3 ? =A0In your sample code, you're only
>> >> reading process output.
>>
>> >> If you don't need IPC::Open3 complexity, you could just
>> >> use magic open to read output :
>>
>> >> sub shell_run
>> >> {
>> >> =A0 =A0 print "YYYY";
>> >> =A0 =A0 my $pid =3D open( my $fh, qq{ [at] _ | } ) =A0or die "open: $!";
>>
>> > Probably better as:
>>
>> > =A0 =A0 =A0my $pid =3D open my $fh, '-|', [at] _ or die "open: $!";
>
>
> In general yes but here I don't think there's a benefit.
> I believe perl will bypass =A0the shell in both cases since
> a list is passed. And, IIRC, =A0perl launches a shell only
> after parsing to see if it's absolutely required.
>
>
>>
>> > And you don't use $pid anywhere so why create it?
>
> Agreed, I was trying to guage the OP's intention more
> than cleaning up all the code.
>
>>
>> >> =A0 =A0 print for<$fh>;
>>
>> > Probably better as:
>>
>> > =A0 =A0 =A0print while <$fh>;
>
> Hm, I'd prefer 'while' as well but, though it may look odd, I
> don't think there's been the =A0penalty of 'for <$fh>' creating
> and then iterating =A0through a potentially large list =A0for some
> time.
>
>>
>> >> =A0 =A0 close $fh =A0or die "close: ", $? || $!;
>>
>> > Probably better as:
>>
>> > =A0 =A0 =A0close $fh or die $! ? "Error closing pipe: $!"
>> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0: "Exit status $? f=
rom $_[0]";
>
> Definitely better. A child error might mask an
> error for a full disk.
>
> --
> Charles DeRykus
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
> For additional commands, e-mail: beginners-help [at] perl.org
> http://learn.perl.org/
>
>
>



--
Marcos Rebelo
http://oleber.freehostia.com
Milan Perl Mongers leader http://milan.pm.org
Webmaster of http://sites.google.com/site/oleberperlrecipes/

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
oleber [ Mo, 30 August 2010 07:46 ] [ ID #2046898 ]

Re: How to test Output when using IPC::Open3

On Aug 29, 10:46=A0pm, ole... [at] gmail.com (marcos rebelo) wrote:
> We are out of contest in here.
>
> I know how to run open3, but I don't know how to test it. Repeating
>

Hm, I just wanted to warn you that Open3 may
easily require more paranoia than you've shown...
your sample is simple enough to escape problems
but deadlock often lurks, especially if lots of data is
sent down the pipe. IO::Select can help with this.

Meanwhile, I made a few tweaks to your program
which now works for me (at least on FreeBSD).

* Take a look at the Test::Trap reviews on CPAN,
for useful info on the the 'use Test::Trap ...' import
list, especially Shlomi's.

--
Charles DeRykus

use strict;
use warnings;

use IPC::Open3;
use IO::Handle;
use Test::More;
use Test::Trap qw(
trap $trap
:flow
:stderr(systemsafe)
:stdout(systemsafe)
:warn
);

$| =3D 1;

sub shell_run {
my ($stdin, $stdout, $stderr) =3D map {IO::Handle->new} (0..2);

print "YYYY";

open3($stdin, $stdout, $stderr, [at] _);

close( $stdin ) or die "close: $! $ [at] ";

foreach my $line ( ( defined $stderr ? <$stderr> : () ),
( defined $stdout ? <$stdout> : () ) )
{
print $line;
}

print "ZZZZ";

close ( $stderr ) if defined $stderr;
close ( $stdout ) if defined $stdout;

}

trap {shell_run('perl', '-e', 'print "TEXT IN"')};

is( $trap->stdout, "YYYYTEXT INZZZZ");

done_testing();
__END__

-----> ok 1
1..1


--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
derykus [ Mi, 01 September 2010 05:54 ] [ ID #2046994 ]
Perl » gmane.comp.lang.perl.beginners » How to test Output when using IPC::Open3

Vorheriges Thema: testing tcp connection
Nächstes Thema: Short survey concerning the use of software engineering in the fieldof High Performance Computing