X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2F72pg.t;h=ec1cab0e075275b97e3afdce7c6a525403f69341;hb=619f81c4e80407520781678162e020ca8d7bf0ef;hp=f3250edab96a38f057abe9ae167762d47ec6a877;hpb=8273e845426f0187b4ad6c4a1b42286fa09a648f;p=dbsrgits%2FDBIx-Class.git diff --git a/t/72pg.t b/t/72pg.t index f3250ed..ec1cab0 100644 --- a/t/72pg.t +++ b/t/72pg.t @@ -1,57 +1,27 @@ +use DBIx::Class::Optional::Dependencies -skip_all_without => 'test_rdbms_pg'; + use strict; use warnings; use Test::More; use Test::Exception; use Sub::Name; +use Config; use DBIx::Class::Optional::Dependencies (); use lib qw(t/lib); use DBICTest; - -plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_rdbms_pg') - unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_rdbms_pg'); +use SQL::Abstract 'is_literal_value'; +use DBIx::Class::_Util 'is_exception'; my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/}; -plan skip_all => <<'EOM' unless $dsn && $user; -Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test -( NOTE: This test drops and creates tables called 'artist', 'cd', -'timestamp_primary_key_test', 'track', 'casecheck', 'array_test' and -'sequence_test' as well as following sequences: 'pkid1_seq', 'pkid2_seq' and -'nonpkid_seq'. as well as following schemas: 'dbic_t_schema', -'dbic_t_schema_2', 'dbic_t_schema_3', 'dbic_t_schema_4', and 'dbic_t_schema_5') -EOM - ### load any test classes that are defined further down in the file via BEGIN blocks - our @test_classes; #< array that will be pushed into by test classes defined in this file DBICTest::Schema->load_classes( map {s/.+:://;$_} @test_classes ) if @test_classes; ### pre-connect tests (keep each test separate as to make sure rebless() runs) { my $s = DBICTest::Schema->connect($dsn, $user, $pass); - - ok (!$s->storage->_dbh, 'definitely not connected'); - - # Check that datetime_parser returns correctly before we explicitly connect. - SKIP: { - skip ( - "Pg parser detection test needs " . DBIx::Class::Optional::Dependencies->req_missing_for ('test_dt_pg'), - 2 - ) unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_dt_pg'); - - my $store = ref $s->storage; - is($store, 'DBIx::Class::Storage::DBI', 'Started with generic storage'); - - my $parser = $s->storage->datetime_parser; - is( $parser, 'DateTime::Format::Pg', 'datetime_parser is as expected'); - } - - ok (!$s->storage->_dbh, 'still not connected'); - } - - { - my $s = DBICTest::Schema->connect($dsn, $user, $pass); # make sure sqlt_type overrides work (::Storage::DBI::Pg does this) ok (!$s->storage->_dbh, 'definitely not connected'); is ($s->storage->sqlt_type, 'PostgreSQL', 'sqlt_type correct pre-connection'); @@ -91,14 +61,12 @@ DBICTest::Schema->load_classes( map {s/.+:://;$_} @test_classes ) if @test_class # check if we indeed do support stuff my $test_server_supports_insert_returning = do { - my $v = DBICTest::Schema->connect($dsn, $user, $pass) - ->storage - ->_get_dbh - ->get_info(18); - $v =~ /^(\d+)\.(\d+)/ - or die "Unparseable Pg server version: $v\n"; - - ( sprintf ('%d.%d', $1, $2) >= 8.2 ) ? 1 : 0; + + my $si = DBICTest::Schema->connect($dsn, $user, $pass)->storage->_server_info; + die "Unparseable Pg server version: $si->{dbms_version}\n" + unless $si->{normalized_dbms_version}; + + $si->{normalized_dbms_version} < 8.002 ? 0 : 1; }; is ( DBICTest::Schema->connect($dsn, $user, $pass)->storage->_use_insert_returning, @@ -112,9 +80,10 @@ for my $use_insert_returning ($test_server_supports_insert_returning : (0) ) { - no warnings qw/once/; + no warnings qw/once redefine/; + my $old_connection = DBICTest::Schema->can('connection'); local *DBICTest::Schema::connection = subname 'DBICTest::Schema::connection' => sub { - my $s = shift->next::method (@_); + my $s = shift->$old_connection(@_); $s->storage->_use_insert_returning ($use_insert_returning); $s; }; @@ -147,6 +116,16 @@ for my $use_insert_returning ($test_server_supports_insert_returning run_apk_tests($schema); #< older set of auto-pk tests run_extended_apk_tests($schema); #< new extended set of auto-pk tests + +######## test the pg-specific syntax from https://rt.cpan.org/Ticket/Display.html?id=99503 + lives_ok { + is( + $schema->resultset('Artist')->search({ artistid => { -in => \ '(select 4) union (select 5)' } })->count, + 2, + 'Two expected artists found on subselect union within IN', + ); + }; + ### type_info tests my $test_type_info = { @@ -184,14 +163,19 @@ for my $use_insert_returning ($test_server_supports_insert_returning my $type_info = $schema->storage->columns_info_for('dbic_t_schema.artist'); my $artistid_defval = delete $type_info->{artistid}->{default_value}; - like($artistid_defval, - qr/^nextval\('([^\.]*\.){0,1}artist_artistid_seq'::(?:text|regclass)\)/, - 'columns_info_for - sequence matches Pg get_autoinc_seq expectations'); - is_deeply($type_info, $test_type_info, - 'columns_info_for - column data types'); - + # The curor info is too radically different from what is in the column_info + # call - just punt it (DBD::SQLite tests the codepath plenty enough) + unless (DBIx::Class::_ENV_::STRESSTEST_COLUMN_INFO_UNAWARE_STORAGE) { + like( + $artistid_defval, + qr/^nextval\('([^\.]*\.){0,1}artist_artistid_seq'::(?:text|regclass)\)/, + 'columns_info_for - sequence matches Pg get_autoinc_seq expectations' + ); + is_deeply($type_info, $test_type_info, + 'columns_info_for - column data types'); + } ####### Array tests @@ -249,7 +233,7 @@ for my $use_insert_returning ($test_server_supports_insert_returning lives_ok { is_deeply ( $arr_rs->search({ arrayfield => { '=' => { -value => [3,4] }} })->first->arrayfield, - [3,4],, + [3,4], 'Array value matches explicit equal' ); } 'searching by arrayref (explicit equal sign)'; @@ -288,11 +272,14 @@ for my $use_insert_returning ($test_server_supports_insert_returning } 'find by arrayref (equal)'; # test inferred condition for creation - TODO: for my $cond ( + for my $cond ( { -value => [3,4] }, \[ '= ?' => [arrayfield => [3, 4]] ], ) { - local $TODO = 'No introspection of complex conditions :('; + local $TODO = 'No introspection of complex literal conditions :(' + if is_literal_value $cond; + + my $arr_rs_cond = $arr_rs->search({ arrayfield => $cond }); my $row = $arr_rs_cond->create({}); @@ -336,14 +323,9 @@ my $cds = $artist->cds_unordered->search({ lives_ok { $cds->update({ year => '2010' }) } 'Update on prefetched rs'; ## Test SELECT ... FOR UPDATE - SKIP: { - if(eval { require Sys::SigAction }) { - Sys::SigAction->import( 'set_sig_handler' ); - } - else { - skip "Sys::SigAction is not available", 6; - } + skip "Your system does not support unsafe signals (d_sigaction) - unable to run deadlock test", 1 + unless eval { $Config{d_sigaction} and require POSIX }; my ($timed_out, $artist2); @@ -382,15 +364,34 @@ lives_ok { $cds->update({ year => '2010' }) } 'Update on prefetched rs'; is($artist->artistid, 1, "select returns artistid = 1"); $timed_out = 0; + eval { - my $h = set_sig_handler( 'ALRM', sub { die "DBICTestTimeout" } ); - alarm(2); + # can not use %SIG assignment directly - we need sigaction below + # localization to a block still works however + local $SIG{ALRM}; + + POSIX::sigaction( POSIX::SIGALRM() => POSIX::SigAction->new( + sub { die "DBICTestTimeout" }, + )); + $artist2 = $schema2->resultset('Artist')->find(1); $artist2->name('fooey'); + + # FIXME - this needs to go away in lieu of a non-retrying runner + # ( i.e. after solving RT#47005 ) + local *DBIx::Class::Storage::DBI::_ping = sub { 1 }, DBIx::Class::_ENV_::OLD_MRO && Class::C3->reinitialize() + if DBIx::Class::_Util::modver_gt_or_eq( 'DBD::Pg' => '3.5.0' ); + + alarm(1); $artist2->update; - alarm(0); }; - $timed_out = $@ =~ /DBICTestTimeout/; + + alarm(0); + + if (is_exception($@)) { + $timed_out = $@ =~ /DBICTestTimeout/ + or die $@; + } }); $t->{test_sub}->(); @@ -449,7 +450,8 @@ done_testing; END { return unless $schema; drop_test_schema($schema); - eapk_drop_all( $schema) + eapk_drop_all($schema); + undef $schema; };