From d7051b6d8d3c634c4f69b3d637295df85fe176cd Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Thu, 16 Mar 2017 21:08:31 +0200 Subject: [PATCH] Bug 18286: Test::DBIx::Class connection/schema is shadowed by a cached connection/schema Content-Type: text/plain; charset=utf-8 If Koha::Database->schema gets called before use Test::DBIx::Class The DB connection from $KOHA_CONF is cached. This happens most of the time because when C4::Context and friends are loaded (in compile-time?), they already access the DB. After Test::DBIx::Class is instantiated and hooks put in place to overload Koha::Schema connection, those hooks are never called due to getting the old connection from cache. This feature introduces a test case to replicate the behaviour and shows how flushing the connection cache solves the problem. Signed-off-by: Marcel de Rooy --- t/db_dependent/01-test_dbic.t | 108 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 t/db_dependent/01-test_dbic.t diff --git a/t/db_dependent/01-test_dbic.t b/t/db_dependent/01-test_dbic.t new file mode 100644 index 0000000..9f63d20 --- /dev/null +++ b/t/db_dependent/01-test_dbic.t @@ -0,0 +1,108 @@ +#!/usr/bin/perl + +# This file is part of Koha. +my $verbose = 0; + +use Modern::Perl; + +use Test::More; +use Test::MockModule; + +use Koha::Libraries; +use C4::Context; +Koha::Libraries->search->count; + + + +subtest "Scenario: Show how caching prevents Test::DBIx::Class from working properly and how to circumvent it", sub { + my ($firstSchema, $schema, $cachedSchema, $cachedSchema2, $firstLibCount, $libCount); + + eval { + + ok($firstSchema = Koha::Database->schema, + 'Step: Given a normal DB connection.'); + + ok($firstLibCount = Koha::Libraries->search->count, + ' When the libraries are counted'); + + ok($firstLibCount, + ' Then we got a count'); #There should be something like 12 branches in the default DB but making an accurate check here to prevent surface for brittleness. + print "\$firstLibCount '$firstLibCount'\n" if $verbose; + + ok($cachedSchema = Koha::Database::get_schema_cached(), + ' And the DB connection is cached'); + + unlike(getConnectionDBName($cachedSchema), qr/sqlite/i, + ' And the cached DB connection type is not sqlite'); + print "getConnectionDBName() -> ".getConnectionDBName($cachedSchema)."\n" if $verbose; + + + use_ok('Test::DBIx::Class'); + my $db = Test::MockModule->new('Koha::Database'); + $db->mock( _new_schema => sub { return Schema(); } ); + ok(1, + 'Step: Given Test::DBIx::Class (T:D:C) is loaded and DB accessor is mocked. Connection from cache is still used.'); + + ok($libCount = Koha::Libraries->search->count, + ' When the libraries are counted'); + + is($libCount, $firstLibCount, + ' Then we got the same count as without T:D:C'); + + $cachedSchema = Koha::Database::get_schema_cached(); + is($cachedSchema, $firstSchema, + ' And the cached DB connection is the same as without T:D:C'); + + is(getConnectionDBName($cachedSchema), getConnectionDBName($firstSchema), + ' And the cached DB connection type is unchanged'); + + + ok(Koha::Database::flush_schema_cache(), + 'Step: Given the DB connection cache is flushed'); + + ok(! ($libCount = Koha::Libraries->search->count), + ' When the libraries are counted'); + + is($libCount, 0, + ' Then we got 0 libraries because fixtures are not deployed'); + + $cachedSchema = Koha::Database::get_schema_cached(); + isnt($cachedSchema, $firstSchema, + ' And the cached DB connection has changed'); + + like(getConnectionDBName($cachedSchema), qr/sqlite/i, + ' And the cached DB connection type is sqlite'); + + + eval "fixtures_ok [ #Dynamically load fixtures, because we dynamically load T:D:C. Otherwise there be compile errors! + Branch => [ + ['branchcode', 'branchname'], + ['XXX_test', 'my branchname XXX'], + ] + ], + 'Step: Given we deploy T:D:C Fixtures';"; + + ok($libCount = Koha::Libraries->search->count, + ' When the libraries are counted'); + + is($libCount, 1, + ' Then we got the count from fixtures'); + + $cachedSchema2 = Koha::Database::get_schema_cached(); + is($cachedSchema2, $cachedSchema, + ' And the cached DB connection is the same from T:D:C'); + + like(getConnectionDBName($cachedSchema), qr/sqlite/i, + ' And the cached DB connection type is sqlite'); + + }; + ok(0, $@) if $@; +}; + +done_testing; + + +sub getConnectionDBName { + #return shift->storage->_dbh_details->{info}->{dbms_version}; #This would return the name from server, but sqlite doesn't report a clear text name and version here. + return shift->storage->connect_info->[0]->{dsn}; +} -- 2.1.4