Work around Firebird/InterBase/ODBC crash in tests
[dbsrgits/DBIx-Class.git] / t / 750firebird.t
index d55474b..1d06387 100644 (file)
@@ -36,15 +36,26 @@ plan skip_all => join (' ',
 
 my $schema;
 
-for my $prefix (keys %$env2optdep) { SKIP: {
+my @test_order = map { "DBICTEST_FIREBIRD$_" }
+  DBICTest::RunMode->is_plain
+    ? ('', '_INTERBASE', '_ODBC')   # Least likely to fail
+    : ('_ODBC', '_INTERBASE' , ''); # Most likely to fail
+
+for my $prefix (@test_order) { SKIP: {
 
   my ($dsn, $user, $pass) = map { $ENV{"${prefix}_$_"} } qw/DSN USER PASS/;
 
   next unless $dsn;
 
+  note "Testing with ${prefix}_DSN";
+
   skip ("Testing with ${prefix}_DSN needs " . DBIx::Class::Optional::Dependencies->req_missing_for( $env2optdep->{$prefix} ), 1)
     unless  DBIx::Class::Optional::Dependencies->req_ok_for($env2optdep->{$prefix});
 
+  skip ("DBD::InterBase crashes if Firebird or ODBC are also loaded", 1)
+    if $prefix eq 'DBICTEST_FIREBIRD_INTERBASE' and
+      ($ENV{DBICTEST_FIREBIRD_DSN} or $ENV{DBICTEST_FIREBIRD_ODBC_DSN});
+
   $schema = DBICTest::Schema->connect($dsn, $user, $pass, {
     auto_savepoint  => 1,
     quote_names     => 1,
@@ -52,7 +63,7 @@ for my $prefix (keys %$env2optdep) { SKIP: {
   });
   my $dbh = $schema->storage->dbh;
 
-  my $sg = Scope::Guard->new(\&cleanup);
+  my $sg = Scope::Guard->new(sub { cleanup($schema) });
 
   eval { $dbh->do(q[DROP TABLE "artist"]) };
   $dbh->do(<<EOF);
@@ -125,6 +136,7 @@ EOF
 # test savepoints
   throws_ok {
     $schema->txn_do(sub {
+      my ($schema, $ars) = @_;
       eval {
         $schema->txn_do(sub {
           $ars->create({ name => 'in_savepoint' });
@@ -135,7 +147,7 @@ EOF
         'savepoint rolled back');
       $ars->create({ name => 'in_outer_txn' });
       die "rolling back outer txn";
-    });
+    }, $schema, $ars);
   } qr/rolling back outer txn/,
     'correct exception for rollback';
 
@@ -252,6 +264,14 @@ EOF
     } 'inferring generator from trigger source works';
   }
 
+  # at this point there should be no active statements
+  # (finish() was called everywhere, either explicitly via
+  # reset() or on DESTROY)
+  for (keys %{$schema->storage->dbh->{CachedKids}}) {
+    fail("Unreachable cached statement still active: $_")
+      if $schema->storage->dbh->{CachedKids}{$_}->FETCH('Active');
+  }
+
 # test blobs (stolen from 73oracle.t)
   eval { $dbh->do('DROP TABLE "bindtype_test"') };
   $dbh->do(q[
@@ -305,6 +325,8 @@ done_testing;
 # clean up our mess
 
 sub cleanup {
+  my $schema = shift;
+
   my $dbh;
   eval {
     $schema->storage->disconnect; # to avoid object FOO is in use errors