File indexing completed on 2024-04-21 04:48:05
0001 /**************************************************************************************** 0002 * Copyright (c) 2010 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #include "TestMasterSlaveSynchronizationJob.h" 0018 0019 #include "core/support/Debug.h" 0020 #include "core/collections/CollectionLocation.h" 0021 #include "core/collections/CollectionLocationDelegate.h" 0022 #include "core/support/Components.h" 0023 #include "synchronization/MasterSlaveSynchronizationJob.h" 0024 0025 #include "CollectionTestImpl.h" 0026 #include "core/collections/MockCollectionLocationDelegate.h" 0027 #include "mocks/MockTrack.h" 0028 #include "mocks/MockAlbum.h" 0029 #include "mocks/MockArtist.h" 0030 0031 #include <gmock/gmock.h> 0032 0033 #include <QSignalSpy> 0034 0035 0036 QTEST_GUILESS_MAIN( TestMasterSlaveSynchronizationJob ) 0037 0038 using ::testing::Return; 0039 using ::testing::AnyNumber; 0040 using ::testing::_; 0041 0042 static int trackCopyCount; 0043 static int trackRemoveCount; 0044 0045 namespace Collections { 0046 0047 class MyCollectionLocation : public CollectionLocation 0048 { 0049 public: 0050 Collections::CollectionTestImpl *coll; 0051 0052 QString prettyLocation() const override { return "foo"; } 0053 bool isWritable() const override { return true; } 0054 0055 void removeUrlsFromCollection( const Meta::TrackList &sources ) override 0056 { 0057 trackRemoveCount += sources.count(); 0058 coll->mc->acquireWriteLock(); 0059 TrackMap map = coll->mc->trackMap(); 0060 foreach( const Meta::TrackPtr &track, sources ) 0061 map.remove( track->uidUrl() ); 0062 coll->mc->setTrackMap( map ); 0063 coll->mc->releaseLock(); 0064 slotRemoveOperationFinished(); 0065 } 0066 0067 void copyUrlsToCollection(const QMap<Meta::TrackPtr, QUrl> &sources, const Transcoding::Configuration& conf) override 0068 { 0069 Q_UNUSED( conf ) 0070 trackCopyCount = sources.count(); 0071 foreach( const Meta::TrackPtr &track, sources.keys() ) 0072 { 0073 coll->mc->addTrack( track ); 0074 } 0075 } 0076 }; 0077 0078 class MyCollectionTestImpl : public CollectionTestImpl 0079 { 0080 public: 0081 MyCollectionTestImpl( const QString &id ) : CollectionTestImpl( id ) {} 0082 0083 CollectionLocation* location() override 0084 { 0085 MyCollectionLocation *r = new MyCollectionLocation(); 0086 r->coll = this; 0087 return r; 0088 } 0089 }; 0090 0091 } //namespace Collections 0092 0093 void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName ) 0094 { 0095 Meta::MockTrack *track = new Meta::MockTrack(); 0096 ::testing::Mock::AllowLeak( track ); 0097 Meta::TrackPtr trackPtr( track ); 0098 EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); 0099 EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) ); 0100 EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) ); 0101 coll->mc->addTrack( trackPtr ); 0102 0103 Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ ); 0104 Meta::MockAlbum *album; 0105 Meta::TrackList albumTracks; 0106 if( albumPtr ) 0107 { 0108 album = dynamic_cast<Meta::MockAlbum*>( albumPtr.data() ); 0109 if( !album ) 0110 { 0111 QFAIL( "expected a Meta::MockAlbum" ); 0112 return; 0113 } 0114 albumTracks = albumPtr->tracks(); 0115 } 0116 else 0117 { 0118 album = new Meta::MockAlbum(); 0119 ::testing::Mock::AllowLeak( album ); 0120 albumPtr = Meta::AlbumPtr( album ); 0121 EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); 0122 EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); 0123 EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ArtistPtr() ) ); 0124 coll->mc->addAlbum( albumPtr ); 0125 } 0126 albumTracks << trackPtr; 0127 EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) ); 0128 0129 EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) ); 0130 0131 Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName ); 0132 Meta::MockArtist *artist; 0133 Meta::TrackList artistTracks; 0134 if( artistPtr ) 0135 { 0136 artist = dynamic_cast<Meta::MockArtist*>( artistPtr.data() ); 0137 if( !artist ) 0138 { 0139 QFAIL( "expected a Meta::MockArtist" ); 0140 return; 0141 } 0142 artistTracks = artistPtr->tracks(); 0143 } 0144 else 0145 { 0146 artist = new Meta::MockArtist(); 0147 ::testing::Mock::AllowLeak( artist ); 0148 artistPtr = Meta::ArtistPtr( artist ); 0149 EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); 0150 coll->mc->addArtist( artistPtr ); 0151 } 0152 artistTracks << trackPtr; 0153 EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) ); 0154 EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); 0155 } 0156 0157 TestMasterSlaveSynchronizationJob::TestMasterSlaveSynchronizationJob() 0158 { 0159 int argc = 1; 0160 char **argv = (char **) malloc(sizeof(char *)); 0161 argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); 0162 ::testing::InitGoogleMock( &argc, argv ); 0163 qRegisterMetaType<Meta::TrackList>(); 0164 qRegisterMetaType<Meta::AlbumList>(); 0165 qRegisterMetaType<Meta::ArtistList>(); 0166 } 0167 0168 void 0169 TestMasterSlaveSynchronizationJob::init() 0170 { 0171 trackCopyCount = 0; 0172 trackRemoveCount = 0; 0173 } 0174 0175 void 0176 TestMasterSlaveSynchronizationJob::testAddTracksToEmptySlave() 0177 { 0178 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0179 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0180 0181 //setup master 0182 addMockTrack( master, "track1", "artist1", "album1" ); 0183 QCOMPARE( master->mc->trackMap().count(), 1 ); 0184 QCOMPARE( slave->mc->trackMap().count(), 0 ); 0185 QCOMPARE( trackCopyCount, 0 ); 0186 QCOMPARE( trackRemoveCount, 0 ); 0187 0188 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0189 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0190 job->setMaster( master ); 0191 job->setSlave( slave ); 0192 job->synchronize(); 0193 spy.wait( 1000 ); 0194 0195 QCOMPARE( trackCopyCount, 1 ); 0196 QCOMPARE( trackRemoveCount, 0 ); 0197 QCOMPARE( master->mc->trackMap().count(), 1 ); 0198 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0199 delete master; 0200 delete slave; 0201 } 0202 0203 void 0204 TestMasterSlaveSynchronizationJob::testAddSingleTrack() 0205 { 0206 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0207 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0208 0209 //setup 0210 addMockTrack( master, "track1", "artist1", "album1" ); 0211 addMockTrack( slave, "track1", "artist1", "album1" ); 0212 addMockTrack( master, "track2", "artist1", "album1" ); 0213 0214 QCOMPARE( master->mc->trackMap().count(), 2 ); 0215 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0216 QCOMPARE( trackCopyCount, 0 ); 0217 QCOMPARE( trackRemoveCount, 0 ); 0218 0219 //test 0220 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0221 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0222 job->setMaster( master ); 0223 job->setSlave( slave ); 0224 job->synchronize(); 0225 spy.wait( 1000 ); 0226 0227 //verify 0228 QCOMPARE( trackCopyCount, 1 ); 0229 QCOMPARE( trackRemoveCount, 0 ); 0230 QCOMPARE( master->mc->trackMap().count(), 2 ); 0231 QCOMPARE( slave->mc->trackMap().count(), 2 ); 0232 0233 delete master; 0234 delete slave; 0235 } 0236 0237 void 0238 TestMasterSlaveSynchronizationJob::testAddAlbum() 0239 { 0240 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0241 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0242 0243 //setup 0244 addMockTrack( master, "track1", "artist1", "album1" ); 0245 addMockTrack( slave, "track1", "artist1", "album1" ); 0246 addMockTrack( master, "track1", "artist1", "album2" ); 0247 0248 QCOMPARE( master->mc->trackMap().count(), 2 ); 0249 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0250 QCOMPARE( trackCopyCount, 0 ); 0251 QCOMPARE( trackRemoveCount, 0 ); 0252 0253 //test 0254 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0255 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0256 job->setMaster( master ); 0257 job->setSlave( slave ); 0258 job->synchronize(); 0259 spy.wait( 1000 ); 0260 0261 //verify 0262 QCOMPARE( trackCopyCount, 1 ); 0263 QCOMPARE( trackRemoveCount, 0 ); 0264 QCOMPARE( master->mc->trackMap().count(), 2 ); 0265 QCOMPARE( slave->mc->trackMap().count(), 2 ); 0266 0267 delete master; 0268 delete slave; 0269 } 0270 0271 void 0272 TestMasterSlaveSynchronizationJob::testAddArtist() 0273 { 0274 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0275 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0276 0277 //setup 0278 addMockTrack( master, "track1", "artist1", "album1" ); 0279 addMockTrack( slave, "track1", "artist1", "album1" ); 0280 addMockTrack( master, "track1", "artist2", "album1" ); 0281 0282 QCOMPARE( master->mc->trackMap().count(), 2 ); 0283 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0284 QCOMPARE( trackCopyCount, 0 ); 0285 QCOMPARE( trackRemoveCount, 0 ); 0286 0287 //test 0288 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0289 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0290 job->setMaster( master ); 0291 job->setSlave( slave ); 0292 job->synchronize(); 0293 spy.wait( 1000 ); 0294 0295 //verify 0296 QCOMPARE( trackCopyCount, 1 ); 0297 QCOMPARE( trackRemoveCount, 0 ); 0298 QCOMPARE( master->mc->trackMap().count(), 2 ); 0299 QCOMPARE( slave->mc->trackMap().count(), 2 ); 0300 0301 delete master; 0302 delete slave; 0303 } 0304 0305 void 0306 TestMasterSlaveSynchronizationJob::testRemoveSingleTrack() 0307 { 0308 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0309 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0310 0311 Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); 0312 EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); 0313 Amarok::Components::setCollectionLocationDelegate( delegate ); 0314 0315 //setup 0316 addMockTrack( master, "track1", "artist1", "album1" ); 0317 addMockTrack( slave, "track1", "artist1", "album1" ); 0318 addMockTrack( slave, "track2", "artist1", "album1" ); 0319 0320 QCOMPARE( master->mc->trackMap().count(), 1 ); 0321 QCOMPARE( slave->mc->trackMap().count(), 2 ); 0322 QCOMPARE( trackCopyCount, 0 ); 0323 QCOMPARE( trackRemoveCount, 0 ); 0324 0325 //test 0326 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0327 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0328 job->setMaster( master ); 0329 job->setSlave( slave ); 0330 job->synchronize(); 0331 spy.wait( 1000 ); 0332 0333 //verify 0334 QCOMPARE( trackCopyCount, 0 ); 0335 QCOMPARE( trackRemoveCount, 1 ); 0336 QCOMPARE( master->mc->trackMap().count(), 1 ); 0337 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0338 0339 delete master; 0340 delete slave; 0341 delete Amarok::Components::setCollectionLocationDelegate( nullptr ); 0342 } 0343 0344 void 0345 TestMasterSlaveSynchronizationJob::testRemoveAlbum() 0346 { 0347 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0348 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0349 0350 Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); 0351 EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); 0352 Amarok::Components::setCollectionLocationDelegate( delegate ); 0353 0354 //setup 0355 addMockTrack( master, "track1", "artist1", "album1" ); 0356 addMockTrack( slave, "track1", "artist1", "album1" ); 0357 addMockTrack( slave, "track1", "artist1", "album2" ); 0358 0359 QCOMPARE( master->mc->trackMap().count(), 1 ); 0360 QCOMPARE( slave->mc->trackMap().count(), 2 ); 0361 QCOMPARE( trackCopyCount, 0 ); 0362 QCOMPARE( trackRemoveCount, 0 ); 0363 0364 //test 0365 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0366 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0367 job->setMaster( master ); 0368 job->setSlave( slave ); 0369 job->synchronize(); 0370 spy.wait( 1000 ); 0371 0372 //verify 0373 QCOMPARE( trackCopyCount, 0 ); 0374 QCOMPARE( trackRemoveCount, 1 ); 0375 QCOMPARE( master->mc->trackMap().count(), 1 ); 0376 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0377 0378 delete master; 0379 delete slave; 0380 delete Amarok::Components::setCollectionLocationDelegate( nullptr ); 0381 } 0382 0383 void 0384 TestMasterSlaveSynchronizationJob::testRemoveArtist() 0385 { 0386 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0387 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0388 0389 Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); 0390 EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); 0391 Amarok::Components::setCollectionLocationDelegate( delegate ); 0392 0393 //setup 0394 addMockTrack( master, "track1", "artist1", "album1" ); 0395 addMockTrack( slave, "track1", "artist1", "album1" ); 0396 addMockTrack( slave, "track1", "artist2", "album1" ); 0397 0398 QCOMPARE( master->mc->trackMap().count(), 1 ); 0399 QCOMPARE( slave->mc->trackMap().count(), 2 ); 0400 QCOMPARE( trackCopyCount, 0 ); 0401 QCOMPARE( trackRemoveCount, 0 ); 0402 0403 //test 0404 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0405 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0406 job->setMaster( master ); 0407 job->setSlave( slave ); 0408 job->synchronize(); 0409 spy.wait( 1000 ); 0410 0411 //verify 0412 QCOMPARE( trackCopyCount, 0 ); 0413 QCOMPARE( trackRemoveCount, 1 ); 0414 QCOMPARE( master->mc->trackMap().count(), 1 ); 0415 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0416 0417 delete master; 0418 delete slave; 0419 delete Amarok::Components::setCollectionLocationDelegate( nullptr ); 0420 } 0421 0422 void 0423 TestMasterSlaveSynchronizationJob::testEmptyMaster() 0424 { 0425 Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); 0426 Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); 0427 0428 Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); 0429 EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); 0430 Amarok::Components::setCollectionLocationDelegate( delegate ); 0431 0432 //setup master 0433 addMockTrack( slave, "track1", "artist1", "album1" ); 0434 QCOMPARE( master->mc->trackMap().count(), 0 ); 0435 QCOMPARE( slave->mc->trackMap().count(), 1 ); 0436 QCOMPARE( trackCopyCount, 0 ); 0437 QCOMPARE( trackRemoveCount, 0 ); 0438 0439 MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); 0440 QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); 0441 job->setMaster( master ); 0442 job->setSlave( slave ); 0443 job->synchronize(); 0444 spy.wait( 1000 ); 0445 0446 QCOMPARE( trackCopyCount, 0 ); 0447 QCOMPARE( trackRemoveCount, 1 ); 0448 QCOMPARE( master->mc->trackMap().count(), 0 ); 0449 QCOMPARE( slave->mc->trackMap().count(), 0 ); 0450 delete master; 0451 delete slave; 0452 delete Amarok::Components::setCollectionLocationDelegate( nullptr ); 0453 }