Fix pesky on_connect_* race condition abraxxa++ ilmari++
[dbsrgits/DBIx-Class.git] / t / storage / on_connect_do.t
1 use strict;
2 use warnings;
3
4 # !!! do not replace this with done_testing - tests reside in the callbacks
5 # !!! number of calls is important
6 use Test::More tests => 13;
7 # !!!
8 use Test::Warn;
9 use Test::Exception;
10
11 use lib qw(t/lib);
12 use DBICTest;
13 require DBI;
14
15
16 my $schema = DBICTest->init_schema(
17     no_connect  => 1,
18     no_deploy   => 1,
19 );
20
21 ok $schema->connection(
22   DBICTest->_database,
23   {
24     on_connect_do => 'CREATE TABLE TEST_empty (id INTEGER)',
25   },
26 ), 'connection()';
27
28 is_deeply (
29   $schema->storage->dbh->selectall_arrayref('SELECT * FROM TEST_empty'),
30   [],
31   'string version on_connect_do() worked'
32 );
33
34 $schema->storage->disconnect;
35
36 ok $schema->connection(
37     sub { DBI->connect(DBICTest->_database, undef, undef, { AutoCommit => 0 }) },
38     {
39         # DO NOT REMOVE - this seems like an unrelated piece of info,
40         # but is in fact a test for a bug where setting an accessor-via-option
41         # would trigger an early connect *bypassing* the on_connect_* pieces
42         cursor_class => 'DBIx::Class::Storage::Cursor',
43
44         on_connect_do       => [
45             'CREATE TABLE TEST_empty (id INTEGER)',
46             [ 'INSERT INTO TEST_empty VALUES (?)', {}, 2 ],
47             \&insert_from_subref,
48         ],
49         on_disconnect_do    =>
50             [\&check_exists, 'DROP TABLE TEST_empty', \&check_dropped],
51     },
52 ), 'connection()';
53
54 warnings_exist {
55   $schema->storage->ensure_connected
56 } qr/The 'RaiseError' of the externally supplied DBI handle is set to false/,
57 'Warning on clobbered AutoCommit => 0 fired';
58
59 is_deeply (
60   $schema->storage->dbh->selectall_arrayref('SELECT * FROM TEST_empty'),
61   [ [ 2 ], [ 3 ], [ 7 ] ],
62   'on_connect_do() worked'
63 );
64 dies_ok {
65   $schema->storage->dbh->do('SELECT 1 FROM TEST_nonexistent');
66 } 'Searching for nonexistent table dies';
67
68 $schema->storage->disconnect();
69
70 my($connected, $disconnected, @cb_args);
71 ok $schema->connection(
72     DBICTest->_database,
73     {
74         on_connect_do       => sub { $connected = 1; @cb_args = @_; },
75         on_disconnect_do    => sub { $disconnected = 1 },
76     },
77 ), 'second connection()';
78 $schema->storage->dbh->do('SELECT 1');
79 ok $connected, 'on_connect_do() called after connect()';
80 ok ! $disconnected, 'on_disconnect_do() not called after connect()';
81 $schema->storage->disconnect();
82 ok $disconnected, 'on_disconnect_do() called after disconnect()';
83
84 isa_ok($cb_args[0], 'DBIx::Class::Storage', 'first arg to on_connect_do hook');
85 @cb_args = ();
86
87 sub check_exists {
88     my $storage = shift;
89     ok $storage->dbh->do('SELECT 1 FROM TEST_empty'), 'Table still exists';
90     return;
91 }
92
93 sub check_dropped {
94     my $storage = shift;
95
96     dies_ok {
97       $storage->dbh->do('SELECT 1 FROM TEST_empty');
98     } 'Reading from dropped table fails';
99     return;
100 }
101
102 sub insert_from_subref {
103     my $storage = shift;
104     return [
105         [ 'INSERT INTO TEST_empty VALUES (?)', {}, 3 ],
106         'INSERT INTO TEST_empty VALUES (7)',
107     ];
108 }