Subject: | Tests are blocking in Windows 7. With a prposed patch. |
Problem:
The tests in Test::TCP are blocking. Sometimes get the system in state,
that it must be restarted.
I am using:
* Strawberry-perl-5.12.2.0
* Perl 5, version 12, subversion 2 (v5.12.2) built for
MSWin32-x86-multi-thread
* Windows 7 Home Premium with Service Pack 1
Proposal of change to Test-TCP.
===============================
Attached is a patch.
The purpose of the patch is to:
1) Reduce the frequency of problems when using kill on a pseudo-proccess
in Windows.
2) To avoid to use kill on a pseudo-process in the test of Test-TCP.
See also "A safer way to kill pseudo-forked processes on Windows?" in
http://www.gossamer-threads.com/lists/perl/porters/261805.
This is to reduce the frequency when sub stop or "sub DESTROY" is used:
+ # kill is inherently unsafe for pseudo-processes in Windows
+ # and the process calling kill(9, $pid) may be destabilized
+ # The call to Sleep will decrease the frequency of this problems
+ Win32::Sleep(0) if $^O eq "MSWin32"; # will relinquish the
remainder of its time slice
+
kill $TERMSIG => $self->{pid};
+
+ Win32::Sleep(0) if $^O eq "MSWin32"; # will relinquish the
remainder of its time slice
+
Other things that perhaps all should be changed.
=================================================
In t/01_simple.t
What is the purpose of "for 1..10" in this:
ok $port, "test case for sharedfork" for 1..10;
Can the test for "leaks" be removed? An example is:
if ($?) {
# It's maybe ActivePerl's bug.
#
http://ppm4.activestate.com/MSWin32-x86/5.12/1200/T/TO/TOKUHIROM/Test-TCP-1.11.d/log-20101221T221845.txt
diag "test_tcp() leaks \$?. Maybe it's Perl bug?: $?";
$? = 0;
}
Tests made 1.
=============
Batchfile used:
@echo off
set count=0
:loop
set /a count=%count%+1
echo Count %count%
@echo on
perl -Ilib -Iinc t/00_compile.t
perl -Ilib -Iinc t/01_simple.t
perl -Ilib -Iinc t/02_abrt.t
perl -Ilib -Iinc t/03_return_when_sigterm.t
perl -Ilib -Iinc t/04_die.t
perl -Ilib -Iinc t/05_sigint.t
perl -Ilib -Iinc t/06_nest.t
perl -Ilib -Iinc t/07_optional.t
perl -Ilib -Iinc t/08_exit.t
perl -Ilib -Iinc t/09_fork.t
perl -Ilib -Iinc t/10_oo.t
@echo off
goto loop
See example of output in attached file log1.txt.
Run more than 1000 loops without blocking.
Tests made 2.
=============
Batchfile used:
@echo off
set count=0
:loop
set /a count=%count%+1
echo Count %count%
@echo on
perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'inc', 'lib')"
t/00_compile.t t/01_simple.t t/02_abrt.t t/03_return_when_sigterm.t
t/04_die.t t/05_sigint.t t/06_nest.t t/07_optional.t t/08_exit.t
t/09_fork.t t/10_oo.t
@echo off
goto loop
See example of output in attached file log2.txt.
Run more than 1000 loops without blocking.
Subject: | log1.txt |
Count 1090
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/00_compile.t
1..1
ok 1 - use Test::TCP;
# Test::More: 0.98
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/01_simple.t
1..22
ok 1 - test case for sharedfork
ok 2 - test case for sharedfork
ok 3 - test case for sharedfork
ok 4 - test case for sharedfork
ok 5 - test case for sharedfork
ok 6 - test case for sharedfork
ok 7 - test case for sharedfork
ok 8 - test case for sharedfork
ok 9 - test case for sharedfork
ok 10 - test case for sharedfork
ok 11 - test case for sharedfork
ok 12 - test case for sharedfork
ok 13 - test case for sharedfork
ok 14 - test case for sharedfork
ok 15 - test case for sharedfork
ok 16 - test case for sharedfork
ok 17 - test case for sharedfork
ok 18 - test case for sharedfork
ok 19 - test case for sharedfork
ok 20 - test case for sharedfork
# send 1
# new request
ok 21
# send 2
# new request
ok 22
# finalize
# new request
# server exit
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/02_abrt.t
1..0 # SKIP win32 doesn't support embedded function named dump()
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/03_return_when_sigterm.t
1..2
ok 1
ok 2 - test finished.
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/04_die.t
1..3
ok 1
ok 2
ok 3 - already killed by test_tcp
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/05_sigint.t
1..0 # SKIP this test requires SIGUSR1
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/06_nest.t
1..1
ok 1 - 10375, 10635
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/07_optional.t
1..2
ok 1 - One
ok 2 - Two
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/08_exit.t
1..5
# SEVER: -1120
# CLIENT: -3376
ok 1 # skip not implemented on Win32
ok 2 # skip not implemented on Win32
ok 3 # skip not implemented on Win32
ok 4 # skip not implemented on Win32
ok 5
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/09_fork.t
1..6
ok 1 - Successfully forked child -3120
ok 2 - Successfully forked child 0
ok 3 - Successfully executed child -3120
ok 4 - child exited normally
ok 5 - socket is connected
# new request
ok 6 - got expected reply
# finalize
# new request
# server exit
# exit
s:\wp\wpPerl\wpTestTcp>perl -Ilib -Iinc t/10_oo.t
1..22
ok 1 - test case for sharedfork
ok 2 - test case for sharedfork
ok 3 - test case for sharedfork
ok 4 - test case for sharedfork
ok 5 - test case for sharedfork
ok 6 - test case for sharedfork
ok 7 - test case for sharedfork
ok 8 - test case for sharedfork
ok 9 - test case for sharedfork
ok 10 - test case for sharedfork
ok 11 - test case for sharedfork
ok 12 - test case for sharedfork
ok 13 - test case for sharedfork
ok 14 - test case for sharedfork
ok 15 - test case for sharedfork
ok 16 - test case for sharedfork
ok 17 - test case for sharedfork
ok 18 - test case for sharedfork
ok 19 - test case for sharedfork
ok 20 - test case for sharedfork
# send 1
# new request
ok 21
# send 2
# new request
ok 22
# finalize
# new request
# server exit
# exit
Count 1091
Subject: | log2.txt |
Count 1056
s:\wp\wpPerl\wpTestTcp>perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'inc', 'lib')" t/00_compile.t t/01_simple.t t/02_abrt.t t/03_return_when_sigterm.t t/04_die.t t/05_sigint.t t/06_nest.t t/07_optional.t t/08_exit.t t/09_fork.t t/10_oo.t
t/00_compile.t .............. ok
t/01_simple.t ............... ok
t/02_abrt.t ................. skipped: win32 doesn't support embedded function named dump()
t/03_return_when_sigterm.t .. ok
t/04_die.t .................. ok
t/05_sigint.t ............... skipped: this test requires SIGUSR1
t/06_nest.t ................. ok
t/07_optional.t ............. ok
t/08_exit.t ................. ok
t/09_fork.t ................. ok
t/10_oo.t ................... ok
All tests successful.
Files=11, Tests=64, 25 wallclock secs ( 0.19 usr + 0.08 sys = 0.27 CPU)
Result: PASS
Count 1057
Subject: | patch.txt |
diff -ur dist/lib/Test/TCP.pm modified/lib/Test/TCP.pm
--- dist/lib/Test/TCP.pm 2011-03-03 08:14:40.000000000 +0100
+++ modified/lib/Test/TCP.pm 2011-04-06 09:50:38.979000000 +0200
@@ -52,7 +52,7 @@
port => $args{port} || empty_port(),
);
$args{client}->($server->port, $server->pid);
- undef $server; # make sure
+ return $server;
}
sub _check_port {
@@ -130,7 +130,15 @@
return unless defined $self->{pid};
return unless $self->{_my_pid} == $$;
+ # kill is inherently unsafe for pseudo-processes in Windows
+ # and the process calling kill(9, $pid) may be destabilized
+ # The call to Sleep will decrease the frequency of this problems
+ Win32::Sleep(0) if $^O eq "MSWin32"; # will relinquish the remainder of its time slice
+
kill $TERMSIG => $self->{pid};
+
+ Win32::Sleep(0) if $^O eq "MSWin32"; # will relinquish the remainder of its time slice
+
local $?; # waitpid modifies original $?.
LOOP: while (1) {
my $kid = waitpid( $self->{pid}, 0 );
diff -ur dist/t/01_simple.t modified/t/01_simple.t
--- dist/t/01_simple.t 2010-08-15 15:21:39.000000000 +0200
+++ modified/t/01_simple.t 2011-04-06 23:21:19.257000000 +0200
@@ -27,6 +27,7 @@
note "finalize";
print {$sock} "quit\n";
+ sleep(1);
},
server => sub {
my $port = shift;
@@ -34,8 +35,11 @@
t::Server->new($port)->run(sub {
note "new request";
my ($remote, $line, $sock) = @_;
+ if ($line eq "quit\n"){
+ note "server exit";
+ exit 0;
+ };
print {$remote} $line;
});
},
);
-
diff -ur dist/t/08_exit.t modified/t/08_exit.t
--- dist/t/08_exit.t 2010-08-24 06:08:16.000000000 +0200
+++ modified/t/08_exit.t 2011-04-06 23:29:18.714200000 +0200
@@ -36,6 +36,7 @@
test_tcp(
client => sub {
my $port = shift;
+ Win32::Sleep(100) if $^O eq "MSWin32"; # will relinquish the remainder of its time slice
note "CLIENT: $$";
exit 1;
},
diff -ur dist/t/09_fork.t modified/t/09_fork.t
--- dist/t/09_fork.t 2011-03-03 08:13:54.000000000 +0100
+++ modified/t/09_fork.t 2011-04-06 23:27:41.947400000 +0200
@@ -3,7 +3,7 @@
use Test::TCP;
use t::Server;
-test_tcp
+my $server = test_tcp
client => sub {
my $port = shift;
@@ -39,20 +39,32 @@
print {$sock} "Hello server\n";
my $res = <$sock>;
is $res, "Hello server\n", "got expected reply";
+
+ note "finalize";
+ print {$sock} "quit\n";
+ sleep(1);
},
server => sub {
my $port = shift;
t::Server->new($port)->run(sub {
note "new request";
my ($remote, $line, $sock) = @_;
+ if ($line eq "quit\n"){
+ note "server exit";
+ exit 0;
+ };
print {$remote} $line;
});
}
;
+$server->stop;
+
if ($?) {
# It's maybe ActivePerl's bug.
# http://ppm4.activestate.com/MSWin32-x86/5.12/1200/T/TO/TOKUHIROM/Test-TCP-1.11.d/log-20101221T221845.txt
diag "test_tcp() leaks \$?. Maybe it's Perl bug?: $?";
$? = 0;
}
+
+note "exit";
\ Ingen nyrad vid filslut
diff -ur dist/t/10_oo.t modified/t/10_oo.t
--- dist/t/10_oo.t 2011-03-03 08:13:56.000000000 +0100
+++ modified/t/10_oo.t 2011-04-06 23:29:04.393400000 +0200
@@ -12,6 +12,10 @@
t::Server->new($port)->run(sub {
note "new request";
my ($remote, $line, $sock) = @_;
+ if ($line eq "quit\n"){ # shut down server
+ note "server exit";
+ exit 0;
+ };
print {$remote} $line;
});
}
@@ -35,7 +39,8 @@
is $res2, "bar\n";
note "finalize";
-print {$sock} "quit\n";
+print {$sock} "quit\n"; # Shut down the server
+sleep(1);
if ($?) {
# It's maybe ActivePerl's bug.
@@ -43,6 +48,6 @@
diag "test_tcp() leaks \$?. Maybe it's Perl bug?: $?";
$? = 0;
}
-
+note "exit";
done_testing;