From fdcba83c60e2306f8dddd600f1ff088042bd7285 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 5 Sep 2024 13:51:09 +0800 Subject: [PATCH] add unit tests --- .../BlobStoring/Google/GoogleBlobProvider.cs | 62 ++++++++++++----- .../Google/AbpBlobStoringGoogleTestModule.cs | 66 ++++++++++++++----- .../Google/GoogleBlobContainer_Tests.cs | 13 ++++ .../Google/GoogleBlobNameCalculator_Tests.cs | 56 ++++++++++++++++ 4 files changed, 162 insertions(+), 35 deletions(-) create mode 100644 framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobContainer_Tests.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobNameCalculator_Tests.cs diff --git a/framework/src/Volo.Abp.BlobStoring.Google/Volo/Abp/BlobStoring/Google/GoogleBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Google/Volo/Abp/BlobStoring/Google/GoogleBlobProvider.cs index 006923996f..dc5eefc1ee 100644 --- a/framework/src/Volo.Abp.BlobStoring.Google/Volo/Abp/BlobStoring/Google/GoogleBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring.Google/Volo/Abp/BlobStoring/Google/GoogleBlobProvider.cs @@ -31,17 +31,13 @@ public class GoogleBlobProvider : BlobProviderBase, ITransientDependency { throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{GetContainerName(args)}'! Set {nameof(args.OverrideExisting)} if it should be overwritten."); } - + if (configuration.CreateContainerIfNotExists) { await CreateContainerIfNotExists(args); } - await storageClient.UploadObjectAsync(containerName, blobName, contentType: "application/octet-stream", args.BlobStream, - new UploadObjectOptions - { - IfGenerationMatch = !args.OverrideExisting ? 0 : 1 - }); + await storageClient.UploadObjectAsync(containerName, blobName, contentType: "application/octet-stream", args.BlobStream); } public async override Task DeleteAsync(BlobProviderDeleteArgs args) @@ -49,8 +45,16 @@ public class GoogleBlobProvider : BlobProviderBase, ITransientDependency var storageClient = await GetStorageClientClientAsync(args); var blobName = GoogleBlobNameCalculator.Calculate(args); var containerName = GetContainerName(args); - - await storageClient.DeleteObjectAsync(containerName, blobName); + + try + { + await storageClient.DeleteObjectAsync(containerName, blobName); + } + catch (GoogleApiException e) when (e.HttpStatusCode == HttpStatusCode.NotFound) + { + return true; + } + return true; } @@ -66,13 +70,12 @@ public class GoogleBlobProvider : BlobProviderBase, ITransientDependency var storageClient = await GetStorageClientClientAsync(args); var blobName = GoogleBlobNameCalculator.Calculate(args); var containerName = GetContainerName(args); - - var @object = await storageClient.GetObjectAsync(containerName, blobName); - if (@object == null) + + if(!await BlobExistsAsync(args, blobName)) { return null; } - + var stream = new MemoryStream(); await storageClient.DownloadObjectAsync(containerName, blobName, stream); @@ -92,23 +95,48 @@ public class GoogleBlobProvider : BlobProviderBase, ITransientDependency protected virtual async Task BlobExistsAsync(BlobProviderArgs args, string blobName) { - var @object = await (await GetStorageClientClientAsync(args)).GetObjectAsync(args.ContainerName, blobName); - - return @object != null; + var storageClient = await GetStorageClientClientAsync(args); + if(!await ContainerExistsAsync(args, storageClient)) + { + return false; + } + + try + { + await storageClient.GetObjectAsync(GetContainerName(args), blobName); + } + catch (GoogleApiException e) when (e.HttpStatusCode == HttpStatusCode.NotFound) + { + return false; + } + + return true; } protected virtual async Task CreateContainerIfNotExists(BlobProviderArgs args) { var storageClient = await GetStorageClientClientAsync(args); var configuration = args.Configuration.GetGoogleConfiguration(); + if(await ContainerExistsAsync(args, storageClient)) + { + return; + } + + await storageClient.CreateBucketAsync(configuration.ProjectId, GetContainerName(args)); + } + + protected virtual async Task ContainerExistsAsync(BlobProviderArgs args, StorageClient client) + { try { - await storageClient.GetBucketAsync(args.ContainerName); + await client.GetBucketAsync(GetContainerName(args)); } catch (GoogleApiException e) when (e.HttpStatusCode == HttpStatusCode.NotFound) { - await storageClient.CreateBucketAsync(configuration.ProjectId, GetContainerName(args)); + return false; } + + return true; } protected virtual async Task GetStorageClientClientAsync(BlobProviderArgs args) diff --git a/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/AbpBlobStoringGoogleTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/AbpBlobStoringGoogleTestModule.cs index 35345613ac..cca775a04f 100644 --- a/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/AbpBlobStoringGoogleTestModule.cs +++ b/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/AbpBlobStoringGoogleTestModule.cs @@ -1,4 +1,7 @@ using System; +using System.Threading.Tasks; +using Google.Apis.Auth.OAuth2; +using Google.Cloud.Storage.V1; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; @@ -25,9 +28,11 @@ public class AbpBlobStoringGoogleTestModule : AbpModule { private const string UserSecretsId = "9f0d2c00-80c1-435b-bfab-2c39c8249091"; - private string _connectionString; + private string _clientEmail; + private string _projectId; + private string _privateKey; - private readonly string _randomContainerName = "abp-azure-test-container-" + Guid.NewGuid().ToString("N"); + private readonly string _randomContainerName = "abp-test-container-" + Guid.NewGuid().ToString("N"); public override void ConfigureServices(ServiceConfigurationContext context) { @@ -36,25 +41,50 @@ public class AbpBlobStoringGoogleTestModule : AbpModule builder.AddUserSecrets(UserSecretsId); })); - // var configuration = context.Services.GetConfiguration(); - // _connectionString = configuration["Azure:ConnectionString"]; - // - // Configure(options => - // { - // options.Containers.ConfigureAll((containerName, containerConfiguration) => - // { - // containerConfiguration.UseAzure(azure => - // { - // azure.ConnectionString = _connectionString; - // azure.ContainerName = _randomContainerName; - // azure.CreateContainerIfNotExists = true; - // }); - // }); - // }); + var configuration = context.Services.GetConfiguration(); + _clientEmail = configuration["Google:ClientEmail"]; + _projectId = configuration["Google:ProjectId"]; + _privateKey = configuration["Google:PrivateKey"]; + + Configure(options => + { + options.Containers.ConfigureAll((containerName, containerConfiguration) => + { + containerConfiguration.UseGoogle(google => + { + google.ClientEmail = _clientEmail; + google.ProjectId = _projectId = "wide-origin-296910"; + google.PrivateKey = _privateKey; + google.ContainerName = _randomContainerName; + google.CreateContainerIfNotExists = true; + }); + }); + }); } public override void OnApplicationShutdown(ApplicationShutdownContext context) { - + var googleCredential = GoogleCredential.FromServiceAccountCredential( + new ServiceAccountCredential( + new ServiceAccountCredential.Initializer(_clientEmail) + { + ProjectId = _projectId + } + .FromPrivateKey(_privateKey) + )); + + var client = StorageClient.Create(googleCredential); + + try + { + client.DeleteBucket(_randomContainerName, new DeleteBucketOptions + { + DeleteObjects = true + }); + } + catch (Exception e) + { + // ignored + } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobContainer_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobContainer_Tests.cs new file mode 100644 index 0000000000..6a4405f7cd --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobContainer_Tests.cs @@ -0,0 +1,13 @@ +using Xunit; + +namespace Volo.Abp.BlobStoring.Google; + +/* +//Please set the correct connection string in secrets.json and continue the test. +public class GoogleBlobContainer_Tests : BlobContainer_Tests +{ + public GoogleBlobContainer_Tests() + { + } +} +*/ diff --git a/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobNameCalculator_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobNameCalculator_Tests.cs new file mode 100644 index 0000000000..dbdc95c6f4 --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Google.Tests/Volo/Abp/BlobStoring/Google/GoogleBlobNameCalculator_Tests.cs @@ -0,0 +1,56 @@ +using System; +using Shouldly; +using Volo.Abp.MultiTenancy; +using Xunit; + +namespace Volo.Abp.BlobStoring.Google; + +public class GoogleBlobNameCalculator_Tests : AbpBlobStoringGoogleTestCommonBase +{ + private readonly IGoogleBlobNameCalculator _calculator; + private readonly ICurrentTenant _currentTenant; + + private const string AzureContainerName = "/"; + private const string AzureSeparator = "/"; + + public GoogleBlobNameCalculator_Tests() + { + _calculator = GetRequiredService(); + _currentTenant = GetRequiredService(); + } + + [Fact] + public void Default_Settings() + { + _calculator.Calculate( + GetArgs("my-container", "my-blob") + ).ShouldBe($"host{AzureSeparator}my-blob"); + } + + [Fact] + public void Default_Settings_With_TenantId() + { + var tenantId = Guid.NewGuid(); + + using (_currentTenant.Change(tenantId)) + { + _calculator.Calculate( + GetArgs("my-container", "my-blob") + ).ShouldBe($"tenants{AzureSeparator}{tenantId:D}{AzureSeparator}my-blob"); + } + } + + private static BlobProviderArgs GetArgs( + string containerName, + string blobName) + { + return new BlobProviderGetArgs( + containerName, + new BlobContainerConfiguration().UseGoogle(x => + { + x.ContainerName = containerName; + }), + blobName + ); + } +} \ No newline at end of file