Skip Menu |

This queue is for tickets about the Test-Database CPAN distribution.

Report information
The Basics
Id: 56516
Status: resolved
Priority: 0/
Queue: Test-Database

People
Owner: Nobody in particular
Requestors: BARBIE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.09
Fixed in: 1.10



Subject: DSN report failures
Hi BooK, Tried the latest version and got the same errors as some of the FAIL reports on my CentOS box. The attached patch appears to resolve these for me at least. However, the PrintError fix might be worth more investigation. Cheers, Barbie.
Subject: test-database-driver.patch
--- Test-Database-1.09/lib/Test/Database/Driver.pm Tue Mar 16 11:45:45 2010 +++ Test-Database-1.09_01/lib/Test/Database/Driver.pm Mon Apr 12 11:07:45 2010 @@ -50,7 +50,7 @@ = DBI->parse_dsn( $args{driver_dsn} ); $args{dbd} = $driver; } - croak "dbd or driver_dsn parameter required" if !exists $args{dbd}; + croak "dbd or driver_dsn parameter required" unless(exists $args{dbd} && $args{dbd}); eval "require Test::Database::Driver::$args{dbd}" or do { $@ =~ s/ at .*?\z//s; croak $@; }; $class = "Test::Database::Driver::$args{dbd}"; @@ -69,7 +69,7 @@ # try to connect before returning the object if ( !$class->is_filebased() ) { - eval { DBI->connect_cached( $self->connection_info() ) } + eval { DBI->connect_cached( $self->connection_info(), PrintError => 0 ) } or return; }
On Mon Apr 12 06:11:50 2010, BARBIE wrote: Show quoted text
> Hi BooK, > > Tried the latest version and got the same errors as some of the FAIL > reports on my CentOS box. The attached patch appears to resolve these > for me at least. However, the PrintError fix might be worth more > investigation. > > Cheers, > Barbie.
Just to add to this report from Barbie. The first time I run Test::Database with no ~/.test-database file and no /tmp/Test-Database-martin I get: prove -vb t/10-drivers.t t/10-drivers.t .. 1..32 ok 1 - Test::Database::Driver->new() failed ok 2 - Expected error message ok 3 - Test::Database::Driver has a base_dir(): /tmp/Test-Database-martin ok 4 - Test::Database::Driver's base_dir() looks like expected ok 5 - Test::Database::Driver base_dir() is a directory ok 6 - use Test::Database::Driver::DBM; Use of uninitialized value $args{"dbd"} in concatenation (.) or string at /tmp/Test-Database-1.09/blib/lib/Test/Database/Driver.pm line 55. ok 7 # skip Failed to create DBM driver with Test::Database::Driver (Can't locate Test/Database/Driver/.pm in @INC (@INC contains: /tmp/Test-Database-1.09/blib/lib /tmp/Test-Database-1.09/blib/arch /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .)) The uninitialized value warning is down to the code Barbie refers to: sub new { my ( $class, %args ) = @_; if ( $class eq __PACKAGE__ ) { if ( exists $args{driver_dsn} ) { my ( $scheme, $driver, $attr_string, $attr_hash, $driver_dsn ) = DBI->parse_dsn( $args{driver_dsn} ); $args{dbd} = $driver; } croak "dbd or driver_dsn parameter required" if !exists $args{dbd}; eval "require Test::Database::Driver::$args{dbd}" or do { $@ =~ s/ at .*?\z//s; croak $@; }; $class = "Test::Database::Driver::$args{dbd}"; $class->__init(); } Where %args contains: $VAR1 = { 'password' => '', 'driver_dsn' => undef, 'dbd' => 'DBM', 'username' => '' }; on entry hence "exists $args{driver_dsn}" is true and DBI's parse_dsn is called with an empty $args{driver_dsn} hence $driver is undef and assigned to $args{dbd} and the eval fails. Barbie's change fixed that for me. Having run once it works but you can make it fail again my deleting /tmp/Test-Database-martin Martin -- Martin J. Evans Wetherby, UK
On Thu Apr 22 04:51:38 2010, MJEVANS wrote: Show quoted text
> On Mon Apr 12 06:11:50 2010, BARBIE wrote:
> > Hi BooK, > > > > Tried the latest version and got the same errors as some of the FAIL > > reports on my CentOS box. The attached patch appears to resolve these > > for me at least. However, the PrintError fix might be worth more > > investigation. > > > > Cheers, > > Barbie.
> > Just to add to this report from Barbie. The first time I run > Test::Database with no ~/.test-database file and no > /tmp/Test-Database-martin I get: > > prove -vb t/10-drivers.t > t/10-drivers.t .. > 1..32 > ok 1 - Test::Database::Driver->new() failed > ok 2 - Expected error message > ok 3 - Test::Database::Driver has a base_dir(): /tmp/Test-Database-martin > ok 4 - Test::Database::Driver's base_dir() looks like expected > ok 5 - Test::Database::Driver base_dir() is a directory > ok 6 - use Test::Database::Driver::DBM; > Use of uninitialized value $args{"dbd"} in concatenation (.) or string > at /tmp/Test-Database-1.09/blib/lib/Test/Database/Driver.pm line 55. > ok 7 # skip Failed to create DBM driver with Test::Database::Driver > (Can't locate Test/Database/Driver/.pm in @INC (@INC contains: > /tmp/Test-Database-1.09/blib/lib /tmp/Test-Database-1.09/blib/arch > /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 > /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 > /usr/local/lib/site_perl .)) > > The uninitialized value warning is down to the code Barbie refers to: > > sub new { > my ( $class, %args ) = @_; > > if ( $class eq __PACKAGE__ ) { > if ( exists $args{driver_dsn} ) { > my ( $scheme, $driver, $attr_string, $attr_hash, $driver_dsn ) > = DBI->parse_dsn( $args{driver_dsn} ); > $args{dbd} = $driver; > } > croak "dbd or driver_dsn parameter required" if !exists
$args{dbd}; Show quoted text
> eval "require Test::Database::Driver::$args{dbd}" > or do { $@ =~ s/ at .*?\z//s; croak $@; }; > $class = "Test::Database::Driver::$args{dbd}"; > $class->__init(); > } > > Where %args contains: > > $VAR1 = { > 'password' => '', > 'driver_dsn' => undef, > 'dbd' => 'DBM', > 'username' => '' > }; > > on entry hence "exists $args{driver_dsn}" is true and DBI's parse_dsn is > called with an empty $args{driver_dsn} hence $driver is undef and > assigned to $args{dbd} and the eval fails. Barbie's change fixed that > for me. > > Having run once it works but you can make it fail again my deleting > /tmp/Test-Database-martin > > Martin
However, I think it is unwise to call DBI's parse_dsn with an undefined value so I think the following is better: sub new { my ( $class, %args ) = @_; if ( $class eq __PACKAGE__ ) { if ( exists $args{driver_dsn} && defined($args{driver_dsn})) { my ( $scheme, $driver, $attr_string, $attr_hash, $driver_dsn ) = DBI->parse_dsn( $args{driver_dsn} ); $args{dbd} = $driver; } croak "dbd or driver_dsn parameter required" unless(exists $args{dbd} && $args{dbd}); #croak "dbd or driver_dsn parameter required" if !exists $args{dbd}; eval "require Test::Database::Driver::$args{dbd}" or do { $@ =~ s/ at .*?\z//s; croak $@; }; $class = "Test::Database::Driver::$args{dbd}"; $class->__init(); } -- Martin J. Evans Wetherby, UK
On Thu Apr 22 05:00:04 2010, MJEVANS wrote: Show quoted text
> On Thu Apr 22 04:51:38 2010, MJEVANS wrote:
> > On Mon Apr 12 06:11:50 2010, BARBIE wrote:
> > > Hi BooK, > > > > > > Tried the latest version and got the same errors as some of the FAIL > > > reports on my CentOS box. The attached patch appears to resolve these > > > for me at least. However, the PrintError fix might be worth more > > > investigation. > > > > > > Cheers, > > > Barbie.
> > > > Just to add to this report from Barbie. The first time I run > > Test::Database with no ~/.test-database file and no > > /tmp/Test-Database-martin I get: > > > > prove -vb t/10-drivers.t > > t/10-drivers.t .. > > 1..32 > > ok 1 - Test::Database::Driver->new() failed > > ok 2 - Expected error message > > ok 3 - Test::Database::Driver has a base_dir():
/tmp/Test-Database-martin Show quoted text
> > ok 4 - Test::Database::Driver's base_dir() looks like expected > > ok 5 - Test::Database::Driver base_dir() is a directory > > ok 6 - use Test::Database::Driver::DBM; > > Use of uninitialized value $args{"dbd"} in concatenation (.) or string > > at /tmp/Test-Database-1.09/blib/lib/Test/Database/Driver.pm line 55. > > ok 7 # skip Failed to create DBM driver with Test::Database::Driver > > (Can't locate Test/Database/Driver/.pm in @INC (@INC contains: > > /tmp/Test-Database-1.09/blib/lib /tmp/Test-Database-1.09/blib/arch > > /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 > > /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 > > /usr/local/lib/site_perl .)) > > > > The uninitialized value warning is down to the code Barbie refers to: > > > > sub new { > > my ( $class, %args ) = @_; > > > > if ( $class eq __PACKAGE__ ) { > > if ( exists $args{driver_dsn} ) { > > my ( $scheme, $driver, $attr_string, $attr_hash,
$driver_dsn ) Show quoted text
> > = DBI->parse_dsn( $args{driver_dsn} ); > > $args{dbd} = $driver; > > } > > croak "dbd or driver_dsn parameter required" if !exists
> $args{dbd};
> > eval "require Test::Database::Driver::$args{dbd}" > > or do { $@ =~ s/ at .*?\z//s; croak $@; }; > > $class = "Test::Database::Driver::$args{dbd}"; > > $class->__init(); > > } > > > > Where %args contains: > > > > $VAR1 = { > > 'password' => '', > > 'driver_dsn' => undef, > > 'dbd' => 'DBM', > > 'username' => '' > > }; > > > > on entry hence "exists $args{driver_dsn}" is true and DBI's parse_dsn is > > called with an empty $args{driver_dsn} hence $driver is undef and > > assigned to $args{dbd} and the eval fails. Barbie's change fixed that > > for me. > > > > Having run once it works but you can make it fail again my deleting > > /tmp/Test-Database-martin > > > > Martin
> > However, I think it is unwise to call DBI's parse_dsn with an undefined > value so I think the following is better: > > sub new { > my ( $class, %args ) = @_; > > if ( $class eq __PACKAGE__ ) { > > if ( exists $args{driver_dsn} && defined($args{driver_dsn})) { > my ( $scheme, $driver, $attr_string, $attr_hash, $driver_dsn ) > = DBI->parse_dsn( $args{driver_dsn} ); > $args{dbd} = $driver; > } > croak "dbd or driver_dsn parameter required" unless(exists > $args{dbd} && $args{dbd}); > #croak "dbd or driver_dsn parameter required" if !exists
$args{dbd}; Show quoted text
> eval "require Test::Database::Driver::$args{dbd}" > or do { $@ =~ s/ at .*?\z//s; croak $@; }; > $class = "Test::Database::Driver::$args{dbd}"; > $class->__init(); > }
However, I think it is unwise to call DBI's parse_dsn with an undefined value and this leads to other warnings later. The following is better for me: sub new { my ( $class, %args ) = @_; if ( $class eq __PACKAGE__ ) { # added defined in the following: if ( exists $args{driver_dsn} && defined($args{driver_dsn})) { my ( $scheme, $driver, $attr_string, $attr_hash, $driver_dsn ) = DBI->parse_dsn( $args{driver_dsn} ); $args{dbd} = $driver; } croak "dbd or driver_dsn parameter required" unless(exists $args{dbd} && $args{dbd}); #croak "dbd or driver_dsn parameter required" if !exists $args{dbd}; eval "require Test::Database::Driver::$args{dbd}" or do { $@ =~ s/ at .*?\z//s; croak $@; }; $class = "Test::Database::Driver::$args{dbd}"; $class->__init(); } Martin -- Martin J. Evans Wetherby, UK
On Thu Apr 22 05:00:04 2010, MJEVANS wrote: Show quoted text
> > > > Where %args contains: > > > > $VAR1 = { > > 'password' => '', > > 'driver_dsn' => undef, > > 'dbd' => 'DBM', > > 'username' => '' > > }; > >
This is an error in the test script itself. The proper patch is: diff --git a/t/10-drivers.t b/t/10-drivers.t index 94b956f..37845c9 100644 --- a/t/10-drivers.t +++ b/t/10-drivers.t @@ -9,7 +9,9 @@ use Test::Database::Driver; my @drivers = ( map { my $d = $_; - +{ map { $_ => $d->{$_} } qw( driver_dsn dbd username password ) } + +{ map { $_ => $d->{$_} } + grep { exists $d->{$_} } + qw( driver_dsn dbd username password ) } } Test::Database->drivers() ); This also removes a number of skips from the test. Removing the warnings is nice, but people putting garbage in should get garbage out. Even the test author. ;-) -- BooK
Subject: Re: [rt.cpan.org #56516] DSN report failures
Date: Tue, 27 Apr 2010 00:25:58 +0200
To: Barbie via RT <bug-Test-Database [...] rt.cpan.org>
From: "Philippe Bruhat (BooK)" <book [...] cpan.org>
On Mon, Apr 12, 2010 at 06:11:52AM -0400, Barbie via RT wrote: Show quoted text
> > However, the PrintError fix might be worth more investigation. >
Show quoted text
> # try to connect before returning the object > if ( !$class->is_filebased() ) { > - eval { DBI->connect_cached( $self->connection_info() ) } > + eval { DBI->connect_cached( $self->connection_info(), PrintError => 0 ) } > or return; > }
This fix actually gives this error: Can't use string ("PrintError") as a HASH ref while "strict refs" in use. because connect expects a hashref. However, it's indeed a good idea to silence errors that are expected, i.e. add a { PrintError => 0 } to all connect() calls that live inside an eval {}, so I did that. :-) Thanks for your proposed patch! -- Philippe Bruhat (BooK) History is made by the winners and written by those with the loudest voices. (Moral from Groo The Wanderer #10 (Epic))