1*5486feefSafresh1use Test2::Bundle::Extended;
2*5486feefSafresh1use Test2::AsyncSubtest;
3*5486feefSafresh1use Test2::Tools::AsyncSubtest;
4*5486feefSafresh1use Test2::Tools::Compare qw{ array event call T };
5*5486feefSafresh1use Test2::IPC;
6*5486feefSafresh1use Test2::Util qw/CAN_REALLY_FORK/;
7*5486feefSafresh1use Test2::API qw/context context_do intercept/;
8*5486feefSafresh1
9*5486feefSafresh1sub DO_THREADS {
10*5486feefSafresh1    return 0 unless $ENV{AUTHOR_TESTING} || $ENV{T2_DO_THREAD_TESTS};
11*5486feefSafresh1    return Test2::AsyncSubtest->CAN_REALLY_THREAD;
12*5486feefSafresh1}
13*5486feefSafresh1
14*5486feefSafresh1skip_all 'These tests require forking or threading'
15*5486feefSafresh1    unless CAN_REALLY_FORK || DO_THREADS();
16*5486feefSafresh1
17*5486feefSafresh1subtest(
18*5486feefSafresh1    'fork tests',
19*5486feefSafresh1    sub {
20*5486feefSafresh1        run_tests('fork');
21*5486feefSafresh1        stress_tests('fork');
22*5486feefSafresh1    }
23*5486feefSafresh1) if CAN_REALLY_FORK;
24*5486feefSafresh1
25*5486feefSafresh1subtest(
26*5486feefSafresh1    'thread tests',
27*5486feefSafresh1    sub {
28*5486feefSafresh1        run_tests('thread');
29*5486feefSafresh1        stress_tests('thread');
30*5486feefSafresh1    }
31*5486feefSafresh1) if DO_THREADS();
32*5486feefSafresh1
33*5486feefSafresh1done_testing;
34*5486feefSafresh1
35*5486feefSafresh1sub run_tests {
36*5486feefSafresh1    my $type = shift;
37*5486feefSafresh1
38*5486feefSafresh1    my $st_sub = $type eq 'fork' ? \&fork_subtest : \&thread_subtest;
39*5486feefSafresh1
40*5486feefSafresh1    is(
41*5486feefSafresh1        intercept {
42*5486feefSafresh1            $st_sub->(
43*5486feefSafresh1                '$ctx->plan(0, SKIP)',
44*5486feefSafresh1                sub {
45*5486feefSafresh1                    skip_all 'because';
46*5486feefSafresh1                    ok(0, "Should not see");
47*5486feefSafresh1                }
48*5486feefSafresh1            )->finish;
49*5486feefSafresh1        },
50*5486feefSafresh1        array {
51*5486feefSafresh1            event Subtest => sub {
52*5486feefSafresh1                call name      => '$ctx->plan(0, SKIP)';
53*5486feefSafresh1                call pass      => T();
54*5486feefSafresh1                call subevents => array {
55*5486feefSafresh1                    event '+Test2::AsyncSubtest::Event::Attach';
56*5486feefSafresh1                    event Plan => sub {
57*5486feefSafresh1                        call directive => 'SKIP';
58*5486feefSafresh1                        call reason    => 'because';
59*5486feefSafresh1                    };
60*5486feefSafresh1                    event '+Test2::AsyncSubtest::Event::Detach';
61*5486feefSafresh1                    end();
62*5486feefSafresh1                };
63*5486feefSafresh1            };
64*5486feefSafresh1            end();
65*5486feefSafresh1        },
66*5486feefSafresh1        qq[${type}_subtest with skip_all]
67*5486feefSafresh1    );
68*5486feefSafresh1
69*5486feefSafresh1    is(
70*5486feefSafresh1        intercept {
71*5486feefSafresh1            $st_sub->(
72*5486feefSafresh1                'skip_all',
73*5486feefSafresh1                { manual_skip_all => 1 },
74*5486feefSafresh1                sub {
75*5486feefSafresh1                    skip_all 'because';
76*5486feefSafresh1                    note "Post skip";
77*5486feefSafresh1                    return;
78*5486feefSafresh1                }
79*5486feefSafresh1            )->finish;
80*5486feefSafresh1        },
81*5486feefSafresh1        array {
82*5486feefSafresh1            event Subtest => sub {
83*5486feefSafresh1                call name      => 'skip_all';
84*5486feefSafresh1                call pass      => T();
85*5486feefSafresh1                call subevents => array {
86*5486feefSafresh1                    event '+Test2::AsyncSubtest::Event::Attach';
87*5486feefSafresh1                    event Plan => sub {
88*5486feefSafresh1                        call directive => 'SKIP';
89*5486feefSafresh1                        call reason    => 'because';
90*5486feefSafresh1                    };
91*5486feefSafresh1                    event Note => { message => 'Post skip' };
92*5486feefSafresh1                    event '+Test2::AsyncSubtest::Event::Detach';
93*5486feefSafresh1                    end();
94*5486feefSafresh1                };
95*5486feefSafresh1            };
96*5486feefSafresh1            end();
97*5486feefSafresh1        },
98*5486feefSafresh1        qq[${type}_subtest with skip_all and manual skip return}]
99*5486feefSafresh1    );
100*5486feefSafresh1
101*5486feefSafresh1    my $method = 'run_' . $type;
102*5486feefSafresh1    is(
103*5486feefSafresh1        intercept {
104*5486feefSafresh1            my $at = Test2::AsyncSubtest->new(name => '$ctx->plan(0, SKIP)');
105*5486feefSafresh1            $at->$method(
106*5486feefSafresh1                sub {
107*5486feefSafresh1                    skip_all 'because';
108*5486feefSafresh1                    ok(0, "should not see");
109*5486feefSafresh1                }
110*5486feefSafresh1            );
111*5486feefSafresh1            $at->finish;
112*5486feefSafresh1        },
113*5486feefSafresh1        array {
114*5486feefSafresh1            event Subtest => sub {
115*5486feefSafresh1                call name      => '$ctx->plan(0, SKIP)';
116*5486feefSafresh1                call pass      => T();
117*5486feefSafresh1                call subevents => array {
118*5486feefSafresh1                    event '+Test2::AsyncSubtest::Event::Attach';
119*5486feefSafresh1                    event Plan => sub {
120*5486feefSafresh1                        call directive => 'SKIP';
121*5486feefSafresh1                        call reason    => 'because';
122*5486feefSafresh1                    };
123*5486feefSafresh1                    event '+Test2::AsyncSubtest::Event::Detach';
124*5486feefSafresh1                    end();
125*5486feefSafresh1                };
126*5486feefSafresh1            };
127*5486feefSafresh1            end();
128*5486feefSafresh1        },
129*5486feefSafresh1        qq[\$subtest->$method with skip_all]
130*5486feefSafresh1    );
131*5486feefSafresh1}
132*5486feefSafresh1
133*5486feefSafresh1sub stress_tests {
134*5486feefSafresh1    my $type = shift;
135*5486feefSafresh1
136*5486feefSafresh1    my $st_sub = $type eq 'fork' ? \&fork_subtest : \&thread_subtest;
137*5486feefSafresh1
138*5486feefSafresh1    for my $i (2 .. 5) {
139*5486feefSafresh1        my @st;
140*5486feefSafresh1        for my $j (1 .. $i) {
141*5486feefSafresh1            push @st, $st_sub->(
142*5486feefSafresh1                "skip all $i - $j",
143*5486feefSafresh1                sub {
144*5486feefSafresh1                    skip_all 'because';
145*5486feefSafresh1                    ok(0, "should not see");
146*5486feefSafresh1                }
147*5486feefSafresh1            );
148*5486feefSafresh1        }
149*5486feefSafresh1        $_->finish for @st;
150*5486feefSafresh1    }
151*5486feefSafresh1}
152