Commit | Line | Data |
c0329273 |
1 | BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) } |
2 | |
7cb35852 |
3 | use strict; |
4 | use warnings; |
5 | |
c0329273 |
6 | |
7cb35852 |
7 | use DBICTest::RunMode; |
8 | BEGIN { |
9 | if( DBICTest::RunMode->is_plain ) { |
10 | print "1..0 # SKIP not running dangerous segfault-prone test on plain install\n"; |
11 | exit 0; |
12 | } |
13 | } |
14 | |
439a7283 |
15 | use DBICTest::Util 'tmpdir'; |
7cb35852 |
16 | use File::Temp (); |
17 | use DBIx::Class::_Util 'scope_guard'; |
18 | use DBIx::Class::Schema; |
19 | |
20 | # Do not use T::B - the test is hard enough not to segfault as it is |
21 | my $test_count = 0; |
22 | |
23 | # start with one failure, and decrement it at the end |
24 | my $failed = 1; |
25 | |
26 | sub ok { |
27 | printf STDOUT ("%s %u - %s\n", |
28 | ( $_[0] ? 'ok' : 'not ok' ), |
29 | ++$test_count, |
30 | $_[1] || '', |
31 | ); |
32 | |
33 | unless( $_[0] ) { |
34 | $failed++; |
35 | printf STDERR ("# Failed test #%d at %s line %d\n", |
36 | $test_count, |
37 | (caller(0))[1,2] |
38 | ); |
39 | } |
40 | |
41 | return !!$_[0]; |
42 | } |
43 | |
44 | # yes, make it even dirtier |
45 | my $schema = 'DBIx::Class::Schema'; |
46 | |
47 | $schema->connection('dbi:SQLite::memory:'); |
48 | |
49 | # this is incredibly horrible... |
50 | # demonstrate utter breakage of the reconnection/retry logic |
51 | # |
52 | open(my $stderr_copy, '>&', *STDERR) or die "Unable to dup STDERR: $!"; |
439a7283 |
53 | my $tf = File::Temp->new( UNLINK => 1, DIR => tmpdir() ); |
7cb35852 |
54 | |
55 | my $output; |
56 | |
57 | ESCAPE: |
58 | { |
59 | my $guard = scope_guard { |
60 | close STDERR; |
61 | open(STDERR, '>&', $stderr_copy); |
62 | $output = do { local (@ARGV, $/) = $tf; <> }; |
63 | close $tf; |
64 | unlink $tf; |
65 | undef $tf; |
66 | close $stderr_copy; |
67 | }; |
68 | |
69 | close STDERR; |
70 | open(STDERR, '>&', $tf) or die "Unable to reopen STDERR: $!"; |
71 | |
72 | $schema->storage->ensure_connected; |
73 | $schema->storage->_dbh->disconnect; |
74 | |
75 | local $SIG{__WARN__} = sub {}; |
76 | |
77 | $schema->exception_action(sub { |
78 | ok(1, 'exception_action invoked'); |
79 | # essentially what Dancer2's redirect() does after https://github.com/PerlDancer/Dancer2/pull/485 |
80 | # which "nicely" combines with: https://metacpan.org/source/MARKOV/Log-Report-1.12/lib/Dancer2/Plugin/LogReport.pm#L143 |
81 | # as encouraged by: https://metacpan.org/pod/release/MARKOV/Log-Report-1.12/lib/Dancer2/Plugin/LogReport.pod#Logging-DBIC-database-queries-and-errors |
82 | last ESCAPE; |
83 | }); |
84 | |
85 | # this *DOES* throw, but the exception will *NEVER SHOW UP* |
86 | $schema->storage->dbh_do(sub { $_[1]->selectall_arrayref("SELECT * FROM wfwqfdqefqef") } ); |
87 | |
88 | # NEITHER will this |
89 | ok(0, "Nope"); |
90 | } |
91 | |
92 | ok(1, "Post-escape reached"); |
93 | |
94 | ok( |
95 | !!( $output =~ /DBIx::Class INTERNAL PANIC.+FIX YOUR ERROR HANDLING/s ), |
96 | 'Proper warning emitted on STDERR' |
97 | ) or print STDERR "Instead found:\n\n$output\n"; |
98 | |
99 | print "1..$test_count\n"; |
100 | |
101 | # this is our "done_testing" |
102 | $failed--; |
103 | |
104 | # avoid tasty segfaults on 5.8.x |
105 | exit( $failed ); |