Skip to content

Commit

Permalink
fixes the regression on BucketExistsAsync (#1106)
Browse files Browse the repository at this point in the history
* fixes the regression on BucketExistsAsync

* incorporates review comments

* incorporatess review comments-2

* incorporatess review comments-3

* incorporates review comments-4

---------

Co-authored-by: Ersan Bozduman <[email protected]>
  • Loading branch information
ebozduman and Ersan Bozduman committed Jun 20, 2024
1 parent 15cca31 commit 8bc1c92
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 20 deletions.
91 changes: 85 additions & 6 deletions Minio.Functional.Tests/FunctionalTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage,
* (C) 2017-2021 MinIO, Inc.
*
Expand Down Expand Up @@ -4657,16 +4657,16 @@ internal static async Task GetObject_Test1(IMinioClient minio)
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);

using (var filestream = rsg.GenerateStreamFromSeed(1 * MB))
Stream strm;
await using ((strm = rsg.GenerateStreamFromSeed(1 * MB)).ConfigureAwait(false))
{
var file_write_size = filestream.Length;
var file_write_size = strm.Length;
long file_read_size = 0;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithStreamData(strm)
.WithObjectSize(strm.Length)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);

Expand Down Expand Up @@ -4775,6 +4775,85 @@ internal static async Task GetObject_Test2(IMinioClient minio)
}
}

internal static async Task GetObjectNegObjNotFound_Test3(IMinioClient minio)
{
var stopwatch = Stopwatch.StartNew();
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
// Don't Put the object, so we can hit "ObjectNotFound" exception
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCallbackStream(_ => throw new Exception("Should never be reached at the Callback function"));
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
new MintLogger("GetObjectNegObjNotFound_Test3", getObjectSignature,
"Tests whether GetObjectAsync hits ObjectNotFoundException",
TestStatus.FAIL, stopwatch.Elapsed, "Failed to hit ObjectNotFoundxception", args: args).Log();
throw new Exception("Failed to hit ObjectNotFoundException");
}
catch (ObjectNotFoundException)
{
new MintLogger("GetObjectNegObjNotFound_Test3", getObjectSignature,
"Tests whether GetObjectAsync hits ObjectNotFoundException",
TestStatus.PASS, stopwatch.Elapsed, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("GetObjectNegObjNotFound_Test3", getObjectSignature,
"Tests whether GetObjectAsync hits ObjectNotFoundException",
TestStatus.FAIL, stopwatch.Elapsed, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}

internal static async Task GetObjectNegBcktNotFound_Test4(IMinioClient minio)
{
var stopwatch = Stopwatch.StartNew();
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } };
try
{
// No object, no bucket, so we can hit "BucketNotFoundException" with
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCallbackStream(_ => throw new Exception("Should never be reached"));
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
new MintLogger("GetObjectNegBcktNotFound_Test4", getObjectSignature,
"Tests whether GetObjectAsync hits BucketNotFoundException",
TestStatus.FAIL, stopwatch.Elapsed, "Failed to hit BucketNotFoundException", args: args).Log();
throw new Exception("Failed to hit BucketNotFoundException");
}
catch (BucketNotFoundException)
{
new MintLogger("GetObjectNegBcktNotFound_Test4", getObjectSignature,
"Tests whether GetObjectAsync hits BucketNotFoundException",
TestStatus.PASS, stopwatch.Elapsed, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("GetObjectNegBcktNotFound_Test4", getObjectSignature,
"Tests whether GetObjectAsync hits BucketNotFoundException",
TestStatus.FAIL, stopwatch.Elapsed, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}

internal static async Task GetObject_3_OffsetLength_Tests(IMinioClient minio)
// 3 tests will run to check different values of offset and length parameters
// when GetObject api returns part of the object as defined by the offset
Expand Down
2 changes: 2 additions & 0 deletions Minio.Functional.Tests/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ public static async Task Main(string[] args)
// Test GetObjectAsync function
functionalTestTasks.Add(FunctionalTest.GetObject_Test1(minioClient));
functionalTestTasks.Add(FunctionalTest.GetObject_Test2(minioClient));
functionalTestTasks.Add(FunctionalTest.GetObjectNegObjNotFound_Test3(minioClient));
functionalTestTasks.Add(FunctionalTest.GetObjectNegBcktNotFound_Test4(minioClient));
// 3 tests will run to check different values of offset and length parameters
// when GetObject api returns part of the object as defined by the offset
// and length parameters. Tests will be reported as GetObject_Test3,
Expand Down
5 changes: 2 additions & 3 deletions Minio/ApiEndpoints/BucketOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,9 @@ public async Task<bool> BucketExistsAsync(BucketExistsArgs args, CancellationTok
HttpStatusCode.NotFound != ice.ServerResponse.StatusCode) &&
ice.ServerResponse is not null;
}
catch (Exception ex)
catch (BucketNotFoundException)
{
if (ex.GetType() == typeof(BucketNotFoundException)) return false;
throw;
return false;
}
}

Expand Down
30 changes: 19 additions & 11 deletions Minio/RequestExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Web;
using Minio.Credentials;
using Minio.DataModel;
using Minio.DataModel.Args;
Expand Down Expand Up @@ -80,7 +81,6 @@ public static Task WrapperPutAsync(this IMinioClient minioClient, string url, St
CancellationToken cancellationToken = default)
{
var startTime = DateTime.Now;

var v4Authenticator = new V4Authenticator(minioClient.Config.Secure,
minioClient.Config.AccessKey, minioClient.Config.SecretKey, minioClient.Config.Region,
minioClient.Config.SessionToken);
Expand All @@ -101,19 +101,29 @@ public static Task WrapperPutAsync(this IMinioClient minioClient, string url, St
await requestMessageBuilder.ResponseWriter(responseResult.ContentStream, cancellationToken)
.ConfigureAwait(false);

var path = request.RequestUri.LocalPath.TrimStart('/').TrimEnd('/').Split('/');
var path = request.RequestUri.LocalPath.TrimStart('/').TrimEnd('/')
.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (responseResult.Response.StatusCode == HttpStatusCode.NotFound)
{
if (request.Method == HttpMethod.Get)
{
var q = HttpUtility.ParseQueryString(request.RequestUri.Query);
if (q.Get("object-lock") != null)
{
responseResult.Exception = new MissingObjectLockConfigurationException();
return responseResult;
}
}

if (request.Method == HttpMethod.Head)
{
if (responseResult.Exception?.GetType().Equals(typeof(BucketNotFoundException)) == true ||
path.Length == 1)
if (responseResult.Exception is BucketNotFoundException || path.Length == 1)
responseResult.Exception = new BucketNotFoundException();

if (path.Length > 1)
{
var found = await minioClient
.BucketExistsAsync(new BucketExistsArgs().WithBucket(path.ToList()[0]), cancellationToken)
.BucketExistsAsync(new BucketExistsArgs().WithBucket(path[0]), cancellationToken)
.ConfigureAwait(false);
responseResult.Exception = !found
? new Exception("ThrowBucketNotFoundException")
Expand All @@ -122,10 +132,11 @@ await requestMessageBuilder.ResponseWriter(responseResult.ContentStream, cancell
}
}

if (request.RequestUri.ToString().Contains("lock", StringComparison.OrdinalIgnoreCase) &&
request.Method == HttpMethod.Get)
responseResult.Exception = new MissingObjectLockConfigurationException();
return responseResult;
}

minioClient.HandleIfErrorResponse(responseResult, errorHandlers, startTime);
return responseResult;
}
catch (Exception ex) when (ex is not (OperationCanceledException or
ObjectNotFoundException))
Expand All @@ -139,9 +150,6 @@ await requestMessageBuilder.ResponseWriter(responseResult.ContentStream, cancell
responseResult = new ResponseResult(request, ex);
return responseResult;
}

minioClient.HandleIfErrorResponse(responseResult, errorHandlers, startTime);
return responseResult;
}

private static Task<ResponseResult> ExecuteWithRetry(this IMinioClient minioClient,
Expand Down

0 comments on commit 8bc1c92

Please sign in to comment.