1# -- 2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ 3# -- 4# This software comes with ABSOLUTELY NO WARRANTY. For details, see 5# the enclosed file COPYING for license information (GPL). If you 6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. 7# -- 8 9use strict; 10use warnings; 11use utf8; 12 13use vars (qw($Self)); 14 15# This test checks the slave handling features in DB.pm 16 17my $MasterDSN = $Kernel::OM->Get('Kernel::Config')->Get('DatabaseDSN'); 18my $MasterUser = $Kernel::OM->Get('Kernel::Config')->Get('DatabaseUser'); 19my $MasterPassword = $Kernel::OM->Get('Kernel::Config')->Get('DatabasePw'); 20 21my @Tests = ( 22 { 23 Name => "No slave configured", 24 Config => { 25 'Core::MirrorDB::DSN' => undef, 26 'Core::MirrorDB::User' => undef, 27 'Core::MirrorDB::Password' => undef, 28 'Core::MirrorDB::AdditionalMirrors' => undef, 29 }, 30 SlaveDBAvailable => 0, 31 TestIterations => 1, 32 }, 33 { 34 Name => "First slave configured", 35 Config => { 36 'Core::MirrorDB::DSN' => $MasterDSN, 37 'Core::MirrorDB::User' => $MasterUser, 38 'Core::MirrorDB::Password' => $MasterPassword, 39 'Core::MirrorDB::AdditionalMirrors' => undef, 40 }, 41 SlaveDBAvailable => 1, 42 TestIterations => 1, 43 }, 44 { 45 Name => "First slave configured as invalid", 46 Config => { 47 'Core::MirrorDB::DSN' => $MasterDSN, 48 'Core::MirrorDB::User' => 'wrong_user', 49 'Core::MirrorDB::Password' => 'wrong_password', 50 'Core::MirrorDB::AdditionalMirrors' => undef, 51 }, 52 SlaveDBAvailable => 0, 53 TestIterations => 1, 54 }, 55 { 56 Name => "Additional slave configured", 57 Config => { 58 'Core::MirrorDB::DSN' => undef, 59 'Core::MirrorDB::User' => undef, 60 'Core::MirrorDB::Password' => undef, 61 'Core::MirrorDB::AdditionalMirrors' => { 62 1 => { 63 DSN => $MasterDSN, 64 User => $MasterUser, 65 Password => $MasterPassword, 66 }, 67 }, 68 }, 69 SlaveDBAvailable => 1, 70 TestIterations => 1, 71 }, 72 { 73 Name => "Additional slave configured as invalid", 74 Config => { 75 'Core::MirrorDB::DSN' => undef, 76 'Core::MirrorDB::User' => undef, 77 'Core::MirrorDB::Password' => undef, 78 'Core::MirrorDB::AdditionalMirrors' => { 79 1 => { 80 DSN => $MasterDSN, 81 User => 'wrong_user', 82 Password => 'wrong_password', 83 }, 84 }, 85 }, 86 SlaveDBAvailable => 0, 87 TestIterations => 1, 88 }, 89 { 90 Name => "Full config with valid first slave and invalid additional", 91 Config => { 92 'Core::MirrorDB::DSN' => $MasterDSN, 93 'Core::MirrorDB::User' => $MasterUser, 94 'Core::MirrorDB::Password' => $MasterPassword, 95 'Core::MirrorDB::AdditionalMirrors' => { 96 1 => { 97 DSN => $MasterDSN, 98 User => 'wrong_user', 99 Password => 'wrong_password', 100 }, 101 2 => { 102 DSN => $MasterDSN, 103 User => $MasterUser, 104 Password => $MasterPassword, 105 }, 106 }, 107 }, 108 SlaveDBAvailable => 1, 109 110 # Use many iterations so that also the invalid mirror will be tried first at some point, probably. 111 TestIterations => 10, 112 }, 113); 114 115TEST: 116for my $Test (@Tests) { 117 118 for my $TestIteration ( 1 .. $Test->{TestIterations} ) { 119 120 $Kernel::OM->ObjectsDiscard(); 121 122 for my $ConfigKey ( sort keys %{ $Test->{Config} } ) { 123 $Kernel::OM->Get('Kernel::Config')->Set( 124 Key => $ConfigKey, 125 Value => $Test->{Config}->{$ConfigKey}, 126 ); 127 } 128 129 { 130 # Regular fetch from master 131 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 132 my @ValidIDs; 133 my $TestPrefix = "$Test->{Name} - $TestIteration - UseSlaveDB 0: "; 134 $DBObject->Prepare( 135 SQL => "\nSELECT id\nFROM valid", # simulate indentation 136 ); 137 while ( my @Row = $DBObject->FetchrowArray() ) { 138 push @ValidIDs, $Row[0]; 139 } 140 $Self->True( 141 scalar @ValidIDs, 142 "$TestPrefix valid ids were found", 143 ); 144 $Self->True( 145 $DBObject->{Cursor}, 146 "$TestPrefix statement handle active on master", 147 ); 148 $Self->False( 149 $DBObject->{SlaveDBObject}, 150 "$TestPrefix SlaveDB not connected", 151 ); 152 153 $Kernel::OM->ObjectsDiscard( 154 Objects => ['Kernel::System::DB'], 155 ); 156 } 157 158 { 159 local $Kernel::System::DB::UseSlaveDB = 1; 160 161 my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); 162 my @ValidIDs = (); 163 my $TestPrefix = "$Test->{Name} - $TestIteration - UseSlaveDB 1: "; 164 165 $DBObject->Prepare( 166 SQL => "\nSELECT id\nFROM valid", # simulate indentation 167 ); 168 while ( my @Row = $DBObject->FetchrowArray() ) { 169 push @ValidIDs, $Row[0]; 170 } 171 $Self->True( 172 scalar @ValidIDs, 173 "$TestPrefix valid ids were found", 174 ); 175 176 if ( !$Test->{SlaveDBAvailable} ) { 177 $Self->True( 178 $DBObject->{Cursor}, 179 "$TestPrefix statement handle active on master", 180 ); 181 $Self->False( 182 $DBObject->{SlaveDBObject}, 183 "$TestPrefix SlaveDB not connected", 184 ); 185 next TEST; 186 } 187 188 $Self->False( 189 $DBObject->{Cursor}, 190 "$TestPrefix statement handle inactive on master", 191 ); 192 $Self->True( 193 $DBObject->{SlaveDBObject}->{Cursor}, 194 "$TestPrefix statement handle active on slave", 195 ); 196 197 $Self->False( 198 scalar $DBObject->Ping( AutoConnect => 0 ), 199 "$TestPrefix master object is not connected automatically", 200 ); 201 202 $Self->True( 203 scalar $DBObject->{SlaveDBObject}->Ping( AutoConnect => 0 ), 204 "$TestPrefix slave object is connected", 205 ); 206 207 $DBObject->Disconnect(); 208 209 $Self->False( 210 scalar $DBObject->Ping( AutoConnect => 0 ), 211 "$TestPrefix master object is disconnected", 212 ); 213 214 $Self->False( 215 scalar $DBObject->{SlaveDBObject}->Ping( AutoConnect => 0 ), 216 "$TestPrefix slave object is disconnected", 217 ); 218 219 $DBObject->Connect(); 220 221 $Self->True( 222 scalar $DBObject->Ping( AutoConnect => 0 ), 223 "$TestPrefix master object is reconnected", 224 ); 225 226 $Self->True( 227 scalar $DBObject->{SlaveDBObject}->Ping( AutoConnect => 0 ), 228 "$TestPrefix slave object is not reconnected automatically", 229 ); 230 } 231 } 232} 233 2341; 235