9 ? ( skip_all => 'needs DBD::Multi for testing' )
13 ## ----------------------------------------------------------------------------
14 ## Build a class to hold all our required testing data and methods.
15 ## ----------------------------------------------------------------------------
19 package DBIx::Class::DBI::Replicated::TestReplication;
25 ## Create a constructor
32 db_paths => $params{db_paths},
33 dsns => $class->init_dsns(%params),
34 schema=>$class->init_schema,
41 ## get the DSNs. We build this up from the list of file paths
46 my $db_paths = $params{db_paths};
55 ## get the Schema and set the replication storage type
59 my $schema = DBICTest->init_schema();
60 $schema->storage_type( '::DBI::Replicated' );
69 my ($master, @slaves) = @{$self->{dsns}};
70 my $master_connect_info = [$master, '','', {AutoCommit=>1, PrintError=>0}];
73 foreach my $slave (@slaves)
75 my $dbh = shift @{$self->{slaves}}
76 || DBI->connect($slave,"","",{PrintError=>0, PrintWarn=>0});
78 push @{$master_connect_info->[-1]->{slaves_connect_info}},
79 [$dbh, '','',{priority=>10}];
85 ## Keep track of the created slave databases
86 $self->{slaves} = \@slavesob;
90 ->connect(@$master_connect_info);
97 my ($master, @slaves) = @{$self->{db_paths}};
99 foreach my $slave (@slaves) {
100 copy($master, $slave);
104 ## Cleanup afer ourselves.
108 my ($master, @slaves) = @{$self->{db_paths}};
110 foreach my $slave (@slaves) {
115 ## Force a reconnection
119 my $schema = $self->connect;
120 $self->{schema} = $schema;
125 ## ----------------------------------------------------------------------------
126 ## Create an object and run some tests
127 ## ----------------------------------------------------------------------------
131 "t/var/DBIxClass.db",
132 "t/var/DBIxClass_slave1.db",
133 "t/var/DBIxClass_slave2.db",
137 ok my $replicate = DBIx::Class::DBI::Replicated::TestReplication->new(%params)
138 => 'Created a replication object';
140 isa_ok $replicate->{schema}
141 => 'DBIx::Class::Schema';
143 ## Add some info to the database
147 ->populate('Artist', [
148 [ qw/artistid name/ ],
149 [ 4, "Ozric Tentacles"],
152 ## Make sure all the slaves have the table definitions
154 $replicate->replicate;
156 ## Make sure we can read the data.
158 ok my $artist1 = $replicate->{schema}->resultset('Artist')->find(4)
162 => 'DBICTest::Artist';
164 is $artist1->name, 'Ozric Tentacles'
165 => 'Found expected name for first result';
167 ## Add some new rows that only the master will have This is because
168 ## we overload any type of write operation so that is must hit the master
173 ->populate('Artist', [
174 [ qw/artistid name/ ],
175 [ 5, "Doom's Children"],
176 [ 6, "Dead On Arrival"],
180 ## Reconnect the database
181 $replicate->reconnect;
183 ## Alright, the database 'cluster' is not in a consistent state. When we do
184 ## a read now we expect bad news
186 is $replicate->{schema}->resultset('Artist')->find(5), undef
187 => 'read after disconnect fails because it uses slave 1 which we have neglected to "replicate" yet';
189 ## Make sure all the slaves have the table definitions
190 $replicate->replicate;
192 ## Should find some data now
194 ok my $artist2 = $replicate->{schema}->resultset('Artist')->find(5)
198 => 'DBICTest::Artist';
200 is $artist2->name, "Doom's Children"
201 => 'Found expected name for first result';
203 ## What happens when we delete one of the slaves?
205 ok my $slave1 = @{$replicate->{slaves}}[0]
208 ok $slave1->disconnect
209 => 'disconnected slave1';
211 $replicate->reconnect;
213 ok my $artist3 = $replicate->{schema}->resultset('Artist')->find(6)
214 => 'Still finding stuff.';
217 => 'DBICTest::Artist';
219 is $artist3->name, "Dead On Arrival"
220 => 'Found expected name for first result';
222 ## Let's delete all the slaves
224 ok my $slave2 = @{$replicate->{slaves}}[1]
227 ok $slave2->disconnect
228 => 'Disconnected slave2';
230 $replicate->reconnect;
232 ## We expect an error now, since all the slaves are dead
235 $replicate->{schema}->resultset('Artist')->find(4)->name;
238 ok $@ => 'Got error when trying to find artistid 4';
240 ## This should also be an error
243 my $artist4 = $replicate->{schema}->resultset('Artist')->find(7);
246 ok $@ => 'Got read errors after everything failed';
248 ## make sure ->connect_info returns something sane
250 ok $replicate->{schema}->storage->connect_info
251 => 'got something out of ->connect_info';
253 ## Force a connection to the write source for testing.
255 $replicate->{schema}->storage($replicate->{schema}->storage->write_source);
257 ## What happens when we do a find for something that doesn't exist?
259 ok ! $replicate->{schema}->resultset('Artist')->find(666)
260 => 'Correctly did not find a bad artist id';
262 ## Delete the old database files