Move find_co_root into DBICTest::Util
[dbsrgits/DBIx-Class-Historic.git] / t / storage / error.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use Test::Warn;
6 use Test::Exception;
7
8 use lib qw(t/lib);
9 use DBICTest;
10
11 for my $conn_args (
12   [ on_connect_do   => "_NOPE_" ],
13   [ on_connect_call => sub { shift->_dbh->do("_NOPE_") } ],
14   [ on_connect_call => "_NOPE_" ],
15 ) {
16   for my $method (qw( ensure_connected _server_info _get_server_version _get_dbh )) {
17
18     my $s = DBICTest->init_schema(
19       no_deploy => 1,
20       on_disconnect_call => sub { fail 'Disconnector should not be invoked' },
21       @$conn_args
22     );
23
24     my $storage = $s->storage;
25     $storage = $storage->master if $ENV{DBICTEST_VIA_REPLICATED};
26
27     ok( ! $storage->connected, 'Starting unconnected' );
28
29     my $desc = "calling $method with broken on_connect action @{[ explain $conn_args ]}";
30
31     throws_ok { $storage->$method }
32       qr/ _NOPE_ \b/x,
33       "Throwing correctly when $desc";
34
35     ok( ! $storage->connected, "Still not connected after $desc" );
36
37     # this checks that the on_disconect_call FAIL won't trigger
38     $storage->disconnect;
39   }
40 }
41
42 for my $conn_args (
43   [ on_disconnect_do   => "_NOPE_" ],
44   [ on_disconnect_call => sub { shift->_dbh->do("_NOPE_") } ],
45   [ on_disconnect_call => "_NOPE_" ],
46 ) {
47   my $s = DBICTest->init_schema( no_deploy => 1, @$conn_args );
48
49   my $storage = $s->storage;
50   $storage = $storage->master if $ENV{DBICTEST_VIA_REPLICATED};
51
52   my $desc = "broken on_disconnect action @{[ explain $conn_args ]}";
53
54   # connect + ping
55   my $dbh = $storage->dbh;
56
57   ok ($dbh->FETCH('Active'), 'Freshly connected DBI handle is healthy');
58
59   warnings_exist { eval { $storage->disconnect } } [
60     qr/\QDisconnect action failed\E .+ _NOPE_ \b/x
61   ], "Found warning of failed $desc";
62
63   ok (! $dbh->FETCH('Active'), "Actual DBI disconnect was not prevented by $desc" );
64 }
65
66 my $schema = DBICTest->init_schema;
67
68 warnings_are ( sub {
69   throws_ok (
70     sub {
71       $schema->resultset('CD')->create({ title => 'vacation in antarctica' })
72     },
73     qr/DBI Exception.+(?x:
74       \QNOT NULL constraint failed: cd.artist\E
75         |
76       \Qcd.artist may not be NULL\E
77     )/s
78   );  # as opposed to some other error
79 }, [], 'No warnings besides exception' );
80
81 my $dbh = $schema->storage->dbh;
82
83 throws_ok (
84   sub {
85     $dbh->do ('INSERT INTO nonexistent_table VALUES (1)')
86   },
87   qr/DBI Exception.+no such table.+nonexistent_table/s,
88   'DBI exceptions properly handled by dbic-installed callback'
89 );
90
91 # This usage is a bit unusual but it was actually seen in the wild
92 # destruction of everything except the $dbh should use the proper
93 # exception fallback:
94
95 SKIP: {
96   if ( !!DBIx::Class::_ENV_::PEEPEENESS ) {
97     skip "Your perl version $] appears to leak like a sieve - skipping garbage collected \$schema test", 1;
98   }
99
100   undef ($schema);
101   throws_ok (
102     sub {
103       $dbh->do ('INSERT INTO nonexistent_table VALUES (1)')
104     },
105     qr/DBI Exception.+unhandled by DBIC.+no such table.+nonexistent_table/s,
106     'callback works after $schema is gone'
107   );
108 }
109
110 done_testing;