use DBICTest;
BEGIN {
- eval "use Moose";
+ eval "use Moose; use Test::Moose";
plan $@
? ( skip_all => 'needs Moose for testing' )
- : ( tests => 40 );
+ : ( tests => 46 );
}
use_ok 'DBIx::Class::Storage::DBI::Replicated::Pool';
use_ok 'DBIx::Class::Storage::DBI::Replicated::Balancer';
-use_ok 'DBIx::Class::Storage::DBI::Replicated::Balancer::Random';
use_ok 'DBIx::Class::Storage::DBI::Replicated::Replicant';
use_ok 'DBIx::Class::Storage::DBI::Replicated';
+=head1 HOW TO USE
+
+ This is a test of the replicated storage system. This will work in one of
+ two ways, either it was try to fake replication with a couple of SQLite DBs
+ and creative use of copy, or if you define a couple of %ENV vars correctly
+ will try to test those. If you do that, it will assume the setup is properly
+ replicating. Your results may vary, but I have demonstrated this to work with
+ mysql native replication.
+
+=cut
+
+
## ----------------------------------------------------------------------------
## Build a class to hold all our required testing data and methods.
## ----------------------------------------------------------------------------
sub init_schema {
my $class = shift @_;
+
my $schema = DBICTest->init_schema(
- storage_type=>'::DBI::Replicated',
- storage_type_args=>{
- balancer_type=>'DBIx::Class::Storage::DBI::Replicated::Balancer::Random',
- });
+ storage_type=>[
+ '::DBI::Replicated' => {
+ balancer_type=>'::Random',
+ }
+ ],
+ deploy_args=>{
+ add_drop_table => 1,
+ },
+ );
return $schema;
}
is $replicated->schema->storage->num_replicants => 2
=> 'has two replicants';
-isa_ok $replicated_storages[0]
+does_ok $replicated_storages[0]
=> 'DBIx::Class::Storage::DBI::Replicated::Replicant';
-isa_ok $replicated_storages[1]
+does_ok $replicated_storages[1]
=> 'DBIx::Class::Storage::DBI::Replicated::Replicant';
-isa_ok $replicated->schema->storage->replicants->{"t/var/DBIxClass_slave1.db"}
+my @replicant_names = keys %{$replicated->schema->storage->replicants};
+
+does_ok $replicated->schema->storage->replicants->{$replicant_names[0]}
=> 'DBIx::Class::Storage::DBI::Replicated::Replicant';
-isa_ok $replicated->schema->storage->replicants->{"t/var/DBIxClass_slave2.db"}
+does_ok $replicated->schema->storage->replicants->{$replicant_names[1]}
=> 'DBIx::Class::Storage::DBI::Replicated::Replicant';
## Add some info to the database
[ 7, "Watergate"],
]);
-## 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';
+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;
is $replicated->schema->storage->pool->connected_replicants => 2
=> "both replicants are connected";
-$replicated->schema->storage->replicants->{"t/var/DBIxClass_slave1.db"}->disconnect;
-$replicated->schema->storage->replicants->{"t/var/DBIxClass_slave2.db"}->disconnect;
+$replicated->schema->storage->replicants->{$replicant_names[0]}->disconnect;
+$replicated->schema->storage->replicants->{$replicant_names[1]}->disconnect;
is $replicated->schema->storage->pool->connected_replicants => 0
=> "both replicants are now disconnected";
$replicated->schema->storage->set_balanced_storage;
ok $replicated->schema->resultset('Artist')->find(3)
- => 'Read from replicant';
+ => 'Read from replicant';
}
-## Make sure when $reliable goes out of scope, we are using replicants again
+## Make sure when reliable goes out of scope, we are using replicants again
ok $replicated->schema->resultset('Artist')->find(1)
=> 'back to replicant 1.';
ok $replicated->schema->resultset('Artist')->find(2)
=> 'back to replicant 2.';
+
+## set all the replicants to inactive, and make sure the balancer falls back to
+## the master.
+
+$replicated->schema->storage->replicants->{$replicant_names[0]}->active(0);
+$replicated->schema->storage->replicants->{$replicant_names[1]}->active(0);
+ok $replicated->schema->resultset('Artist')->find(2)
+ => 'Fallback to master';
+
+$replicated->schema->storage->replicants->{$replicant_names[0]}->active(1);
+$replicated->schema->storage->replicants->{$replicant_names[1]}->active(1);
+
+ok $replicated->schema->resultset('Artist')->find(2)
+ => 'Returned to replicates';
+
+## Getting slave status tests
+
+SKIP: {
+ ## We skip this tests unless you have a custom replicants, since the default
+ ## sqlite based replication tests don't support these functions.
+
+ skip 'Cannot Test Replicant Status on Non Replicating Database', 3
+ unless DBICTest->has_custom_dsn && $ENV{"DBICTEST_SLAVE0_DSN"};
+
+ $replicated->replicate; ## Give the slaves a chance to catchup.
+
+ ok $replicated->schema->storage->replicants->{$replicant_names[0]}->is_replicating
+ => 'Replicants are replicating';
+
+ is $replicated->schema->storage->replicants->{$replicant_names[0]}->lag_behind_master, 0
+ => 'Replicant is zero seconds behind master';
+
+ ## Test the validate replicants
+
+ $replicated->schema->storage->pool->validate_replicants;
+
+ is $replicated->schema->storage->pool->active_replicants, 2
+ => 'Still have 2 replicants after validation';
+
+ ## Force the replicants to fail the validate test by required their lag to
+ ## be negative (ie ahead of the master!)
+
+ $replicated->schema->storage->pool->maximum_lag(-10);
+ $replicated->schema->storage->pool->validate_replicants;
+
+ is $replicated->schema->storage->pool->active_replicants, 0
+ => 'No way a replicant be be ahead of the master';
+
+ ## Let's be fair to the replicants again. Let them lag up to 5
+
+ $replicated->schema->storage->pool->maximum_lag(5);
+ $replicated->schema->storage->pool->validate_replicants;
+
+ is $replicated->schema->storage->pool->active_replicants, 2
+ => 'Both replicants in good standing again';
+}
## Delete the old database files
$replicated->cleanup;