15759b3d2Safresh1use strict; 25759b3d2Safresh1use warnings; 35759b3d2Safresh1 4*de8cc8edSafresh1BEGIN { no warnings 'once'; $main::cleanup1 = bless {}, 'My::Cleanup' } 5*de8cc8edSafresh1 65759b3d2Safresh1use Test2::API qw/context/; 75759b3d2Safresh1 85759b3d2Safresh1my ($LOADED, $INIT); 95759b3d2Safresh1BEGIN { 105759b3d2Safresh1 $INIT = Test2::API::test2_init_done; 115759b3d2Safresh1 $LOADED = Test2::API::test2_load_done; 125759b3d2Safresh1}; 135759b3d2Safresh1 145759b3d2Safresh1use Test2::IPC; 155759b3d2Safresh1use Test2::Tools::Tiny; 165759b3d2Safresh1use Test2::Util qw/get_tid/; 175759b3d2Safresh1my $CLASS = 'Test2::API'; 185759b3d2Safresh1 195759b3d2Safresh1# Ensure we do not break backcompat later by removing anything 205759b3d2Safresh1ok(Test2::API->can($_), "$_ method is present") for qw{ 215759b3d2Safresh1 context_do 225759b3d2Safresh1 no_context 235759b3d2Safresh1 245759b3d2Safresh1 test2_init_done 255759b3d2Safresh1 test2_load_done 265759b3d2Safresh1 275759b3d2Safresh1 test2_pid 285759b3d2Safresh1 test2_tid 295759b3d2Safresh1 test2_stack 305759b3d2Safresh1 test2_no_wait 31*de8cc8edSafresh1 test2_is_testing_done 325759b3d2Safresh1 335759b3d2Safresh1 test2_add_callback_context_init 345759b3d2Safresh1 test2_add_callback_context_release 355759b3d2Safresh1 test2_add_callback_exit 365759b3d2Safresh1 test2_add_callback_post_load 375759b3d2Safresh1 test2_list_context_init_callbacks 385759b3d2Safresh1 test2_list_context_release_callbacks 395759b3d2Safresh1 test2_list_exit_callbacks 405759b3d2Safresh1 test2_list_post_load_callbacks 415759b3d2Safresh1 425759b3d2Safresh1 test2_ipc 435759b3d2Safresh1 test2_ipc_disable 445759b3d2Safresh1 test2_ipc_disabled 455759b3d2Safresh1 test2_ipc_drivers 465759b3d2Safresh1 test2_ipc_add_driver 475759b3d2Safresh1 test2_ipc_polling 485759b3d2Safresh1 test2_ipc_disable_polling 495759b3d2Safresh1 test2_ipc_enable_polling 505759b3d2Safresh1 515759b3d2Safresh1 test2_formatter 525759b3d2Safresh1 test2_formatters 535759b3d2Safresh1 test2_formatter_add 545759b3d2Safresh1 test2_formatter_set 555759b3d2Safresh1}; 565759b3d2Safresh1 575759b3d2Safresh1ok(!$LOADED, "Was not load_done right away"); 585759b3d2Safresh1ok(!$INIT, "Init was not done right away"); 595759b3d2Safresh1ok(Test2::API::test2_load_done, "We loaded it"); 605759b3d2Safresh1 615759b3d2Safresh1# Note: This is a check that stuff happens in an END block. 625759b3d2Safresh1{ 635759b3d2Safresh1 { 645759b3d2Safresh1 package FOLLOW; 655759b3d2Safresh1 665759b3d2Safresh1 sub DESTROY { 675759b3d2Safresh1 return if $_[0]->{fixed}; 685759b3d2Safresh1 print "not ok - Did not run end ($_[0]->{name})!"; 695759b3d2Safresh1 $? = 255; 705759b3d2Safresh1 exit 255; 715759b3d2Safresh1 } 725759b3d2Safresh1 } 735759b3d2Safresh1 745759b3d2Safresh1 our $kill1 = bless {fixed => 0, name => "Custom Hook"}, 'FOLLOW'; 755759b3d2Safresh1 Test2::API::test2_add_callback_exit( 765759b3d2Safresh1 sub { 775759b3d2Safresh1 print "# Running END hook\n"; 785759b3d2Safresh1 $kill1->{fixed} = 1; 795759b3d2Safresh1 } 805759b3d2Safresh1 ); 815759b3d2Safresh1 825759b3d2Safresh1 our $kill2 = bless {fixed => 0, name => "set exit"}, 'FOLLOW'; 835759b3d2Safresh1 my $old = Test2::API::Instance->can('set_exit'); 845759b3d2Safresh1 no warnings 'redefine'; 855759b3d2Safresh1 *Test2::API::Instance::set_exit = sub { 865759b3d2Safresh1 $kill2->{fixed} = 1; 875759b3d2Safresh1 print "# Running set_exit\n"; 885759b3d2Safresh1 $old->(@_); 895759b3d2Safresh1 }; 905759b3d2Safresh1} 915759b3d2Safresh1 925759b3d2Safresh1ok($CLASS->can('test2_init_done')->(), "init is done."); 935759b3d2Safresh1ok($CLASS->can('test2_load_done')->(), "Test2 is finished loading"); 945759b3d2Safresh1 955759b3d2Safresh1is($CLASS->can('test2_pid')->(), $$, "got pid"); 965759b3d2Safresh1is($CLASS->can('test2_tid')->(), get_tid(), "got tid"); 975759b3d2Safresh1 985759b3d2Safresh1ok($CLASS->can('test2_stack')->(), 'got stack'); 995759b3d2Safresh1is($CLASS->can('test2_stack')->(), $CLASS->can('test2_stack')->(), "always get the same stack"); 1005759b3d2Safresh1 1015759b3d2Safresh1ok($CLASS->can('test2_ipc')->(), 'got ipc'); 1025759b3d2Safresh1is($CLASS->can('test2_ipc')->(), $CLASS->can('test2_ipc')->(), "always get the same IPC"); 1035759b3d2Safresh1 1045759b3d2Safresh1is_deeply([$CLASS->can('test2_ipc_drivers')->()], [qw/Test2::IPC::Driver::Files/], "Got driver list"); 1055759b3d2Safresh1 1065759b3d2Safresh1# Verify it reports to the correct file/line, there was some trouble with this... 1075759b3d2Safresh1my $file = __FILE__; 1085759b3d2Safresh1my $line = __LINE__ + 1; 1095759b3d2Safresh1my $warnings = warnings { $CLASS->can('test2_ipc_add_driver')->('fake') }; 1105759b3d2Safresh1my $sub1 = sub { 1115759b3d2Safresh1like( 1125759b3d2Safresh1 $warnings->[0], 1135759b3d2Safresh1 qr{^IPC driver fake loaded too late to be used as the global ipc driver at \Q$file\E line $line}, 1145759b3d2Safresh1 "got warning about adding driver too late" 1155759b3d2Safresh1); 1165759b3d2Safresh1}; 1175759b3d2Safresh1if ($] le "5.006002") { 1185759b3d2Safresh1 todo("TODO known to fail on $]", $sub1); 1195759b3d2Safresh1} else { 1205759b3d2Safresh1 $sub1->(); 1215759b3d2Safresh1} 1225759b3d2Safresh1 1235759b3d2Safresh1is_deeply([$CLASS->can('test2_ipc_drivers')->()], [qw/fake Test2::IPC::Driver::Files/], "Got updated list"); 1245759b3d2Safresh1 1255759b3d2Safresh1ok($CLASS->can('test2_ipc_polling')->(), "Polling is on"); 1265759b3d2Safresh1$CLASS->can('test2_ipc_disable_polling')->(); 1275759b3d2Safresh1ok(!$CLASS->can('test2_ipc_polling')->(), "Polling is off"); 1285759b3d2Safresh1$CLASS->can('test2_ipc_enable_polling')->(); 1295759b3d2Safresh1ok($CLASS->can('test2_ipc_polling')->(), "Polling is on"); 1305759b3d2Safresh1 1315759b3d2Safresh1ok($CLASS->can('test2_formatter')->(), "Got a formatter"); 1325759b3d2Safresh1is($CLASS->can('test2_formatter')->(), $CLASS->can('test2_formatter')->(), "always get the same Formatter (class name)"); 1335759b3d2Safresh1 1345759b3d2Safresh1my $ran = 0; 1355759b3d2Safresh1$CLASS->can('test2_add_callback_post_load')->(sub { $ran++ }); 1365759b3d2Safresh1is($ran, 1, "ran the post-load"); 1375759b3d2Safresh1 1385759b3d2Safresh1like( 1395759b3d2Safresh1 exception { $CLASS->can('test2_formatter_set')->() }, 1405759b3d2Safresh1 qr/No formatter specified/, 1415759b3d2Safresh1 "formatter_set requires an argument" 1425759b3d2Safresh1); 1435759b3d2Safresh1 1445759b3d2Safresh1like( 1455759b3d2Safresh1 exception { $CLASS->can('test2_formatter_set')->('fake') }, 1465759b3d2Safresh1 qr/Global Formatter already set/, 1475759b3d2Safresh1 "formatter_set doesn't work after initialization", 1485759b3d2Safresh1); 1495759b3d2Safresh1 1505759b3d2Safresh1ok(!$CLASS->can('test2_no_wait')->(), "no_wait is not set"); 1515759b3d2Safresh1$CLASS->can('test2_no_wait')->(1); 1525759b3d2Safresh1ok($CLASS->can('test2_no_wait')->(), "no_wait is set"); 1535759b3d2Safresh1$CLASS->can('test2_no_wait')->(undef); 1545759b3d2Safresh1ok(!$CLASS->can('test2_no_wait')->(), "no_wait is not set"); 1555759b3d2Safresh1 1565759b3d2Safresh1ok($CLASS->can('test2_ipc_wait_enabled')->(), "IPC waiting enabled"); 1575759b3d2Safresh1$CLASS->can('test2_ipc_wait_disable')->(); 1585759b3d2Safresh1ok(!$CLASS->can('test2_ipc_wait_enabled')->(), "IPC waiting disabled"); 1595759b3d2Safresh1$CLASS->can('test2_ipc_wait_enable')->(); 1605759b3d2Safresh1ok($CLASS->can('test2_ipc_wait_enabled')->(), "IPC waiting enabled"); 1615759b3d2Safresh1 1625759b3d2Safresh1my $pctx; 1635759b3d2Safresh1sub tool_a($;$) { 1645759b3d2Safresh1 Test2::API::context_do { 1655759b3d2Safresh1 my $ctx = shift; 1665759b3d2Safresh1 my ($bool, $name) = @_; 1675759b3d2Safresh1 $pctx = wantarray; 1685759b3d2Safresh1 die "xyz" unless $bool; 1695759b3d2Safresh1 $ctx->ok($bool, $name); 1705759b3d2Safresh1 return unless defined $pctx; 1715759b3d2Safresh1 return (1, 2) if $pctx; 1725759b3d2Safresh1 return 'a'; 1735759b3d2Safresh1 } @_; 1745759b3d2Safresh1} 1755759b3d2Safresh1 1765759b3d2Safresh1$pctx = 'x'; 1775759b3d2Safresh1tool_a(1, "void context test"); 1785759b3d2Safresh1ok(!defined($pctx), "void context"); 1795759b3d2Safresh1 1805759b3d2Safresh1my $x = tool_a(1, "scalar context test"); 1815759b3d2Safresh1ok(defined($pctx) && $pctx == 0, "scalar context"); 1825759b3d2Safresh1is($x, 'a', "got scalar return"); 1835759b3d2Safresh1 1845759b3d2Safresh1my @x = tool_a(1, "array context test"); 1855759b3d2Safresh1ok($pctx, "array context"); 1865759b3d2Safresh1is_deeply(\@x, [1, 2], "Got array return"); 1875759b3d2Safresh1 1885759b3d2Safresh1like( 1895759b3d2Safresh1 exception { tool_a(0) }, 1905759b3d2Safresh1 qr/^xyz/, 1915759b3d2Safresh1 "got exception" 1925759b3d2Safresh1); 1935759b3d2Safresh1 1945759b3d2Safresh1sub { 1955759b3d2Safresh1 my $outer = context(); 1965759b3d2Safresh1 sub { 1975759b3d2Safresh1 my $middle = context(); 1985759b3d2Safresh1 is($outer->trace, $middle->trace, "got the same context before calling no_context"); 1995759b3d2Safresh1 2005759b3d2Safresh1 Test2::API::no_context { 2015759b3d2Safresh1 my $inner = context(); 2025759b3d2Safresh1 ok($inner->trace != $outer->trace, "Got a different context inside of no_context()"); 2035759b3d2Safresh1 $inner->release; 2045759b3d2Safresh1 }; 2055759b3d2Safresh1 2065759b3d2Safresh1 $middle->release; 2075759b3d2Safresh1 }->(); 2085759b3d2Safresh1 2095759b3d2Safresh1 $outer->release; 2105759b3d2Safresh1}->(); 2115759b3d2Safresh1 2125759b3d2Safresh1sub { 2135759b3d2Safresh1 my $outer = context(); 2145759b3d2Safresh1 sub { 2155759b3d2Safresh1 my $middle = context(); 2165759b3d2Safresh1 is($outer->trace, $middle->trace, "got the same context before calling no_context"); 2175759b3d2Safresh1 2185759b3d2Safresh1 Test2::API::no_context { 2195759b3d2Safresh1 my $inner = context(); 2205759b3d2Safresh1 ok($inner->trace != $outer->trace, "Got a different context inside of no_context({}, hid)"); 2215759b3d2Safresh1 $inner->release; 2225759b3d2Safresh1 } $outer->hub->hid; 2235759b3d2Safresh1 2245759b3d2Safresh1 $middle->release; 2255759b3d2Safresh1 }->(); 2265759b3d2Safresh1 2275759b3d2Safresh1 $outer->release; 2285759b3d2Safresh1}->(); 2295759b3d2Safresh1 2305759b3d2Safresh1sub { 2315759b3d2Safresh1 my @warnings; 2325759b3d2Safresh1 my $outer = context(); 2335759b3d2Safresh1 sub { 2345759b3d2Safresh1 my $middle = context(); 2355759b3d2Safresh1 is($outer->trace, $middle->trace, "got the same context before calling no_context"); 2365759b3d2Safresh1 2375759b3d2Safresh1 local $SIG{__WARN__} = sub { push @warnings => @_ }; 2385759b3d2Safresh1 Test2::API::no_context { 2395759b3d2Safresh1 my $inner = context(); 2405759b3d2Safresh1 ok($inner->trace != $outer->trace, "Got a different context inside of no_context({}, hid)"); 2415759b3d2Safresh1 } $outer->hub->hid; 2425759b3d2Safresh1 2435759b3d2Safresh1 $middle->release; 2445759b3d2Safresh1 }->(); 2455759b3d2Safresh1 2465759b3d2Safresh1 $outer->release; 2475759b3d2Safresh1 2485759b3d2Safresh1 is(@warnings, 1, "1 warning"); 2495759b3d2Safresh1 like( 2505759b3d2Safresh1 $warnings[0], 2515759b3d2Safresh1 qr/A context appears to have been destroyed without first calling release/, 2525759b3d2Safresh1 "Got warning about unreleased context" 2535759b3d2Safresh1 ); 2545759b3d2Safresh1}->(); 2555759b3d2Safresh1 2565759b3d2Safresh1 2575759b3d2Safresh1sub { 2585759b3d2Safresh1 my $hub = Test2::Hub->new(); 2595759b3d2Safresh1 my $ctx = context(hub => $hub); 2605759b3d2Safresh1 is($ctx->hub,$hub, 'got the hub of context() argument'); 2615759b3d2Safresh1 $ctx->release; 2625759b3d2Safresh1}->(); 2635759b3d2Safresh1 2645759b3d2Safresh1 2655759b3d2Safresh1my $sub = sub { }; 2665759b3d2Safresh1 2675759b3d2Safresh1Test2::API::test2_add_callback_context_acquire($sub); 2685759b3d2Safresh1Test2::API::test2_add_callback_context_init($sub); 2695759b3d2Safresh1Test2::API::test2_add_callback_context_release($sub); 2705759b3d2Safresh1Test2::API::test2_add_callback_exit($sub); 2715759b3d2Safresh1Test2::API::test2_add_callback_post_load($sub); 2725759b3d2Safresh1 2735759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_context_acquire_callbacks()), 1, "got the one instance of the hook"); 2745759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_context_init_callbacks()), 1, "got the one instance of the hook"); 2755759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_context_release_callbacks()), 1, "got the one instance of the hook"); 2765759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_exit_callbacks()), 1, "got the one instance of the hook"); 2775759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_post_load_callbacks()), 1, "got the one instance of the hook"); 2785759b3d2Safresh1 2795759b3d2Safresh1Test2::API::test2_add_callback_context_acquire($sub); 2805759b3d2Safresh1Test2::API::test2_add_callback_context_init($sub); 2815759b3d2Safresh1Test2::API::test2_add_callback_context_release($sub); 2825759b3d2Safresh1Test2::API::test2_add_callback_exit($sub); 2835759b3d2Safresh1Test2::API::test2_add_callback_post_load($sub); 2845759b3d2Safresh1 2855759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_context_acquire_callbacks()), 2, "got the two instances of the hook"); 2865759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_context_init_callbacks()), 2, "got the two instances of the hook"); 2875759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_context_release_callbacks()), 2, "got the two instances of the hook"); 2885759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_exit_callbacks()), 2, "got the two instances of the hook"); 2895759b3d2Safresh1is((grep { $_ == $sub } Test2::API::test2_list_post_load_callbacks()), 2, "got the two instances of the hook"); 2905759b3d2Safresh1 291*de8cc8edSafresh1ok(!Test2::API::test2_is_testing_done(), "Testing is not done"); 292*de8cc8edSafresh1 2935759b3d2Safresh1done_testing; 2945759b3d2Safresh1 295*de8cc8edSafresh1die "Testing should be done, but it is not!" unless Test2::API::test2_is_testing_done(); 296*de8cc8edSafresh1 297*de8cc8edSafresh1{ 298*de8cc8edSafresh1 package My::Cleanup; 299*de8cc8edSafresh1 300*de8cc8edSafresh1 sub DESTROY { 301*de8cc8edSafresh1 return if Test2::API::test2_is_testing_done(); 302*de8cc8edSafresh1 print "not ok - Testing should be done, but it is not!\n"; 303*de8cc8edSafresh1 warn "Testing should be done, but it is not!"; 304*de8cc8edSafresh1 eval "END { $? = 255 }; 1" or die $@; 305*de8cc8edSafresh1 exit 255; 306*de8cc8edSafresh1 } 307*de8cc8edSafresh1} 308*de8cc8edSafresh1 309*de8cc8edSafresh1# This should destroy the thing 310*de8cc8edSafresh1END { no warnings 'once'; $main::cleanup2 = bless {}, 'My::Cleanup' } 311