Skip to content

Commit

Permalink
Adding more tests for file storage and fixing issues with scoped file…
Browse files Browse the repository at this point in the history
… storage
  • Loading branch information
ejsmith committed Nov 22, 2021
1 parent e948215 commit e13e92d
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 14 deletions.
23 changes: 20 additions & 3 deletions src/Foundatio.TestHarness/Storage/FileStorageTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ public virtual async Task CanGetFileListForSingleFolderAsync() {
}
}

public virtual async Task CanGetFileListForSingleFileAsync() {
await ResetAsync();

var storage = GetStorage();
if (storage == null)
return;

using (storage) {
await storage.SaveFileAsync(@"archived\archived.txt", "archived");
await storage.SaveFileAsync(@"archived\archived.csv", "archived");
await storage.SaveFileAsync(@"q\new.txt", "new");
await storage.SaveFileAsync(@"long/path/in/here/1.hey.stuff-2.json", "archived");

Assert.Equal(1, (await storage.GetFileListAsync(@"archived\archived.txt")).Count);
}
}

public virtual async Task CanGetPagedFileListForSingleFolderAsync() {
await ResetAsync();

Expand Down Expand Up @@ -114,7 +131,7 @@ public virtual async Task CanGetFileInfoAsync() {
var fileInfo = await storage.GetFileInfoAsync(Guid.NewGuid().ToString());
Assert.Null(fileInfo);

var startTime = SystemClock.UtcNow.Floor(TimeSpan.FromSeconds(1));
var startTime = SystemClock.UtcNow.Subtract(TimeSpan.FromMinutes(1));
string path = $"folder\\{Guid.NewGuid()}-nested.txt";
Assert.True(await storage.SaveFileAsync(path, "test"));
fileInfo = await storage.GetFileInfoAsync(path);
Expand Down Expand Up @@ -246,7 +263,7 @@ public virtual async Task CanDeleteEntireFolderAsync() {
await storage.SaveFileAsync(@"x\nested\world.csv", "nested world");
Assert.Equal(2, (await storage.GetFileListAsync()).Count);

await storage.DeleteFilesAsync(@"x");
await storage.DeleteFilesAsync(@"x\*");
Assert.Empty(await storage.GetFileListAsync());
}
}
Expand Down Expand Up @@ -341,7 +358,7 @@ public virtual async Task CanDeleteNestedFolderAsync() {
Assert.Equal(2, (await storage.GetFileListAsync(@"x\nested\*")).Count);
Assert.Equal(2, (await storage.GetFileListAsync(@"x\*.txt")).Count);

await storage.DeleteFilesAsync(@"x\nested");
await storage.DeleteFilesAsync(@"x\nested\*");

Assert.Single(await storage.GetFileListAsync());
Assert.True(await storage.ExistsAsync(@"x\hello.txt"));
Expand Down
11 changes: 4 additions & 7 deletions src/Foundatio/Storage/IFileStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,11 @@ public static Task<bool> SaveFileAsync(this IFileStorage storage, string path, s

public static async Task<IReadOnlyCollection<FileSpec>> GetFileListAsync(this IFileStorage storage, string searchPattern = null, int? limit = null, CancellationToken cancellationToken = default) {
var files = new List<FileSpec>();
var result = await storage.GetPagedFileListAsync(100, searchPattern, cancellationToken).AnyContext();
limit ??= Int32.MaxValue;
var result = await storage.GetPagedFileListAsync(Math.Min(limit.Value, 100), searchPattern, cancellationToken).AnyContext();
do {
foreach (var file in result.Files) {
files.Add(file);
if (limit.HasValue && limit.Value == files.Count)
return files;
}
} while (result.HasMore && await result.NextPageAsync().AnyContext());
files.AddRange(result.Files);
} while (result.HasMore && files.Count < limit.Value && await result.NextPageAsync().AnyContext());

return files;
}
Expand Down
9 changes: 5 additions & 4 deletions src/Foundatio/Storage/ScopedFileStorage.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Foundatio.Serializer;
Expand Down Expand Up @@ -83,14 +81,17 @@ public Task<bool> DeleteFileAsync(string path, CancellationToken cancellationTok
}

public Task<int> DeleteFilesAsync(string searchPattern = null, CancellationToken cancellation = default) {
return UnscopedStorage.DeleteFilesAsync(String.Concat(_pathPrefix, searchPattern), cancellation);
searchPattern = !String.IsNullOrEmpty(searchPattern) ? String.Concat(_pathPrefix, searchPattern) : String.Concat(_pathPrefix, "*");
return UnscopedStorage.DeleteFilesAsync(searchPattern, cancellation);
}

public async Task<PagedFileListResult> GetPagedFileListAsync(int pageSize = 100, string searchPattern = null, CancellationToken cancellationToken = default) {
if (pageSize <= 0)
return PagedFileListResult.Empty;

var unscopedResult = await UnscopedStorage.GetPagedFileListAsync(pageSize, String.Concat(_pathPrefix, searchPattern), cancellationToken).AnyContext();
searchPattern = !String.IsNullOrEmpty(searchPattern) ? String.Concat(_pathPrefix, searchPattern) : String.Concat(_pathPrefix, "*");
var unscopedResult = await UnscopedStorage.GetPagedFileListAsync(pageSize, searchPattern, cancellationToken).AnyContext();
unscopedResult = unscopedResult.DeepClone();
foreach (var file in unscopedResult.Files)
file.Path = file.Path.Substring(_pathPrefix.Length);

Expand Down
5 changes: 5 additions & 0 deletions tests/Foundatio.Tests/Storage/FolderFileStorageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public override Task CanGetFileListForSingleFolderAsync() {
public override Task CanGetPagedFileListForSingleFolderAsync() {
return base.CanGetPagedFileListForSingleFolderAsync();
}

[Fact]
public override Task CanGetFileListForSingleFileAsync() {
return base.CanGetFileListForSingleFileAsync();
}

[Fact]
public override Task CanGetFileInfoAsync() {
Expand Down
5 changes: 5 additions & 0 deletions tests/Foundatio.Tests/Storage/InMemoryFileStorageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public override Task CanGetEmptyFileListOnMissingDirectoryAsync() {
public override Task CanGetFileListForSingleFolderAsync() {
return base.CanGetFileListForSingleFolderAsync();
}

[Fact]
public override Task CanGetFileListForSingleFileAsync() {
return base.CanGetFileListForSingleFileAsync();
}

[Fact]
public override Task CanGetPagedFileListForSingleFolderAsync() {
Expand Down
5 changes: 5 additions & 0 deletions tests/Foundatio.Tests/Storage/ScopedFolderFileStorageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public override Task CanGetEmptyFileListOnMissingDirectoryAsync() {
public override Task CanGetFileListForSingleFolderAsync() {
return base.CanGetFileListForSingleFolderAsync();
}

[Fact]
public override Task CanGetFileListForSingleFileAsync() {
return base.CanGetFileListForSingleFileAsync();
}

[Fact]
public override Task CanGetPagedFileListForSingleFolderAsync() {
Expand Down
109 changes: 109 additions & 0 deletions tests/Foundatio.Tests/Storage/ScopedInMemoryFileStorageTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System.Threading.Tasks;
using Foundatio.Storage;
using Xunit;
using Xunit.Abstractions;

namespace Foundatio.Tests.Storage {
public class ScopedInMemoryFileStorageTests : FileStorageTestsBase {
public ScopedInMemoryFileStorageTests(ITestOutputHelper output) : base(output) {}

protected override IFileStorage GetStorage() {
return new ScopedFileStorage(new InMemoryFileStorage { MaxFiles = 2000 }, "scoped");
}

[Fact]
public override Task CanGetEmptyFileListOnMissingDirectoryAsync() {
return base.CanGetEmptyFileListOnMissingDirectoryAsync();
}

[Fact]
public override Task CanGetFileListForSingleFolderAsync() {
return base.CanGetFileListForSingleFolderAsync();
}

[Fact]
public override Task CanGetFileListForSingleFileAsync() {
return base.CanGetFileListForSingleFileAsync();
}

[Fact]
public override Task CanGetPagedFileListForSingleFolderAsync() {
return base.CanGetPagedFileListForSingleFolderAsync();
}

[Fact]
public override Task CanGetFileInfoAsync() {
return base.CanGetFileInfoAsync();
}

[Fact]
public override Task CanGetNonExistentFileInfoAsync() {
return base.CanGetNonExistentFileInfoAsync();
}

[Fact]
public override Task CanSaveFilesAsync() {
return base.CanSaveFilesAsync();
}

[Fact]
public override Task CanManageFilesAsync() {
return base.CanManageFilesAsync();
}

[Fact]
public override Task CanRenameFilesAsync() {
return base.CanRenameFilesAsync();
}

[Fact]
public override Task CanConcurrentlyManageFilesAsync() {
return base.CanConcurrentlyManageFilesAsync();
}

[Fact]
public override void CanUseDataDirectory() {
base.CanUseDataDirectory();
}

[Fact]
public override Task CanDeleteEntireFolderAsync() {
return base.CanDeleteEntireFolderAsync();
}

[Fact]
public override Task CanDeleteEntireFolderWithWildcardAsync() {
return base.CanDeleteEntireFolderWithWildcardAsync();
}

[Fact]
public override Task CanDeleteFolderWithMultiFolderWildcardsAsync() {
return base.CanDeleteFolderWithMultiFolderWildcardsAsync();
}

[Fact]
public override Task CanDeleteSpecificFilesAsync() {
return base.CanDeleteSpecificFilesAsync();
}

[Fact]
public override Task CanDeleteNestedFolderAsync() {
return base.CanDeleteNestedFolderAsync();
}

[Fact]
public override Task CanDeleteSpecificFilesInNestedFolderAsync() {
return base.CanDeleteSpecificFilesInNestedFolderAsync();
}

[Fact]
public override Task CanRoundTripSeekableStreamAsync() {
return base.CanRoundTripSeekableStreamAsync();
}

[Fact]
public override Task WillRespectStreamOffsetAsync() {
return base.WillRespectStreamOffsetAsync();
}
}
}

0 comments on commit e13e92d

Please sign in to comment.