use DBICTest;
BEGIN {
- eval "use Moose; use Test::Moose";
+ eval "use DBIx::Class::Storage::DBI::Replicated; use Test::Moose";
plan $@
- ? ( skip_all => 'needs Moose for testing' )
- : ( tests => 57 );
+ ? ( skip_all => "Deps not installed: $@" )
+ : ( tests => 79 );
}
use_ok 'DBIx::Class::Storage::DBI::Replicated::Pool';
## Get the Schema and set the replication storage type
sub init_schema {
+ # current SQLT SQLite producer does not handle DROP TABLE IF EXISTS, trap warnings here
+ local $SIG{__WARN__} = sub { warn @_ unless $_[0] =~ /no such table.+DROP TABLE/ };
+
my $class = shift @_;
-
+
my $schema = DBICTest->init_schema(
+ sqlite_use_file => 1,
storage_type=>{
'::DBI::Replicated' => {
balancer_type=>'::Random',
## Make sure all the slaves have the table definitions
$replicated->replicate;
+$replicated->schema->storage->replicants->{$replicant_names[0]}->active(1);
+$replicated->schema->storage->replicants->{$replicant_names[1]}->active(1);
+$replicated->schema->storage->pool->validate_replicants;
## Make sure we can read the data.
[ 7, "Watergate"],
]);
-SKIP: {
- ## We can't do this test if we have a custom replicants, since we assume
- ## if there are custom one that you are trying to test a real replicating
- ## system. See docs above for more.
-
- skip 'Cannot test inconsistent replication since you have a real replication system', 1
- if DBICTest->has_custom_dsn && $ENV{"DBICTEST_SLAVE0_DSN"};
-
- ## Alright, the database 'cluster' is not in a consistent state. When we do
- ## a read now we expect bad news
- is $replicated->schema->resultset('Artist')->find(5), undef
- => 'read after disconnect fails because it uses a replicant which we have neglected to "replicate" yet';
-}
-
## Make sure all the slaves have the table definitions
$replicated->replicate;
=> 'Found expected name for first result';
is $replicated->schema->storage->pool->connected_replicants => 1
- => "One replicant reconnected to handle the job";
+ => "At Least One replicant reconnected to handle the job";
## What happens when we try to select something that doesn't exist?
$replicated->schema->storage->replicants->{$replicant_names[0]}->active(1);
$replicated->schema->storage->replicants->{$replicant_names[1]}->active(1);
+$replicated->schema->storage->pool->validate_replicants;
ok $replicated->schema->resultset('Artist')->find(2)
=> 'Returned to replicates';
} => 'created coderef properly';
throws_ok {$replicated->schema->storage->execute_reliably($unreliably)}
- qr/coderef returned an error: Can't find source for ArtistXX/
+ qr/Can't find source for ArtistXX/
=> 'Bad coderef throws proper error';
+## Make sure replication came back
+
+ok $replicated->schema->resultset('Artist')->find(3)
+ => 'replicant reactivated';
+
## make sure transactions are set to execute_reliably
ok my $transaction = sub {
+ my $id = shift @_;
+
$replicated
->schema
->populate('Artist', [
[ qw/artistid name/ ],
- [ 666, "Children of the Grave"],
+ [ $id, "Children of the Grave"],
]);
- ok my $result = $replicated->schema->resultset('Artist')->find(666);
+ ok my $result = $replicated->schema->resultset('Artist')->find($id)
+ => 'Found expected artist';
+
+ ok my $more = $replicated->schema->resultset('Artist')->find(1)
+ => 'Found expected artist again';
+
+ return ($result, $more);
-};
+} => 'Created a coderef properly';
-$replicated->schema->txn_do($transaction);
+## Test the transaction with multi return
+{
+ ok my @return = $replicated->schema->txn_do($transaction, 666)
+ => 'did transaction';
+
+ is $return[0]->id, 666
+ => 'first returned value is correct';
+
+ is $return[1]->id, 1
+ => 'second returned value is correct';
+}
+
+## Test that asking for single return works
+{
+ ok my $return = $replicated->schema->txn_do($transaction, 777)
+ => 'did transaction';
+
+ is $return->id, 777
+ => 'first returned value is correct';
+}
+
+## Test transaction returning a single value
+
+{
+ ok my $result = $replicated->schema->txn_do(sub {
+ ok my $more = $replicated->schema->resultset('Artist')->find(1)
+ => 'found inside a transaction';
+ return $more;
+ }) => 'successfully processed transaction';
+
+ is $result->id, 1
+ => 'Got expected single result from transaction';
+}
## Make sure replication came back
-ok $replicated->schema->resultset('Artist')->find(5)
+ok $replicated->schema->resultset('Artist')->find(1)
=> 'replicant reactivated';
-
-## Delete the old database files
-$replicated->cleanup;
-
+
+## Test Discard changes
+{
+ ok my $artist = $replicated->schema->resultset('Artist')->find(2)
+ => 'got an artist to test discard changes';
+
+ ok $artist->discard_changes
+ => 'properly discard changes';
+}
+## Test some edge cases, like trying to do a transaction inside a transaction, etc
+{
+ ok my $result = $replicated->schema->txn_do(sub {
+ return $replicated->schema->txn_do(sub {
+ ok my $more = $replicated->schema->resultset('Artist')->find(1)
+ => 'found inside a transaction inside a transaction';
+ return $more;
+ });
+ }) => 'successfully processed transaction';
+
+ is $result->id, 1
+ => 'Got expected single result from transaction';
+}
+{
+ ok my $result = $replicated->schema->txn_do(sub {
+ return $replicated->schema->storage->execute_reliably(sub {
+ return $replicated->schema->txn_do(sub {
+ return $replicated->schema->storage->execute_reliably(sub {
+ ok my $more = $replicated->schema->resultset('Artist')->find(1)
+ => 'found inside crazy deep transactions and execute_reliably';
+ return $more;
+ });
+ });
+ });
+ }) => 'successfully processed transaction';
+
+ is $result->id, 1
+ => 'Got expected single result from transaction';
+}
+
+## Test the force_pool resultset attribute.
+
+{
+ ok my $artist_rs = $replicated->schema->resultset('Artist')
+ => 'got artist resultset';
+
+ ## Turn on Forced Pool Storage
+ ok my $reliable_artist_rs = $artist_rs->search(undef, {force_pool=>'master'})
+ => 'Created a resultset using force_pool storage';
+
+ ok my $artist = $reliable_artist_rs->find(2)
+ => 'got an artist result via force_pool storage';
+}
+## Delete the old database files
+$replicated->cleanup;