Skip to content

Commit

Permalink
fixes BucketExists' return value and StatObject's returned exceptions (
Browse files Browse the repository at this point in the history
…#987)

* fixes error messages for BucketExists and StatObject

* lint changes

* adds required format changes

* for debugging workfloww only build failure

* possible fix for build failure

* another try for the timing issue

* debug trial for the build timing issue

* yet another try for the timing issue

* more lint changes

---------

Co-authored-by: Ersan Bozduman <[email protected]>
  • Loading branch information
ebozduman and Ersan Bozduman authored Jan 24, 2024
1 parent a447942 commit 9772a37
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 108 deletions.
69 changes: 43 additions & 26 deletions Minio.Functional.Tests/FunctionalTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,11 @@ internal static async Task BucketExists_Test(IMinioClient minio)

try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsFalse(found);
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
new MintLogger(nameof(BucketExists_Test), bucketExistsSignature, "Tests whether BucketExists passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
Expand Down Expand Up @@ -1007,7 +1010,7 @@ internal static async Task<ObjectStat> PutObject_Tester(IMinioClient minio,
filestream = bs.AsStream();
}

using (filestream)
await using (filestream.ConfigureAwait(false))
{
var file_write_size = filestream.Length;
var tempFileName = "tempfile-" + GetRandomName();
Expand All @@ -1020,7 +1023,7 @@ internal static async Task<ObjectStat> PutObject_Tester(IMinioClient minio,
.WithProgress(progress)
.WithContentType(contentType)
.WithHeaders(metaData);
await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var statPutObj = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);

var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
Expand All @@ -1036,11 +1039,6 @@ internal static async Task<ObjectStat> PutObject_Tester(IMinioClient minio,
Assert.IsNotNull(statObject.ContentType);
Assert.IsTrue(statObject.ContentType.Equals(contentType, StringComparison.OrdinalIgnoreCase));
}

var rmArgs = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectAsync(rmArgs).ConfigureAwait(false);
}

return statObject;
Expand Down Expand Up @@ -3504,8 +3502,11 @@ internal static async Task PutObject_Test9(IMinioClient minio)
totalBytesTransferred = progressReport.TotalBytesTransferred;
// Console.WriteLine(
// $"PutObject_Test9 - Percentage: {progressReport.Percentage}% TotalBytesTransferred: {progressReport.TotalBytesTransferred} bytes");
// if (progressReport.Percentage != 100)
// Console.SetCursorPosition(0, Console.CursorTop - 1);
if (progressReport.Percentage != 100)
{
var topPosition = Console.CursorTop > 0 ? Console.CursorTop - 1 : Console.CursorTop;
Console.SetCursorPosition(0, topPosition);
}
// else Console.WriteLine();
});
var args = new Dictionary<string, string>
Expand All @@ -3519,8 +3520,10 @@ internal static async Task PutObject_Test9(IMinioClient minio)
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
rsg.GenerateStreamFromSeed(objSize), progress).ConfigureAwait(false);

var stream = rsg.GenerateStreamFromSeed(objSize);
var statObj = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
stream, progress).ConfigureAwait(false);
Assert.IsTrue(percentage == 100);
Assert.IsTrue(totalBytesTransferred == objSize);
new MintLogger(nameof(PutObject_Test9), putObjectSignature,
Expand Down Expand Up @@ -3556,8 +3559,11 @@ internal static async Task PutObject_Test10(IMinioClient minio)
totalBytesTransferred = progressReport.TotalBytesTransferred;
// Console.WriteLine(
// $"PutObject_Test10 - Percentage: {progressReport.Percentage}% TotalBytesTransferred: {progressReport.TotalBytesTransferred} bytes");
// if (progressReport.Percentage != 100)
// Console.SetCursorPosition(0, Console.CursorTop - 1);
if (progressReport.Percentage != 100)
{
var topPosition = Console.CursorTop > 0 ? Console.CursorTop - 1 : Console.CursorTop;
Console.SetCursorPosition(0, topPosition);
}
// else Console.WriteLine();
});
var args = new Dictionary<string, string>
Expand Down Expand Up @@ -3673,6 +3679,9 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var objectSize = 1 * KB;
var objectSizeStr = objectSize.ToString(CultureInfo.InvariantCulture)
.Replace(" * ", "", StringComparison.Ordinal);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var args = new Dictionary<string, string>
Expand All @@ -3682,30 +3691,30 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
{ "data", objectSizeStr },
{ "size", objectSizeStr }
};
try
{
// Test CopyConditions where matching ETag is not found
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);

using var filestream = rsg.GenerateStreamFromSeed(1 * KB);
using var filestream = rsg.GenerateStreamFromSeed(objectSize);
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithHeaders(null);
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
new MintLogger("CopyObject_Test2", copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch (initial part) passes", TestStatus.FAIL,
DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
Expand All @@ -3724,6 +3733,10 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
.WithObject(destObjectName);

await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);

new MintLogger("CopyObject_Test2", copyObjectSignature,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (MinioException ex)
{
Expand All @@ -3732,21 +3745,23 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
StringComparison.OrdinalIgnoreCase))
{
new MintLogger(nameof(CopyObject_Test2), copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.PASS, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.PASS,
DateTime.Now - startTime,
args: args).Log();
}
else
{
new MintLogger(nameof(CopyObject_Test2), copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.FAIL,
DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
}
catch (Exception ex)
{
new MintLogger(nameof(CopyObject_Test2), copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
Expand Down Expand Up @@ -4074,6 +4089,7 @@ internal static async Task CopyObject_Test7(IMinioClient minio)
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var objectSize = 1 * KB;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
Expand All @@ -4089,13 +4105,14 @@ internal static async Task CopyObject_Test7(IMinioClient minio)
// Test CopyConditions where matching ETag is found
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
Stream stream = null;
await using ((stream = rsg.GenerateStreamFromSeed(objectSize)).ConfigureAwait(false))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
.WithStreamData(stream)
.WithObjectSize(stream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}

Expand Down
6 changes: 3 additions & 3 deletions Minio.Functional.Tests/Minio.Functional.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<ProjectReference Include="..\Minio\Minio.csproj" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) ">
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) ">
<Reference Include="System.Web" />
</ItemGroup>

</Project>
15 changes: 6 additions & 9 deletions Minio/ApiEndpoints/BucketOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,21 @@ public async Task<bool> BucketExistsAsync(BucketExistsArgs args, CancellationTok
using var response =
await this.ExecuteTaskAsync(ResponseErrorHandlers, requestMessageBuilder,
cancellationToken: cancellationToken).ConfigureAwait(false);
if (response.Exception is not null &&
response.Exception.GetType() == typeof(BucketNotFoundException))
return false;
return response is not null &&
(response.Exception is null ||
response.Exception.GetType() != typeof(BucketNotFoundException));
}
catch (InternalClientException ice)
{
if ((ice.ServerResponse is not null &&
HttpStatusCode.NotFound.Equals(ice.ServerResponse.StatusCode)) ||
ice.ServerResponse is null)
return false;
return (ice.ServerResponse is null ||
!HttpStatusCode.NotFound.Equals(ice.ServerResponse.StatusCode)) &&
ice.ServerResponse is not null;
}
catch (Exception ex)
{
if (ex.GetType() == typeof(BucketNotFoundException)) return false;
throw;
}

return true;
}

/// <summary>
Expand Down
14 changes: 6 additions & 8 deletions Minio/ApiEndpoints/ObjectOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -698,14 +698,12 @@ public async Task CopyObjectAsync(CopyObjectArgs args, CancellationToken cancell
(srcByteRangeSize > 0 &&
args.SourceObject.CopyOperationConditions.byteRangeEnd >=
args.SourceObjectInfo.Size))
throw new InvalidDataException(
$"Specified byte range ({
args.SourceObject.CopyOperationConditions
.byteRangeStart.ToString(CultureInfo.InvariantCulture)}-{
args.SourceObject.CopyOperationConditions.byteRangeEnd
.ToString(CultureInfo.InvariantCulture)
}) does not fit within source object (size={
args.SourceObjectInfo.Size.ToString(CultureInfo.InvariantCulture)})");
throw new InvalidDataException($"Specified byte range ({args.SourceObject
.CopyOperationConditions
.byteRangeStart.ToString(CultureInfo.InvariantCulture)}-{args.SourceObject
.CopyOperationConditions.byteRangeEnd.ToString(CultureInfo.InvariantCulture)
}) does not fit within source object (size={args.SourceObjectInfo.Size
.ToString(CultureInfo.InvariantCulture)})");

if (copySize > Constants.MaxSingleCopyObjectSize ||
(srcByteRangeSize > 0 &&
Expand Down
2 changes: 1 addition & 1 deletion Minio/DataModel/Args/PutObjectArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public override PutObjectArgs WithHeaders(IDictionary<string, string> headers)
}

if (string.IsNullOrWhiteSpace(ContentType)) ContentType = "application/octet-stream";
if (!Headers.ContainsKey("Content-Type")) Headers["Content-Type"] = ContentType;
Headers["Content-Type"] = ContentType;
return this;
}

Expand Down
7 changes: 2 additions & 5 deletions Minio/DataModel/Response/CopyObjectResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/

using System.Net;
using System.Text;
using CommunityToolkit.HighPerformance;
using Minio.DataModel.Result;
using Minio.Helper;

Expand All @@ -27,11 +25,10 @@ internal class CopyObjectResponse : GenericResponse
public CopyObjectResponse(HttpStatusCode statusCode, string responseContent, Type reqType)
: base(statusCode, responseContent)
{
using var stream = Encoding.UTF8.GetBytes(responseContent).AsMemory().AsStream();
if (reqType == typeof(CopyObjectResult))
CopyObjectRequestResult = Utils.DeserializeXml<CopyObjectResult>(stream);
CopyObjectRequestResult = Utils.DeserializeXml<CopyObjectResult>(responseContent);
else
CopyPartRequestResult = Utils.DeserializeXml<CopyPartResult>(stream);
CopyPartRequestResult = Utils.DeserializeXml<CopyPartResult>(responseContent);
}

internal CopyObjectResult CopyObjectRequestResult { get; set; }
Expand Down
9 changes: 3 additions & 6 deletions Minio/Exceptions/MinioException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ private static string GetMessage(string message, ResponseResult serverResponse)

var contentString = serverResponse.Content;

if (message is null)
return
$"MinIO API responded with status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}";

return
$"MinIO API responded with message={message}. Status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}";
return message is null
? $"MinIO API responded with status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}"
: $"MinIO API responded with message={message}. Status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}";
}
}
27 changes: 27 additions & 0 deletions Minio/Exceptions/PreconditionFailedException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Minio.DataModel.Result;

namespace Minio.Exceptions;

[Serializable]
public class PreconditionFailedException : MinioException
{
public PreconditionFailedException()
{
}

public PreconditionFailedException(string message, Exception innerException) : base(message, innerException)
{
}

public PreconditionFailedException(ResponseResult serverResponse) : base(serverResponse)
{
}

public PreconditionFailedException(string message) : base(message)
{
}

public PreconditionFailedException(string message, ResponseResult serverResponse) : base(message, serverResponse)
{
}
}
32 changes: 28 additions & 4 deletions Minio/Helper/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,10 @@ public static void Print(object obj)
.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
var value = prop.GetValue(obj, Array.Empty<object>());
Console.WriteLine("DEBUG >> {0} = {1}", prop.Name, value);
if (string.Equals(prop.Name, "Headers", StringComparison.Ordinal))
PrintDict((Dictionary<string, string>)value);
else
Console.WriteLine("DEBUG >> {0} = {1}", prop.Name, value);
}

Console.WriteLine("DEBUG >> Print is DONE!\n\n");
Expand All @@ -1006,9 +1009,9 @@ public static void PrintDict(IDictionary<string, string> d)
{
if (d is not null)
foreach (var kv in d)
Console.WriteLine("DEBUG >> {0} = {1}", kv.Key, kv.Value);
Console.WriteLine("DEBUG >> Dictionary({0} => {1})", kv.Key, kv.Value);

Console.WriteLine("DEBUG >> Done printing\n");
Console.WriteLine("DEBUG >> Dictionary: Done printing\n");
}

public static string DetermineNamespace(XDocument document)
Expand Down Expand Up @@ -1062,10 +1065,23 @@ public static string SerializeToXml<T>(T anyobject) where T : class
XmlResolver = null
};

var xRoot = (XmlRootAttribute)typeof(T).GetCustomAttributes(typeof(XmlRootAttribute), true).FirstOrDefault();

var serializer = new XmlSerializer(typeof(T), xRoot);

using var stringReader = new StringReader(xml);
using var xmlReader = XmlReader.Create(stringReader, settings);
if (xml.Contains("<Error><Code>", StringComparison.Ordinal))
{
// Skip the first line
xml = xml[(xml.IndexOf('\n', StringComparison.Ordinal) + 1)..];
stringReader.Dispose();
using var stringReader1 = new StringReader(xml);
xRoot = new XmlRootAttribute { ElementName = "Error", IsNullable = true };
serializer = new XmlSerializer(typeof(T), xRoot);
return (T)serializer.Deserialize(new NamespaceIgnorantXmlTextReader(stringReader1));
}

var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(xmlReader);
}

Expand All @@ -1076,4 +1092,12 @@ private static string GetNamespace<T>()
? xmlRootAttribute.Namespace
: null;
}

// Class to ignore namespaces when de-serializing
public class NamespaceIgnorantXmlTextReader : XmlTextReader
{
public NamespaceIgnorantXmlTextReader(TextReader reader) : base(reader) { }

public override string NamespaceURI => string.Empty;
}
}
Loading

0 comments on commit 9772a37

Please sign in to comment.