15759b3d2Safresh1use strict; 25759b3d2Safresh1use warnings; 35759b3d2Safresh1 45759b3d2Safresh1use Test2::IPC; 55759b3d2Safresh1use Test2::Tools::Tiny; 65759b3d2Safresh1use Test2::Util qw/CAN_THREAD CAN_REALLY_FORK USE_THREADS get_tid/; 75759b3d2Safresh1 85759b3d2Safresh1ok(1, "Just to get things initialized."); 95759b3d2Safresh1 10*5486feefSafresh1# We need to control these env vars for this test 115759b3d2Safresh1$ENV{T2_NO_IPC} = 0; 12*5486feefSafresh1$ENV{T2_TRACE_STAMPS} = 0; 135759b3d2Safresh1# This test relies on TAP being the default formatter for non-canon instances 145759b3d2Safresh1$ENV{T2_FORMATTER} = 'TAP'; 155759b3d2Safresh1 165759b3d2Safresh1my $CLASS = 'Test2::API::Instance'; 175759b3d2Safresh1 185759b3d2Safresh1my $one = $CLASS->new; 195759b3d2Safresh1is_deeply( 205759b3d2Safresh1 $one, 215759b3d2Safresh1 { 225759b3d2Safresh1 contexts => {}, 235759b3d2Safresh1 245759b3d2Safresh1 finalized => undef, 255759b3d2Safresh1 ipc => undef, 265759b3d2Safresh1 formatter => undef, 275759b3d2Safresh1 285759b3d2Safresh1 add_uuid_via => undef, 295759b3d2Safresh1 305759b3d2Safresh1 ipc_polling => undef, 315759b3d2Safresh1 ipc_drivers => [], 325759b3d2Safresh1 ipc_timeout => 30, 335759b3d2Safresh1 ipc_disabled => 0, 345759b3d2Safresh1 355759b3d2Safresh1 formatters => [], 365759b3d2Safresh1 375759b3d2Safresh1 no_wait => 0, 385759b3d2Safresh1 loaded => 0, 395759b3d2Safresh1 405759b3d2Safresh1 exit_callbacks => [], 415759b3d2Safresh1 post_load_callbacks => [], 425759b3d2Safresh1 context_acquire_callbacks => [], 435759b3d2Safresh1 context_init_callbacks => [], 445759b3d2Safresh1 context_release_callbacks => [], 455759b3d2Safresh1 pre_subtest_callbacks => [], 465759b3d2Safresh1 47*5486feefSafresh1 trace_stamps => 0, 48*5486feefSafresh1 495759b3d2Safresh1 stack => [], 505759b3d2Safresh1 }, 515759b3d2Safresh1 "Got initial settings" 525759b3d2Safresh1); 535759b3d2Safresh1 545759b3d2Safresh1%$one = (); 555759b3d2Safresh1is_deeply($one, {}, "wiped object"); 565759b3d2Safresh1 575759b3d2Safresh1$one->reset; 585759b3d2Safresh1is_deeply( 595759b3d2Safresh1 $one, 605759b3d2Safresh1 { 615759b3d2Safresh1 contexts => {}, 625759b3d2Safresh1 635759b3d2Safresh1 ipc_polling => undef, 645759b3d2Safresh1 ipc_drivers => [], 655759b3d2Safresh1 ipc_timeout => 30, 665759b3d2Safresh1 ipc_disabled => 0, 675759b3d2Safresh1 685759b3d2Safresh1 add_uuid_via => undef, 695759b3d2Safresh1 705759b3d2Safresh1 formatters => [], 715759b3d2Safresh1 725759b3d2Safresh1 finalized => undef, 735759b3d2Safresh1 ipc => undef, 745759b3d2Safresh1 formatter => undef, 755759b3d2Safresh1 765759b3d2Safresh1 no_wait => 0, 775759b3d2Safresh1 loaded => 0, 785759b3d2Safresh1 795759b3d2Safresh1 exit_callbacks => [], 805759b3d2Safresh1 post_load_callbacks => [], 815759b3d2Safresh1 context_acquire_callbacks => [], 825759b3d2Safresh1 context_init_callbacks => [], 835759b3d2Safresh1 context_release_callbacks => [], 845759b3d2Safresh1 pre_subtest_callbacks => [], 855759b3d2Safresh1 86*5486feefSafresh1 trace_stamps => 0, 87*5486feefSafresh1 885759b3d2Safresh1 stack => [], 895759b3d2Safresh1 }, 905759b3d2Safresh1 "Reset Object" 915759b3d2Safresh1); 925759b3d2Safresh1 935759b3d2Safresh1ok(!$one->formatter_set, "no formatter set"); 945759b3d2Safresh1$one->set_formatter('Foo'); 955759b3d2Safresh1ok($one->formatter_set, "formatter set"); 965759b3d2Safresh1$one->reset; 975759b3d2Safresh1 985759b3d2Safresh1my $ran = 0; 995759b3d2Safresh1my $callback = sub { $ran++ }; 1005759b3d2Safresh1$one->add_post_load_callback($callback); 1015759b3d2Safresh1ok(!$ran, "did not run yet"); 1025759b3d2Safresh1is_deeply($one->post_load_callbacks, [$callback], "stored callback for later"); 1035759b3d2Safresh1 1045759b3d2Safresh1ok(!$one->loaded, "not loaded"); 1055759b3d2Safresh1$one->load; 1065759b3d2Safresh1ok($one->loaded, "loaded"); 1075759b3d2Safresh1is($ran, 1, "ran the callback"); 1085759b3d2Safresh1 1095759b3d2Safresh1$one->load; 1105759b3d2Safresh1is($ran, 1, "Did not run the callback again"); 1115759b3d2Safresh1 1125759b3d2Safresh1$one->add_post_load_callback($callback); 1135759b3d2Safresh1is($ran, 2, "ran the new callback"); 1145759b3d2Safresh1is_deeply($one->post_load_callbacks, [$callback, $callback], "stored callback for the record"); 1155759b3d2Safresh1 1165759b3d2Safresh1like( 1175759b3d2Safresh1 exception { $one->add_post_load_callback({}) }, 1185759b3d2Safresh1 qr/Post-load callbacks must be coderefs/, 1195759b3d2Safresh1 "Post-load callbacks must be coderefs" 1205759b3d2Safresh1); 1215759b3d2Safresh1 1225759b3d2Safresh1$one->reset; 1235759b3d2Safresh1ok($one->ipc, 'got ipc'); 1245759b3d2Safresh1ok($one->finalized, "calling ipc finalized the object"); 1255759b3d2Safresh1 1265759b3d2Safresh1$one->reset; 1275759b3d2Safresh1ok($one->stack, 'got stack'); 1285759b3d2Safresh1ok(!$one->finalized, "calling stack did not finaliz the object"); 1295759b3d2Safresh1 1305759b3d2Safresh1$one->reset; 1315759b3d2Safresh1ok($one->formatter, 'Got formatter'); 1325759b3d2Safresh1ok($one->finalized, "calling format finalized the object"); 1335759b3d2Safresh1 1345759b3d2Safresh1$one->reset; 1355759b3d2Safresh1$one->set_formatter('Foo'); 1365759b3d2Safresh1is($one->formatter, 'Foo', "got specified formatter"); 1375759b3d2Safresh1ok($one->finalized, "calling format finalized the object"); 1385759b3d2Safresh1 1395759b3d2Safresh1{ 1405759b3d2Safresh1 local $ENV{T2_FORMATTER} = 'TAP'; 141f3efcd01Safresh1 my $one = $CLASS->new; 1425759b3d2Safresh1 is($one->formatter, 'Test2::Formatter::TAP', "got specified formatter"); 1435759b3d2Safresh1 ok($one->finalized, "calling format finalized the object"); 1445759b3d2Safresh1 1455759b3d2Safresh1 local $ENV{T2_FORMATTER} = '+Test2::Formatter::TAP'; 1465759b3d2Safresh1 $one->reset; 1475759b3d2Safresh1 is($one->formatter, 'Test2::Formatter::TAP', "got specified formatter"); 1485759b3d2Safresh1 ok($one->finalized, "calling format finalized the object"); 1495759b3d2Safresh1 1505759b3d2Safresh1 local $ENV{T2_FORMATTER} = '+A::Fake::Module::That::Should::Not::Exist'; 1515759b3d2Safresh1 $one->reset; 1525759b3d2Safresh1 like( 1535759b3d2Safresh1 exception { $one->formatter }, 1545759b3d2Safresh1 qr/COULD NOT LOAD FORMATTER 'A::Fake::Module::That::Should::Not::Exist' \(set by the 'T2_FORMATTER' environment variable\)/, 1555759b3d2Safresh1 "Bad formatter" 1565759b3d2Safresh1 ); 1575759b3d2Safresh1} 1585759b3d2Safresh1 1595759b3d2Safresh1$ran = 0; 1605759b3d2Safresh1$one->reset; 1615759b3d2Safresh1$one->add_exit_callback($callback); 1625759b3d2Safresh1is(@{$one->exit_callbacks}, 1, "added an exit callback"); 1635759b3d2Safresh1$one->add_exit_callback($callback); 1645759b3d2Safresh1is(@{$one->exit_callbacks}, 2, "added another exit callback"); 1655759b3d2Safresh1 1665759b3d2Safresh1like( 1675759b3d2Safresh1 exception { $one->add_exit_callback({}) }, 1685759b3d2Safresh1 qr/End callbacks must be coderefs/, 1695759b3d2Safresh1 "Exit callbacks must be coderefs" 1705759b3d2Safresh1); 1715759b3d2Safresh1 1725759b3d2Safresh1$one->reset; 1735759b3d2Safresh1$one->add_pre_subtest_callback($callback); 1745759b3d2Safresh1is(@{$one->pre_subtest_callbacks}, 1, "added a pre-subtest callback"); 1755759b3d2Safresh1$one->add_pre_subtest_callback($callback); 1765759b3d2Safresh1is(@{$one->pre_subtest_callbacks}, 2, "added another pre-subtest callback"); 1775759b3d2Safresh1 1785759b3d2Safresh1like( 1795759b3d2Safresh1 exception { $one->add_pre_subtest_callback({}) }, 1805759b3d2Safresh1 qr/Pre-subtest callbacks must be coderefs/, 1815759b3d2Safresh1 "Pre-subtest callbacks must be coderefs" 1825759b3d2Safresh1); 1835759b3d2Safresh1 1845759b3d2Safresh1if (CAN_REALLY_FORK) { 185f3efcd01Safresh1 my $one = $CLASS->new; 1865759b3d2Safresh1 my $pid = fork; 1875759b3d2Safresh1 die "Failed to fork!" unless defined $pid; 1885759b3d2Safresh1 unless($pid) { exit 0 } 1895759b3d2Safresh1 1905759b3d2Safresh1 is(Test2::API::Instance::_ipc_wait, 0, "No errors"); 1915759b3d2Safresh1 1925759b3d2Safresh1 $pid = fork; 1935759b3d2Safresh1 die "Failed to fork!" unless defined $pid; 1945759b3d2Safresh1 unless($pid) { exit 255 } 1955759b3d2Safresh1 my @warnings; 1965759b3d2Safresh1 { 1975759b3d2Safresh1 local $SIG{__WARN__} = sub { push @warnings => @_ }; 1985759b3d2Safresh1 is(Test2::API::Instance::_ipc_wait, 255, "Process exited badly"); 1995759b3d2Safresh1 } 2005759b3d2Safresh1 like($warnings[0], qr/Process .* did not exit cleanly \(wstat: \S+, exit: 255, sig: 0\)/, "Warn about exit"); 2015759b3d2Safresh1 2025759b3d2Safresh1 $pid = fork; 2035759b3d2Safresh1 die "Failed to fork!" unless defined $pid; 2045759b3d2Safresh1 unless($pid) { sleep 20; exit 0 } 2055759b3d2Safresh1 kill('TERM', $pid) or die "Failed to send signal"; 2065759b3d2Safresh1 @warnings = (); 2075759b3d2Safresh1 { 2085759b3d2Safresh1 local $SIG{__WARN__} = sub { push @warnings => @_ }; 2095759b3d2Safresh1 is(Test2::API::Instance::_ipc_wait, 255, "Process exited badly"); 2105759b3d2Safresh1 } 2115759b3d2Safresh1 like($warnings[0], qr/Process .* did not exit cleanly \(wstat: \S+, exit: 0, sig: 15\)/, "Warn about exit"); 2125759b3d2Safresh1} 2135759b3d2Safresh1 2145759b3d2Safresh1if (CAN_THREAD && $] ge '5.010') { 2155759b3d2Safresh1 require threads; 216f3efcd01Safresh1 my $one = $CLASS->new; 2175759b3d2Safresh1 2185759b3d2Safresh1 threads->new(sub { 1 }); 2195759b3d2Safresh1 is(Test2::API::Instance::_ipc_wait, 0, "No errors"); 2205759b3d2Safresh1 2215759b3d2Safresh1 if (threads->can('error')) { 2225759b3d2Safresh1 threads->new(sub { 2235759b3d2Safresh1 close(STDERR); 2245759b3d2Safresh1 close(STDOUT); 2255759b3d2Safresh1 die "xxx" 2265759b3d2Safresh1 }); 2275759b3d2Safresh1 my @warnings; 2285759b3d2Safresh1 { 2295759b3d2Safresh1 local $SIG{__WARN__} = sub { push @warnings => @_ }; 2305759b3d2Safresh1 is(Test2::API::Instance::_ipc_wait, 255, "Thread exited badly"); 2315759b3d2Safresh1 } 2325759b3d2Safresh1 like($warnings[0], qr/Thread .* did not end cleanly: xxx/, "Warn about exit"); 2335759b3d2Safresh1 } 2345759b3d2Safresh1} 2355759b3d2Safresh1 2365759b3d2Safresh1{ 237f3efcd01Safresh1 my $one = $CLASS->new; 2385759b3d2Safresh1 local $? = 0; 2395759b3d2Safresh1 $one->set_exit; 2405759b3d2Safresh1 is($?, 0, "no errors on exit"); 2415759b3d2Safresh1} 2425759b3d2Safresh1 2435759b3d2Safresh1{ 244f3efcd01Safresh1 my $one = $CLASS->new; 2455759b3d2Safresh1 $one->set__tid(1); 2465759b3d2Safresh1 local $? = 0; 2475759b3d2Safresh1 $one->set_exit; 2485759b3d2Safresh1 is($?, 0, "no errors on exit"); 2495759b3d2Safresh1} 2505759b3d2Safresh1 2515759b3d2Safresh1{ 252f3efcd01Safresh1 my $one = $CLASS->new; 2535759b3d2Safresh1 $one->stack->top; 254*5486feefSafresh1 $one->set_no_wait(1); 2555759b3d2Safresh1 local $? = 0; 2565759b3d2Safresh1 $one->set_exit; 2575759b3d2Safresh1 is($?, 0, "no errors on exit"); 2585759b3d2Safresh1} 2595759b3d2Safresh1 2605759b3d2Safresh1{ 261f3efcd01Safresh1 my $one = $CLASS->new; 2625759b3d2Safresh1 $one->stack->top->set_no_ending(1); 2635759b3d2Safresh1 local $? = 0; 2645759b3d2Safresh1 $one->set_exit; 2655759b3d2Safresh1 is($?, 0, "no errors on exit"); 2665759b3d2Safresh1} 2675759b3d2Safresh1 2685759b3d2Safresh1{ 269f3efcd01Safresh1 my $one = $CLASS->new; 2705759b3d2Safresh1 $one->load(); 2715759b3d2Safresh1 $one->stack->top->set_failed(2); 2725759b3d2Safresh1 local $? = 0; 2735759b3d2Safresh1 $one->set_exit; 2745759b3d2Safresh1 is($?, 2, "number of failures"); 2755759b3d2Safresh1} 2765759b3d2Safresh1 2775759b3d2Safresh1{ 278f3efcd01Safresh1 my $one = $CLASS->new; 2795759b3d2Safresh1 $one->load(); 2805759b3d2Safresh1 local $? = 500; 2815759b3d2Safresh1 $one->set_exit; 2825759b3d2Safresh1 is($?, 255, "set exit code to a sane number"); 2835759b3d2Safresh1} 2845759b3d2Safresh1 2855759b3d2Safresh1{ 2865759b3d2Safresh1 local %INC = %INC; 2875759b3d2Safresh1 delete $INC{'Test2/IPC.pm'}; 288f3efcd01Safresh1 my $one = $CLASS->new; 2895759b3d2Safresh1 $one->load(); 2905759b3d2Safresh1 my @events; 2915759b3d2Safresh1 $one->stack->top->filter(sub { push @events => $_[1]; undef}); 2925759b3d2Safresh1 $one->stack->new_hub; 2935759b3d2Safresh1 local $? = 0; 2945759b3d2Safresh1 $one->set_exit; 2955759b3d2Safresh1 is($?, 255, "errors on exit"); 2965759b3d2Safresh1 like($events[0]->message, qr/Test ended with extra hubs on the stack!/, "got diag"); 2975759b3d2Safresh1} 2985759b3d2Safresh1 2995759b3d2Safresh1SKIP: { 3005759b3d2Safresh1 last SKIP if $] lt "5.008"; 301f3efcd01Safresh1 my $one = $CLASS->new; 3025759b3d2Safresh1 my $stderr = ""; 3035759b3d2Safresh1 { 3045759b3d2Safresh1 local $INC{'Test/Builder.pm'} = __FILE__; 3055759b3d2Safresh1 local $Test2::API::VERSION = '0.002'; 3065759b3d2Safresh1 local $Test::Builder::VERSION = '0.001'; 3075759b3d2Safresh1 local *STDERR; 3085759b3d2Safresh1 open(STDERR, '>', \$stderr) or print "Failed to open new STDERR"; 3095759b3d2Safresh1 3105759b3d2Safresh1 $one->set_exit; 3115759b3d2Safresh1 } 3125759b3d2Safresh1 3135759b3d2Safresh1 is($stderr, <<' EOT', "Got warning about version mismatch"); 3145759b3d2Safresh1 3155759b3d2Safresh1******************************************************************************** 3165759b3d2Safresh1* * 3175759b3d2Safresh1* Test::Builder -- Test2::API version mismatch detected * 3185759b3d2Safresh1* * 3195759b3d2Safresh1******************************************************************************** 3205759b3d2Safresh1 Test2::API Version: 0.002 3215759b3d2Safresh1Test::Builder Version: 0.001 3225759b3d2Safresh1 3235759b3d2Safresh1This is not a supported configuration, you will have problems. 3245759b3d2Safresh1 3255759b3d2Safresh1 EOT 3265759b3d2Safresh1} 3275759b3d2Safresh1 3285759b3d2Safresh1SKIP: { 3295759b3d2Safresh1 last SKIP if $] lt "5.008"; 3305759b3d2Safresh1 require Test2::API::Breakage; 3315759b3d2Safresh1 no warnings qw/redefine once/; 3325759b3d2Safresh1 my $ran = 0; 3335759b3d2Safresh1 local *Test2::API::Breakage::report = sub { $ran++; return "foo" }; 3345759b3d2Safresh1 use warnings qw/redefine once/; 335f3efcd01Safresh1 my $one = $CLASS->new; 3365759b3d2Safresh1 $one->load(); 3375759b3d2Safresh1 3385759b3d2Safresh1 my $stderr = ""; 3395759b3d2Safresh1 { 3405759b3d2Safresh1 local *STDERR; 3415759b3d2Safresh1 open(STDERR, '>', \$stderr) or print "Failed to open new STDERR"; 3425759b3d2Safresh1 local $? = 255; 3435759b3d2Safresh1 $one->set_exit; 3445759b3d2Safresh1 } 3455759b3d2Safresh1 3465759b3d2Safresh1 is($stderr, <<" EOT", "Reported bad modules"); 3475759b3d2Safresh1 3485759b3d2Safresh1You have loaded versions of test modules known to have problems with Test2. 3495759b3d2Safresh1This could explain some test failures. 3505759b3d2Safresh1foo 3515759b3d2Safresh1 3525759b3d2Safresh1 EOT 3535759b3d2Safresh1} 3545759b3d2Safresh1 3555759b3d2Safresh1 3565759b3d2Safresh1{ 357f3efcd01Safresh1 my $one = $CLASS->new; 3585759b3d2Safresh1 $one->load(); 3595759b3d2Safresh1 my @events; 3605759b3d2Safresh1 $one->stack->top->filter(sub { push @events => $_[1]; undef}); 3615759b3d2Safresh1 $one->stack->new_hub; 3625759b3d2Safresh1 ok($one->stack->top->ipc, "Have IPC"); 3635759b3d2Safresh1 $one->stack->new_hub; 3645759b3d2Safresh1 ok($one->stack->top->ipc, "Have IPC"); 3655759b3d2Safresh1 $one->stack->top->set_ipc(undef); 3665759b3d2Safresh1 ok(!$one->stack->top->ipc, "no IPC"); 3675759b3d2Safresh1 $one->stack->new_hub; 3685759b3d2Safresh1 local $? = 0; 3695759b3d2Safresh1 $one->set_exit; 3705759b3d2Safresh1 is($?, 255, "errors on exit"); 3715759b3d2Safresh1 like($events[0]->message, qr/Test ended with extra hubs on the stack!/, "got diag"); 3725759b3d2Safresh1} 3735759b3d2Safresh1 3745759b3d2Safresh1if (CAN_REALLY_FORK) { 3755759b3d2Safresh1 local $SIG{__WARN__} = sub { }; 376f3efcd01Safresh1 my $one = $CLASS->new; 3775759b3d2Safresh1 my $pid = fork; 3785759b3d2Safresh1 die "Failed to fork!" unless defined $pid; 3795759b3d2Safresh1 unless ($pid) { exit 255 } 3805759b3d2Safresh1 $one->_finalize; 3815759b3d2Safresh1 $one->stack->top; 3825759b3d2Safresh1 3835759b3d2Safresh1 local $? = 0; 3845759b3d2Safresh1 $one->set_exit; 3855759b3d2Safresh1 is($?, 255, "errors on exit"); 3865759b3d2Safresh1 3875759b3d2Safresh1 $one->reset(); 3885759b3d2Safresh1 $pid = fork; 3895759b3d2Safresh1 die "Failed to fork!" unless defined $pid; 3905759b3d2Safresh1 unless ($pid) { exit 255 } 3915759b3d2Safresh1 $one->_finalize; 3925759b3d2Safresh1 $one->stack->top; 3935759b3d2Safresh1 3945759b3d2Safresh1 local $? = 122; 3955759b3d2Safresh1 $one->set_exit; 3965759b3d2Safresh1 is($?, 122, "kept original exit"); 3975759b3d2Safresh1} 3985759b3d2Safresh1 3995759b3d2Safresh1{ 400f3efcd01Safresh1 my $one = $CLASS->new; 4015759b3d2Safresh1 my $ctx = bless { 4025759b3d2Safresh1 trace => Test2::EventFacet::Trace->new(frame => ['Foo::Bar', 'Foo/Bar.pm', 42, 'xxx']), 4035759b3d2Safresh1 hub => Test2::Hub->new(), 4045759b3d2Safresh1 }, 'Test2::API::Context'; 4055759b3d2Safresh1 $one->contexts->{1234} = $ctx; 4065759b3d2Safresh1 4075759b3d2Safresh1 local $? = 500; 4085759b3d2Safresh1 my $warnings = warnings { $one->set_exit }; 4095759b3d2Safresh1 is($?, 255, "set exit code to a sane number"); 4105759b3d2Safresh1 4115759b3d2Safresh1 is_deeply( 4125759b3d2Safresh1 $warnings, 4135759b3d2Safresh1 [ 4145759b3d2Safresh1 "context object was never released! This means a testing tool is behaving very badly at Foo/Bar.pm line 42.\n" 4155759b3d2Safresh1 ], 4165759b3d2Safresh1 "Warned about unfreed context" 4175759b3d2Safresh1 ); 418f3efcd01Safresh1 $one->set_no_wait(0); 4195759b3d2Safresh1} 4205759b3d2Safresh1 4215759b3d2Safresh1{ 4225759b3d2Safresh1 local %INC = %INC; 4235759b3d2Safresh1 delete $INC{'Test2/IPC.pm'}; 4245759b3d2Safresh1 delete $INC{'threads.pm'}; 4255759b3d2Safresh1 ok(!USE_THREADS, "Sanity Check"); 4265759b3d2Safresh1 427f3efcd01Safresh1 my $one = $CLASS->new; 4285759b3d2Safresh1 ok(!$one->ipc, 'IPC not loaded, no IPC object'); 4295759b3d2Safresh1 ok($one->finalized, "calling ipc finalized the object"); 4305759b3d2Safresh1 is($one->ipc_polling, undef, "no polling defined"); 4315759b3d2Safresh1 ok(!@{$one->ipc_drivers}, "no driver"); 4325759b3d2Safresh1 4335759b3d2Safresh1 if (CAN_THREAD) { 4345759b3d2Safresh1 local $INC{'threads.pm'} = 1; 4355759b3d2Safresh1 no warnings 'once'; 4365759b3d2Safresh1 local *threads::tid = sub { 0 } unless threads->can('tid'); 4375759b3d2Safresh1 $one->reset; 4385759b3d2Safresh1 ok($one->ipc, 'IPC loaded if threads are'); 4395759b3d2Safresh1 ok($one->finalized, "calling ipc finalized the object"); 4405759b3d2Safresh1 ok($one->ipc_polling, "polling on by default"); 4415759b3d2Safresh1 is($one->ipc_drivers->[0], 'Test2::IPC::Driver::Files', "default driver"); 4425759b3d2Safresh1 } 4435759b3d2Safresh1 4445759b3d2Safresh1 { 4455759b3d2Safresh1 local $INC{'Test2/IPC.pm'} = 1; 4465759b3d2Safresh1 $one->reset; 4475759b3d2Safresh1 ok($one->ipc, 'IPC loaded if Test2::IPC is'); 4485759b3d2Safresh1 ok($one->finalized, "calling ipc finalized the object"); 4495759b3d2Safresh1 ok($one->ipc_polling, "polling on by default"); 4505759b3d2Safresh1 is($one->ipc_drivers->[0], 'Test2::IPC::Driver::Files', "default driver"); 4515759b3d2Safresh1 } 4525759b3d2Safresh1 4535759b3d2Safresh1 require Test2::IPC::Driver::Files; 4545759b3d2Safresh1 $one->reset; 4555759b3d2Safresh1 $one->add_ipc_driver('Test2::IPC::Driver::Files'); 4565759b3d2Safresh1 ok($one->ipc, 'IPC loaded if drivers have been added'); 4575759b3d2Safresh1 ok($one->finalized, "calling ipc finalized the object"); 4585759b3d2Safresh1 ok($one->ipc_polling, "polling on by default"); 4595759b3d2Safresh1 4605759b3d2Safresh1 my $file = __FILE__; 4615759b3d2Safresh1 my $line = __LINE__ + 1; 4625759b3d2Safresh1 my $warnings = warnings { $one->add_ipc_driver('Test2::IPC::Driver::Files') }; 4635759b3d2Safresh1 like( 4645759b3d2Safresh1 $warnings->[0], 4655759b3d2Safresh1 qr{^IPC driver Test2::IPC::Driver::Files loaded too late to be used as the global ipc driver at \Q$file\E line $line}, 4665759b3d2Safresh1 "Got warning at correct frame" 4675759b3d2Safresh1 ); 4685759b3d2Safresh1 4695759b3d2Safresh1 $one->reset; 4705759b3d2Safresh1 $one->add_ipc_driver('Fake::Fake::XXX'); 4715759b3d2Safresh1 is( 4725759b3d2Safresh1 exception { $one->ipc }, 4735759b3d2Safresh1 "IPC has been requested, but no viable drivers were found. Aborting...\n", 4745759b3d2Safresh1 "Failed without viable IPC driver" 4755759b3d2Safresh1 ); 4765759b3d2Safresh1} 4775759b3d2Safresh1 4785759b3d2Safresh1{ 479f3efcd01Safresh1 my $one = $CLASS->new; 480f3efcd01Safresh1 $one->{ipc} = Test2::IPC::Driver::Files->new; 4815759b3d2Safresh1 4825759b3d2Safresh1 ok(!@{$one->context_init_callbacks}, "no callbacks"); 4835759b3d2Safresh1 is($one->ipc_polling, undef, "no polling, undef"); 4845759b3d2Safresh1 4855759b3d2Safresh1 $one->disable_ipc_polling; 4865759b3d2Safresh1 ok(!@{$one->context_init_callbacks}, "no callbacks"); 4875759b3d2Safresh1 is($one->ipc_polling, undef, "no polling, still undef"); 4885759b3d2Safresh1 4895759b3d2Safresh1 my $cull = 0; 4905759b3d2Safresh1 no warnings 'once'; 4915759b3d2Safresh1 local *Fake::Hub::cull = sub { $cull++ }; 4925759b3d2Safresh1 use warnings; 4935759b3d2Safresh1 4945759b3d2Safresh1 $one->enable_ipc_polling; 4955759b3d2Safresh1 ok(defined($one->{_pid}), "pid is defined"); 4965759b3d2Safresh1 ok(defined($one->{_tid}), "tid is defined"); 4975759b3d2Safresh1 is(@{$one->context_init_callbacks}, 1, "added the callback"); 4985759b3d2Safresh1 is($one->ipc_polling, 1, "polling on"); 4995759b3d2Safresh1 $one->context_init_callbacks->[0]->({'hub' => 'Fake::Hub'}); 5005759b3d2Safresh1 is($cull, 1, "called cull once"); 5015759b3d2Safresh1 $cull = 0; 5025759b3d2Safresh1 5035759b3d2Safresh1 $one->disable_ipc_polling; 5045759b3d2Safresh1 is(@{$one->context_init_callbacks}, 1, "kept the callback"); 5055759b3d2Safresh1 is($one->ipc_polling, 0, "no polling, set to 0"); 5065759b3d2Safresh1 $one->context_init_callbacks->[0]->({'hub' => 'Fake::Hub'}); 5075759b3d2Safresh1 is($cull, 0, "did not call cull"); 5085759b3d2Safresh1 $cull = 0; 5095759b3d2Safresh1 5105759b3d2Safresh1 $one->enable_ipc_polling; 5115759b3d2Safresh1 is(@{$one->context_init_callbacks}, 1, "did not add the callback"); 5125759b3d2Safresh1 is($one->ipc_polling, 1, "polling on"); 5135759b3d2Safresh1 $one->context_init_callbacks->[0]->({'hub' => 'Fake::Hub'}); 5145759b3d2Safresh1 is($cull, 1, "called cull once"); 5155759b3d2Safresh1} 5165759b3d2Safresh1 5175759b3d2Safresh1{ 5185759b3d2Safresh1 require Test2::IPC::Driver::Files; 5195759b3d2Safresh1 5205759b3d2Safresh1 local $ENV{T2_NO_IPC} = 1; 521f3efcd01Safresh1 my $one = $CLASS->new; 5225759b3d2Safresh1 $one->add_ipc_driver('Test2::IPC::Driver::Files'); 5235759b3d2Safresh1 ok($one->ipc_disabled, "IPC is disabled by env var"); 5245759b3d2Safresh1 ok(!$one->ipc, 'IPC not loaded'); 5255759b3d2Safresh1 5265759b3d2Safresh1 local $ENV{T2_NO_IPC} = 0; 5275759b3d2Safresh1 $one->reset; 5285759b3d2Safresh1 ok(!$one->ipc_disabled, "IPC is not disabled by env var"); 5295759b3d2Safresh1 ok($one->ipc, 'IPC loaded'); 5305759b3d2Safresh1 like( 5315759b3d2Safresh1 exception { $one->ipc_disable }, 5325759b3d2Safresh1 qr/Attempt to disable IPC after it has been initialized/, 533*5486feefSafresh1 "Cannot disable IPC once it is initialized" 5345759b3d2Safresh1 ); 5355759b3d2Safresh1 5365759b3d2Safresh1 $one->reset; 5375759b3d2Safresh1 ok(!$one->ipc_disabled, "IPC is not disabled by env var"); 5385759b3d2Safresh1 $one->ipc_disable; 5395759b3d2Safresh1 ok($one->ipc_disabled, "IPC is disabled directly"); 5405759b3d2Safresh1} 5415759b3d2Safresh1 542f3efcd01Safresh1Test2::API::test2_ipc_wait_enable(); 543f3efcd01Safresh1 5445759b3d2Safresh1done_testing; 545