public void SetsArtworkKey() { string key = BlobCacheKeys.GetKeyForArtwork(new byte[] { 0, 1 }); var song = new LocalSong("C://Bla", TimeSpan.Zero, key); Assert.Equal(key, song.ArtworkKey); }
public async Task StoresArtworkInBlobCache() { var blobCache = new InMemoryBlobCache(); var artworkCache = new ArtworkCache(blobCache); var data = new byte[] { 0, 1 }; string key = BlobCacheKeys.GetKeyForArtwork(data); await artworkCache.Store(key, data); Assert.Equal(data, await blobCache.Get(key)); }
public async Task DoesntStoreArtworkIfAlreadyInLocalCache() { var blobCache = Substitute.For <IBlobCache>(); var artworkCache = new ArtworkCache(blobCache); var data = new byte[] { 0, 1 }; string key = BlobCacheKeys.GetKeyForArtwork(data); await artworkCache.Store(key, data); blobCache.GetCreatedAt(Arg.Any <string>()).Returns(Observable.Return(new DateTimeOffset?(DateTimeOffset.MaxValue))); await artworkCache.Store(key, data); blobCache.Received(1).Insert(Arg.Any <string>(), Arg.Any <byte[]>()); }
public void CanStoreMulipleArtworksIfArtworksExistsInCache() { var blobCache = new InMemoryBlobCache(); var data = new byte[] { 0, 1 }; string key = BlobCacheKeys.GetKeyForArtwork(data); blobCache.Insert(key, data); var fixture = new ArtworkCache(blobCache); Task firstTask = fixture.Store(key, data); Task secondTask = fixture.Store(key, data); Task thrirdTask = fixture.Store(key, data); Assert.True(firstTask.IsCompleted); Assert.True(secondTask.IsCompleted); Assert.True(thrirdTask.IsCompleted); }
public void SameKeysWaitOnFirstToFinish() { var signal = new AsyncSubject <Unit>(); var blobCache = Substitute.For <IBlobCache>(); blobCache.Insert(Arg.Any <string>(), Arg.Any <byte[]>(), Arg.Any <DateTimeOffset?>()).Returns(signal); var fixture = new ArtworkCache(blobCache); var data = new byte[] { 0, 1 }; string key = BlobCacheKeys.GetKeyForArtwork(data); Task firstTask = fixture.Store(key, data); Task secondTask = fixture.Store(key, data); Assert.False(firstTask.IsCompleted); Assert.False(secondTask.IsCompleted); signal.OnNext(Unit.Default); signal.OnCompleted(); Assert.True(firstTask.IsCompleted); Assert.True(secondTask.IsCompleted); }
private async Task UpdateSongsAsync(string path) { if (this.currentSongFinderSubscription != null) { this.currentSongFinderSubscription.Dispose(); this.currentSongFinderSubscription = null; } this.IsUpdating = true; await this.RemoveMissingSongsAsync(path); ILocalSongFinder songFinder = this.localSongFinderFunc(path); this.currentSongFinderSubscription = songFinder.GetSongsAsync() .ObserveOn(RxApp.TaskpoolScheduler) .Subscribe(t => { LocalSong song = t.Item1; this.songLock.EnterWriteLock(); bool added = this.songs.Add(song); LocalSong realSong; bool needsUpdate = false; if (added) { realSong = song; needsUpdate = true; } else { LocalSong existing = this.songs.First(x => x.OriginalPath == song.OriginalPath); if (existing.UpdateMetadataFrom(song)) { needsUpdate = true; } realSong = existing; } this.songLock.ExitWriteLock(); byte[] artworkData = t.Item2; if (artworkData != null) { string key = BlobCacheKeys.GetKeyForArtwork(artworkData); if (realSong.ArtworkKey != key) { ArtworkCache.Instance.Store(key, artworkData).ToObservable() .Subscribe(x => realSong.ArtworkKey = key); } } if (needsUpdate) { this.songsUpdated.OnNext(Unit.Default); } }, () => { this.Save(); this.StartOnlineArtworkLookup(); this.songLock.EnterReadLock(); int songCount = this.songs.Count; this.songLock.ExitReadLock(); AnalyticsClient.Instance.RecordLibrarySize(songCount); this.IsUpdating = false; }); }