You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6288 lines
270 KiB

/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage,
* (C) 2017-2021 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using CommunityToolkit.HighPerformance;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Minio.DataModel;
using Minio.DataModel.Args;
using Minio.DataModel.Encryption;
using Minio.DataModel.ILM;
using Minio.DataModel.Notification;
using Minio.DataModel.ObjectLock;
using Minio.DataModel.Select;
using Minio.DataModel.Tags;
using Minio.Exceptions;
using Minio.Helper;
namespace Minio.Functional.Tests;
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Keep private const lowercase")]
public static class FunctionalTest
{
private const int KB = 1024;
private const int MB = 1024 * 1024;
private const int GB = 1024 * 1024 * 1024;
private const string dataFile1B = "datafile-1-b";
private const string dataFile10KB = "datafile-10-kB";
private const string dataFile6MB = "datafile-6-MB";
private const string makeBucketSignature =
"Task MakeBucketAsync(string bucketName, string location = 'us-east-1', CancellationToken cancellationToken = default(CancellationToken))";
private const string listBucketsSignature =
"Task<ListAllMyBucketsResult> ListBucketsAsync(CancellationToken cancellationToken = default(CancellationToken))";
private const string bucketExistsSignature =
"Task<bool> BucketExistsAsync(string bucketName, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeBucketSignature =
"Task RemoveBucketAsync(string bucketName, CancellationToken cancellationToken = default(CancellationToken))";
private const string listObjectsSignature =
"IObservable<Item> ListObjectsAsync(string bucketName, string prefix = null, bool recursive = false, CancellationToken cancellationToken = default(CancellationToken))";
private const string putObjectSignature =
"Task PutObjectAsync(PutObjectArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getObjectSignature =
"Task GetObjectAsync(GetObjectArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string listIncompleteUploadsSignature =
"IObservable<Upload> ListIncompleteUploads(ListIncompleteUploads args, CancellationToken cancellationToken = default(CancellationToken))";
private const string listenBucketNotificationsSignature =
"IObservable<MinioNotificationRaw> ListenBucketNotificationsAsync(ListenBucketNotificationsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string copyObjectSignature =
"Task<CopyObjectResult> CopyObjectAsync(CopyObjectArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string statObjectSignature =
"Task<ObjectStat> StatObjectAsync(StatObjectArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeObjectSignature1 =
"Task RemoveObjectAsync(RemoveObjectArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeObjectSignature2 =
"Task<IObservable<DeleteError>> RemoveObjectsAsync(RemoveObjectsArgs, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeIncompleteUploadSignature =
"Task RemoveIncompleteUploadAsync(RemoveIncompleteUploadArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string presignedPutObjectSignature =
"Task<string> PresignedPutObjectAsync(PresignedPutObjectArgs args)";
private const string presignedGetObjectSignature =
"Task<string> PresignedGetObjectAsync(PresignedGetObjectArgs args)";
private const string presignedPostPolicySignature =
"Task<Dictionary<string, string>> PresignedPostPolicyAsync(PresignedPostPolicyArgs args)";
private const string getBucketPolicySignature =
"Task<string> GetPolicyAsync(GetPolicyArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setBucketPolicySignature =
"Task SetPolicyAsync(SetPolicyArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getBucketNotificationSignature =
"Task<BucketNotification> GetBucketNotificationAsync(GetBucketNotificationsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setBucketNotificationSignature =
"Task SetBucketNotificationAsync(SetBucketNotificationsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeAllBucketsNotificationSignature =
"Task RemoveAllBucketNotificationsAsync(RemoveAllBucketNotifications args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setBucketEncryptionSignature =
"Task SetBucketEncryptionAsync(SetBucketEncryptionArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getBucketEncryptionSignature =
"Task<ServerSideEncryptionConfiguration> GetBucketEncryptionAsync(GetBucketEncryptionArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeBucketEncryptionSignature =
"Task RemoveBucketEncryptionAsync(RemoveBucketEncryptionArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string selectObjectSignature =
"Task<SelectResponseStream> SelectObjectContentAsync(SelectObjectContentArgs args,CancellationToken cancellationToken = default(CancellationToken))";
private const string setObjectLegalHoldSignature =
"Task SetObjectLegalHoldAsync(SetObjectLegalHoldArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getObjectLegalHoldSignature =
"Task<bool> GetObjectLegalHoldAsync(GetObjectLegalHoldArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setObjectLockConfigurationSignature =
"Task SetObjectLockConfigurationAsync(SetObjectLockConfigurationArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getObjectLockConfigurationSignature =
"Task<ObjectLockConfiguration> GetObjectLockConfigurationAsync(GetObjectLockConfigurationArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string deleteObjectLockConfigurationSignature =
"Task RemoveObjectLockConfigurationAsync(GetObjectLockConfigurationArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getBucketTagsSignature =
"Task<Tagging> GetBucketTagsAsync(GetBucketTagsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setBucketTagsSignature =
"Task SetBucketTagsAsync(SetBucketTagsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string deleteBucketTagsSignature =
"Task RemoveBucketTagsAsync(RemoveBucketTagsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setVersioningSignature =
"Task SetVersioningAsync(SetVersioningArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getVersioningSignature =
"Task<VersioningConfiguration> GetVersioningAsync(GetVersioningArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeVersioningSignature =
"Task RemoveBucketTagsAsync(RemoveBucketTagsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getObjectTagsSignature =
"Task<Tagging> GetObjectTagsAsync(GetObjectTagsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setObjectTagsSignature =
"Task SetObjectTagsAsync(SetObjectTagsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string deleteObjectTagsSignature =
"Task RemoveObjectTagsAsync(RemoveObjectTagsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setObjectRetentionSignature =
"Task SetObjectRetentionAsync(SetObjectRetentionArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getObjectRetentionSignature =
"Task<ObjectRetentionConfiguration> GetObjectRetentionAsync(GetObjectRetentionArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string clearObjectRetentionSignature =
"Task ClearObjectRetentionAsync(ClearObjectRetentionArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getBucketLifecycleSignature =
"Task<LifecycleConfiguration> GetBucketLifecycleAsync(GetBucketLifecycleArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setBucketLifecycleSignature =
"Task SetBucketLifecycleAsync(SetBucketLifecycleArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string deleteBucketLifecycleSignature =
"Task RemoveBucketLifecycleAsync(RemoveBucketLifecycleArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private static readonly Random rnd = new();
private static readonly RandomStreamGenerator rsg = new(100 * MB);
private static string Bash(string cmd)
{
var Replacements = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "$", "\\$" },
{ "(", "\\(" },
{ ")", "\\)" },
{ "{", "\\{" },
{ "}", "\\}" },
{ "[", "\\[" },
{ "]", "\\]" },
{ "@", "\\@" },
{ "%", "\\%" },
{ "&", "\\&" },
{ "#", "\\#" },
{ "+", "\\+" }
};
foreach (var toReplace in Replacements.Keys)
cmd = cmd.Replace(toReplace, Replacements[toReplace], StringComparison.Ordinal);
var cmdNoReturn = cmd + " >/dev/null 2>&1";
using var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = $"-c \"{cmdNoReturn}\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
_ = process.Start();
var result = process.StandardOutput.ReadLine();
process.WaitForExit();
return result;
}
// Create a file of given size from random byte array or optionally create a symbolic link
// to the dataFileName residing in MINT_DATA_DIR
private static string CreateFile(int size, string dataFileName = null)
{
var fileName = GetRandomName();
if (!IsMintEnv())
{
var data = new byte[size];
rnd.NextBytes(data);
File.WriteAllBytes(fileName, data);
return GetFilePath(fileName);
}
return GetFilePath(dataFileName);
}
public static string GetRandomObjectName(int length = 5)
{
// Server side does not allow the following characters in object names
// '-', '_', '.', '/', '*'
#if NET6_0_OR_GREATER
var characters = "abcd+%$#@&{}[]()";
#else
var characters = "abcdefgh+%$#@&";
#endif
var result = new StringBuilder(length);
for (var i = 0; i < length; i++) result.Append(characters[rnd.Next(characters.Length)]);
return result.ToString();
}
// Generate a random string
public static string GetRandomName(int length = 5)
{
var characters = "0123456789abcdefghijklmnopqrstuvwxyz";
if (length > 50) length = 50;
var result = new StringBuilder(length);
for (var i = 0; i < length; i++) _ = result.Append(characters[rnd.Next(characters.Length)]);
return "minio-dotnet-example-" + result;
}
internal static void GenerateRandom500MB_File(string fileName)
{
using var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true);
var fileSize = 500L * 1024 * 1024;
var segments = fileSize / 10000;
var last_seg = fileSize % 10000;
using var br = new BinaryWriter(fs);
for (long i = 0; i < segments; i++)
br.Write(new byte[10000]);
br.Write(new byte[last_seg]);
br.Close();
}
// Return true if running in Mint mode
public static bool IsMintEnv()
{
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MINT_DATA_DIR"));
}
// Get full path of file
public static string GetFilePath(string fileName)
{
var dataDir = Environment.GetEnvironmentVariable("MINT_DATA_DIR");
if (!string.IsNullOrEmpty(dataDir)) return $"{dataDir}/{fileName}";
var path = Directory.GetCurrentDirectory();
return $"{path}/{fileName}";
}
internal static Task RunCoreTests(IMinioClient minioClient)
{
ConcurrentBag<Task> coreTestsTasks = new()
{
// Check if bucket exists
BucketExists_Test(minioClient),
// Create a new bucket
MakeBucket_Test1(minioClient),
PutObject_Test1(minioClient),
PutObject_Test2(minioClient),
ListObjects_Test1(minioClient),
RemoveObject_Test1(minioClient),
CopyObject_Test1(minioClient),
// Test SetPolicyAsync function
SetBucketPolicy_Test1(minioClient),
// Test Presigned Get/Put operations
PresignedGetObject_Test1(minioClient),
PresignedPutObject_Test1(minioClient),
// Test incomplete uploads
ListIncompleteUpload_Test1(minioClient),
RemoveIncompleteUpload_Test(minioClient),
// Test GetBucket policy
GetBucketPolicy_Test1(minioClient)
};
return coreTestsTasks.ForEachAsync();
}
internal static async Task BucketExists_Test(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName();
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName);
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var 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();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketExists_Test), bucketExistsSignature, "Tests whether BucketExists passes",
TestStatus.NA, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(BucketExists_Test), bucketExistsSignature, "Tests whether BucketExists passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
internal static async Task RemoveBucket_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(20);
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName);
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
var found = false;
try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsFalse(found);
new MintLogger(nameof(RemoveBucket_Test1), removeBucketSignature, "Tests whether RemoveBucket passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(RemoveBucket_Test1), removeBucketSignature, "Tests whether RemoveBucket passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
if (found)
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
internal static async Task RemoveBucket_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(20);
var objectName = GetRandomName(20);
var forceFlagHeader = new Dictionary<string, string>
(StringComparer.Ordinal) { { "x-minio-force-delete", "true" } };
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName)
.WithHeaders(forceFlagHeader);
// Create and populate a bucket
var count = 50;
var tasks = new Task[count];
await Setup_Test(minio, bucketName).ConfigureAwait(false);
for (var i = 0; i < count; i++)
tasks[i] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(5));
await Task.WhenAll(tasks).ConfigureAwait(false);
await Task.Delay(1000).ConfigureAwait(false);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "x-minio-force-delete", "true" } };
var found = false;
try
{
found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsFalse(found);
new MintLogger(nameof(RemoveBucket_Test2), removeBucketSignature, "Tests whether RemoveBucket passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(RemoveBucket_Test2), removeBucketSignature, "Tests whether RemoveBucket passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
if (found)
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
internal static async Task ListBuckets_Test(IMinioClient minio)
{
var startTime = DateTime.Now;
IList<Bucket> bucketList = new List<Bucket>();
var bucketNameSuffix = "listbucketstest";
var noOfBuckets = 5;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketNameSuffix", bucketNameSuffix },
{ "noOfBuckets", noOfBuckets.ToString(CultureInfo.InvariantCulture) }
};
try
{
foreach (var indx in Enumerable.Range(1, noOfBuckets))
await Setup_Test(minio, "bucket" + indx + bucketNameSuffix).ConfigureAwait(false);
}
catch (Exception ex)
{
if (ex.Message.StartsWith("Bucket already owned by you", StringComparison.OrdinalIgnoreCase))
{
// You have your bucket already created, continue
}
else
{
throw;
}
}
try
{
var list = await minio.ListBucketsAsync().ConfigureAwait(false);
bucketList = list.Buckets;
bucketList = bucketList.Where(x => x.Name.EndsWith(bucketNameSuffix, StringComparison.OrdinalIgnoreCase))
.ToList();
Assert.AreEqual(noOfBuckets, bucketList.Count);
bucketList.ToList().Sort((x, y) =>
{
if (string.Equals(x.Name, y.Name, StringComparison.Ordinal)) return 0;
if (x.Name is null) return -1;
if (y.Name is null) return 1;
return string.Compare(x.Name, y.Name, StringComparison.Ordinal);
});
var indx = 0;
foreach (var bucket in bucketList)
{
indx++;
Assert.AreEqual("bucket" + indx + bucketNameSuffix, bucket.Name);
}
new MintLogger(nameof(ListBuckets_Test), listBucketsSignature, "Tests whether ListBucket passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(ListBuckets_Test), listBucketsSignature, "Tests whether ListBucket passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
foreach (var bucket in bucketList)
{
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucket.Name);
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
}
internal static async Task Setup_Test(IMinioClient minio, string bucketName)
{
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
if (await minio.BucketExistsAsync(beArgs).ConfigureAwait(false))
return;
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName);
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
}
internal static async Task Setup_WithLock_Test(IMinioClient minio, string bucketName)
{
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName)
.WithObjectLock();
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
}
internal static async Task TearDown(IMinioClient minio, string bucketName)
{
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var bktExists = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
if (!bktExists)
return;
var taskList = new List<Task>();
var getVersions = false;
// Get Versioning/Retention Info.
var lockConfigurationArgs =
new GetObjectLockConfigurationArgs()
.WithBucket(bucketName);
ObjectLockConfiguration lockConfig = null;
try
{
var versioningConfig = await minio.GetVersioningAsync(new GetVersioningArgs()
.WithBucket(bucketName)).ConfigureAwait(false);
if (versioningConfig is not null &&
(versioningConfig.Status.Contains("Enabled", StringComparison.Ordinal) ||
versioningConfig.Status.Contains("Suspended", StringComparison.Ordinal)))
getVersions = true;
lockConfig = await minio.GetObjectLockConfigurationAsync(lockConfigurationArgs).ConfigureAwait(false);
}
catch (MissingObjectLockConfigurationException)
{
// This exception is expected for those buckets created without a lock.
}
catch (NotImplementedException)
{
// No throw. Move to the next step without versions.
}
var tasks = new List<Task>();
var listObjectsArgs = new ListObjectsArgs()
.WithBucket(bucketName)
.WithRecursive(true)
.WithVersions(getVersions);
var objectNamesVersions =
new List<Tuple<string, string>>();
var objectNames = new List<string>();
var observable = minio.ListObjectsAsync(listObjectsArgs);
var exceptionList = new List<Exception>();
var subscription = observable.Subscribe(
item =>
{
if (getVersions)
objectNamesVersions.Add(new Tuple<string, string>(item.Key, item.VersionId));
else
objectNames.Add(item.Key);
},
exceptionList.Add,
() => { });
await Task.Delay(20000).ConfigureAwait(false);
if (lockConfig?.ObjectLockEnabled.Equals(ObjectLockConfiguration.LockEnabled,
StringComparison.OrdinalIgnoreCase) == true)
{
foreach (var item in objectNamesVersions)
{
var objectRetentionArgs = new GetObjectRetentionArgs()
.WithBucket(bucketName)
.WithObject(item.Item1)
.WithVersionId(item.Item2);
var retentionConfig = await minio.GetObjectRetentionAsync(objectRetentionArgs).ConfigureAwait(false);
var bypassGovMode = retentionConfig.Mode == ObjectRetentionMode.GOVERNANCE;
var removeObjectArgs = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(item.Item1)
.WithVersionId(item.Item2);
if (bypassGovMode)
removeObjectArgs = removeObjectArgs.WithBypassGovernanceMode(bypassGovMode);
var t = minio.RemoveObjectAsync(removeObjectArgs);
tasks.Add(t);
}
}
else
{
if (objectNamesVersions.Count > 0)
{
var removeObjectArgs = new RemoveObjectsArgs()
.WithBucket(bucketName)
.WithObjectsVersions(objectNamesVersions);
Task t = minio.RemoveObjectsAsync(removeObjectArgs);
tasks.Add(t);
}
if (objectNames.Count > 0)
{
var removeObjectArgs = new RemoveObjectsArgs()
.WithBucket(bucketName)
.WithObjects(objectNames);
Task t = minio.RemoveObjectsAsync(removeObjectArgs);
tasks.Add(t);
}
}
await Task.WhenAll(tasks).ConfigureAwait(false);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
internal static string XmlStrToJsonStr(string xml)
{
var doc = new XmlDocument();
doc.LoadXml(xml);
var xmlSerializer = new XmlSerializer(typeof(string));
using var stringReader = new StringReader(xml);
var obj = (string)xmlSerializer.Deserialize(stringReader)!;
return JsonSerializer.Serialize(obj);
}
internal static async Task PutGetStatEncryptedObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "application/octet-stream";
var tempFileName = "tempFile-" + GetRandomName();
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// Putobject with SSE-C encryption.
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var aesEncryption = Aes.Create();
aesEncryption.KeySize = 256;
aesEncryption.GenerateKey();
var ssec = new SSEC(aesEncryption.Key);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var file_write_size = filestream.Length;
long file_read_size = 0;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithServerSideEncryption(ssec)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(ssec)
.WithCallbackStream(async (stream, cancellationToken) =>
{
using var fileStream = File.Create(tempFileName);
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
await fileStream.DisposeAsync().ConfigureAwait(false);
var writtenInfo = new FileInfo(tempFileName);
file_read_size = writtenInfo.Length;
Assert.AreEqual(file_write_size, file_read_size);
File.Delete(tempFileName);
});
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(ssec);
_ = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
}
new MintLogger("PutGetStatEncryptedObject_Test1", putObjectSignature,
"Tests whether Put/Get/Stat Object with encryption passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger("PutGetStatEncryptedObject_Test1", putObjectSignature,
"Tests whether Put/Get/Stat Object with encryption passes", TestStatus.NA, DateTime.Now - startTime, "",
ex.Message, ex.ToString(), args).Log();
}
catch (Exception ex)
{
new MintLogger("PutGetStatEncryptedObject_Test1", putObjectSignature,
"Tests whether Put/Get/Stat Object with encryption passes", TestStatus.FAIL, DateTime.Now - startTime,
"", ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutGetStatEncryptedObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "application/octet-stream";
var tempFileName = "tempFile-" + GetRandomName();
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "data", "6MB" },
{ "size", "6MB" }
};
try
{
// Test multipart Put with SSE-C encryption
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var aesEncryption = Aes.Create();
aesEncryption.KeySize = 256;
aesEncryption.GenerateKey();
var ssec = new SSEC(aesEncryption.Key);
Stream filestream;
await using ((filestream = rsg.GenerateStreamFromSeed(6 * MB)).ConfigureAwait(false))
{
var file_write_size = filestream.Length;
long file_read_size = 0;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(contentType)
.WithServerSideEncryption(ssec);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(ssec)
.WithCallbackStream(async (stream, cancellationToken) =>
{
Stream fileStream;
await using ((fileStream = File.Create(tempFileName)).ConfigureAwait(false))
{
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
await fileStream.DisposeAsync().ConfigureAwait(false);
var writtenInfo = new FileInfo(tempFileName);
file_read_size = writtenInfo.Length;
Assert.AreEqual(file_write_size, file_read_size);
File.Delete(tempFileName);
}
});
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(ssec);
_ = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
}
new MintLogger("PutGetStatEncryptedObject_Test2", putObjectSignature,
"Tests whether Put/Get/Stat multipart upload with encryption passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
File.Delete(tempFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
new MintLogger("PutGetStatEncryptedObject_Test2", putObjectSignature,
"Tests whether Put/Get/Stat multipart upload with encryption passes", TestStatus.NA,
DateTime.Now - startTime, "", ex.Message, ex.ToString(), args).Log();
File.Delete(tempFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
catch (Exception ex)
{
new MintLogger("PutGetStatEncryptedObject_Test2", putObjectSignature,
"Tests whether Put/Get/Stat multipart upload with encryption passes", TestStatus.FAIL,
DateTime.Now - startTime, "", ex.Message, ex.ToString(), args).Log();
File.Delete(tempFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
}
internal static async Task PutGetStatEncryptedObject_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "application/octet-stream";
var tempFileName = "tempFile-" + GetRandomName();
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "data", "6MB" },
{ "size", "6MB" }
};
try
{
// Test multipart Put/Get/Stat with SSE-S3 encryption
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var aesEncryption = Aes.Create();
var sses3 = new SSES3();
using (var filestream = rsg.GenerateStreamFromSeed(6 * MB))
{
var file_write_size = filestream.Length;
long file_read_size = 0;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithServerSideEncryption(sses3)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCallbackStream(async (stream, cancellationToken) =>
{
using var fileStream = File.Create(tempFileName);
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
await fileStream.DisposeAsync().ConfigureAwait(false);
var writtenInfo = new FileInfo(tempFileName);
file_read_size = writtenInfo.Length;
Assert.AreEqual(file_write_size, file_read_size);
File.Delete(tempFileName);
});
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
_ = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
}
new MintLogger("PutGetStatEncryptedObject_Test3", putObjectSignature,
"Tests whether Put/Get/Stat multipart upload with encryption passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("PutGetStatEncryptedObject_Test3", putObjectSignature,
"Tests whether Put/Get/Stat multipart upload with encryption passes", TestStatus.FAIL,
DateTime.Now - startTime, "", ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Task(IMinioClient minio, string bucketName, string objectName,
string fileName = null, string contentType = "application/octet-stream", long size = 0,
Dictionary<string, string> metaData = null, Stream mstream = null)
{
var startTime = DateTime.Now;
var filestream = mstream;
if (filestream is null)
{
#if NETFRAMEWORK
ReadOnlyMemory<byte> bs = File.ReadAllBytes(fileName);
#else
ReadOnlyMemory<byte> bs = await File.ReadAllBytesAsync(fileName).ConfigureAwait(false);
#endif
filestream = bs.AsStream();
}
using (filestream)
{
var file_write_size = filestream.Length;
var tempFileName = "tempfile-" + GetRandomName();
if (size == 0)
size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(size)
.WithContentType(contentType)
.WithHeaders(metaData);
await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
File.Delete(tempFileName);
}
}
internal static async Task<ObjectStat> PutObject_Tester(IMinioClient minio,
string bucketName, string objectName, string fileName = null,
string contentType = "application/octet-stream", long size = 0,
Dictionary<string, string> metaData = null, Stream mstream = null,
IProgress<ProgressReport> progress = null)
{
ObjectStat statObject = null;
var startTime = DateTime.Now;
var filestream = mstream;
if (filestream is null)
{
#if NETFRAMEWORK
Memory<byte> bs = File.ReadAllBytes(fileName);
#else
Memory<byte> bs = await File.ReadAllBytesAsync(fileName).ConfigureAwait(false);
#endif
filestream = bs.AsStream();
}
using (filestream)
{
var file_write_size = filestream.Length;
var tempFileName = "tempfile-" + GetRandomName();
if (size == 0) size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(size)
.WithProgress(progress)
.WithContentType(contentType)
.WithHeaders(metaData);
await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
statObject = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsNotNull(statObject);
Assert.IsTrue(statObject.ObjectName.Equals(objectName, StringComparison.Ordinal));
Assert.AreEqual(statObject.Size, size);
if (contentType is not null)
{
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;
}
internal static async Task StatObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "gzip";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, null, 0, null,
rsg.GenerateStreamFromSeed(1 * KB)).ConfigureAwait(false);
new MintLogger(nameof(StatObject_Test1), statObjectSignature, "Tests whether StatObject passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(StatObject_Test1), statObjectSignature, "Tests whether statObjectSignature passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task FPutObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var fileName = CreateFile(6 * MB, dataFile6MB);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "fileName", fileName }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithFileName(fileName);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
new MintLogger("FPutObject_Test1", putObjectSignature,
"Tests whether FPutObject for multipart upload passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger("FPutObject_Test1", putObjectSignature,
"Tests whether FPutObject for multipart upload passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
if (!IsMintEnv()) File.Delete(fileName);
}
}
internal static async Task FPutObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var fileName = CreateFile(10 * KB, dataFile10KB);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "fileName", fileName }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithFileName(fileName);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
new MintLogger("FPutObject_Test2", putObjectSignature, "Tests whether FPutObject for small upload passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("FPutObject_Test2", putObjectSignature, "Tests whether FPutObject for small upload passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
if (!IsMintEnv())
{
GC.Collect();
GC.WaitForPendingFinalizers();
File.Delete(fileName);
}
}
}
internal static async Task RemoveObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } };
try
{
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
new MintLogger("RemoveObject_Test1", removeObjectSignature1,
"Tests whether RemoveObjectAsync for existing object passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger("RemoveObject_Test1", removeObjectSignature1,
"Tests whether RemoveObjectAsync for existing object passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task RemoveObjects_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(6);
var objectsList = new List<string>();
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectNames", "[" + objectName + "0..." + objectName + "50]" }
};
try
{
var count = 50;
var tasks = new Task[count];
await Setup_Test(minio, bucketName).ConfigureAwait(false);
for (var i = 0; i < count; i++)
{
tasks[i] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(5));
objectsList.Add(objectName + i);
}
await Task.WhenAll(tasks).ConfigureAwait(false);
await Task.Delay(1000).ConfigureAwait(false);
new MintLogger("RemoveObjects_Test2", removeObjectSignature2,
"Tests whether RemoveObjectAsync for multi objects delete passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("RemoveObjects_Test2", removeObjectSignature2,
"Tests whether RemoveObjectAsync for multi objects delete passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task RemoveObjects_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(6);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectNames", "[" + objectName + "0..." + objectName + "50]" }
};
try
{
var count = 50;
var tasks = new Task[count * 2];
var objectsList = new List<string>();
await Setup_WithLock_Test(minio, bucketName).ConfigureAwait(false);
for (var i = 0; i < count * 2;)
{
tasks[i++] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(5));
tasks[i++] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(5));
objectsList.Add(objectName + i);
}
await Task.WhenAll(tasks).ConfigureAwait(false);
await Task.Delay(1000).ConfigureAwait(false);
var listObjectsArgs = new ListObjectsArgs()
.WithBucket(bucketName)
.WithRecursive(true)
.WithVersions(true);
var observable = minio.ListObjectsAsync(listObjectsArgs);
var objVersions = new List<Tuple<string, string>>();
#pragma warning disable AsyncFixer03 // Fire-and-forget async-void methods or delegates
var subscription = observable.Subscribe(
item => objVersions.Add(new Tuple<string, string>(item.Key, item.VersionId)),
ex => throw ex,
async () =>
{
var removeObjectsArgs = new RemoveObjectsArgs()
.WithBucket(bucketName)
.WithObjectsVersions(objVersions);
var rmObservable = await minio.RemoveObjectsAsync(removeObjectsArgs).ConfigureAwait(false);
var deList = new List<DeleteError>();
using var rmSub = rmObservable.Subscribe(
err => deList.Add(err),
ex => throw ex,
async () => await TearDown(minio, bucketName).ConfigureAwait(false));
});
#pragma warning restore AsyncFixer03 // Fire-and-forget async-void methods or delegates
await Task.Delay(2 * 1000).ConfigureAwait(false);
new MintLogger("RemoveObjects_Test3", removeObjectSignature2,
"Tests whether RemoveObjectsAsync for multi objects/versions delete passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger("RemoveObjects_Test3", removeObjectSignature2,
"Tests whether RemoveObjectsAsync for multi objects/versions delete passes", TestStatus.NA,
DateTime.Now - startTime, "", ex.Message, ex.ToString(), args).Log();
}
catch (Exception ex)
{
new MintLogger("RemoveObjects_Test3", removeObjectSignature2,
"Tests whether RemoveObjectsAsync for multi objects/versions delete passes", TestStatus.FAIL,
DateTime.Now - startTime, "", ex.Message, ex.ToString(), args).Log();
throw;
}
}
internal static async Task DownloadObjectAsync(IMinioClient minio, string url, string filePath,
CancellationToken cancellationToken = default)
{
using var response = await minio.WrapperGetAsync(url).ConfigureAwait(false);
if (string.IsNullOrEmpty(Convert.ToString(response.Content)) || !HttpStatusCode.OK.Equals(response.StatusCode))
throw new InvalidOperationException("Unable to download via presigned URL" + nameof(response.Content));
using var fs = new FileStream(filePath, FileMode.CreateNew);
await response.Content.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
}
internal static async Task UploadObjectAsync(IMinioClient minio, string url, string filePath)
{
using var filestream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
using var stream = new StreamContent(filestream);
await minio.WrapperPutAsync(url, stream).ConfigureAwait(false);
}
internal static async Task PresignedPostPolicy_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var metadataKey = GetRandomName(10);
var metadataValue = GetRandomName(10);
// Generate presigned post policy url
var formPolicy = new PostPolicy();
var expiresOn = DateTime.UtcNow.AddMinutes(15);
formPolicy.SetExpires(expiresOn);
formPolicy.SetBucket(bucketName);
formPolicy.SetKey(objectName);
formPolicy.SetUserMetadata(metadataKey, metadataValue);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "expiresOn", expiresOn.ToString(CultureInfo.InvariantCulture) }
};
// File to be uploaded
var size = 10 * KB;
var sizeExpected = 10240;
var contentType = "application/octet-stream";
var fileName = CreateFile(size, dataFile10KB);
try
{
// Creates the bucket
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var polArgs = new PresignedPostPolicyArgs().WithBucket(bucketName)
.WithObject(objectName)
.WithPolicy(formPolicy);
var policyTuple = await minio.PresignedPostPolicyAsync(polArgs).ConfigureAwait(false);
var uri = policyTuple.Item1.AbsoluteUri;
var curlCommand = "curl --insecure";
foreach (var pair in policyTuple.Item2) curlCommand += $" -F {pair.Key}=\"{pair.Value}\"";
curlCommand += $" -F file=\"@{fileName}\" {uri}";
_ = Bash(curlCommand);
// Validate
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var statObject = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsNotNull(statObject);
Assert.IsTrue(statObject.ObjectName.Equals(objectName, StringComparison.Ordinal));
Assert.AreEqual(statObject.Size, sizeExpected);
Assert.IsTrue(statObject.MetaData["Content-Type"] is not null);
Assert.IsTrue(statObject.ContentType.Equals(contentType, StringComparison.OrdinalIgnoreCase));
Assert.IsTrue(statObject.MetaData[metadataKey].Equals(metadataValue, StringComparison.Ordinal));
new MintLogger("PresignedPostPolicy_Test1", presignedPostPolicySignature,
"Tests whether PresignedPostPolicy url applies policy on server", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("PresignedPostPolicy_Test1", presignedPostPolicySignature,
"Tests whether PresignedPostPolicy url applies policy on server", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
if (!IsMintEnv()) File.Delete(fileName);
}
internal static async Task RemoveIncompleteUpload_Test(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "csv";
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMilliseconds(2));
try
{
using var filestream = rsg.GenerateStreamFromSeed(30 * MB);
var file_write_size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs, cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
var rmArgs = new RemoveIncompleteUploadArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveIncompleteUploadAsync(rmArgs).ConfigureAwait(false);
var listArgs = new ListIncompleteUploadsArgs()
.WithBucket(bucketName);
var observable = minio.ListIncompleteUploads(listArgs);
var subscription = observable.Subscribe(
item => Assert.Fail(),
ex => Assert.Fail());
}
new MintLogger("RemoveIncompleteUpload_Test", removeIncompleteUploadSignature,
"Tests whether RemoveIncompleteUpload passes.", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (Exception ex)
{
new MintLogger("RemoveIncompleteUpload_Test", removeIncompleteUploadSignature,
"Tests whether RemoveIncompleteUpload passes.", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#region Select Object Content
internal static async Task SelectObjectContent_Test(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var outFileName = "outFileName-SelectObjectContent_Test";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "fileName", outFileName }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var csvString = new StringBuilder();
csvString.AppendLine("Employee,Manager,Group");
csvString.AppendLine("Employee4,Employee2,500");
csvString.AppendLine("Employee3,Employee1,500");
csvString.AppendLine("Employee1,,1000");
csvString.AppendLine("Employee5,Employee1,500");
csvString.AppendLine("Employee2,Employee1,800");
ReadOnlyMemory<byte> csvBytes = Encoding.UTF8.GetBytes(csvString.ToString());
using var stream = csvBytes.AsStream();
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(stream)
.WithObjectSize(stream.Length);
await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var inputSerialization = new SelectObjectInputSerialization
{
CompressionType = SelectCompressionType.NONE,
CSV = new CSVInputOptions
{
FileHeaderInfo = CSVFileHeaderInfo.None, RecordDelimiter = "\n", FieldDelimiter = ","
}
};
var outputSerialization = new SelectObjectOutputSerialization
{
CSV = new CSVOutputOptions { RecordDelimiter = "\n", FieldDelimiter = "," }
};
var selArgs = new SelectObjectContentArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpressionType(QueryExpressionType.SQL)
.WithQueryExpression("select * from s3object")
.WithInputSerialization(inputSerialization)
.WithOutputSerialization(outputSerialization);
var resp = await minio.SelectObjectContentAsync(selArgs).ConfigureAwait(false);
using var streamReader = new StreamReader(resp.Payload);
var output = await streamReader.ReadToEndAsync().ConfigureAwait(false);
var csvStringNoWS =
Regex.Replace(csvString.ToString(), @"\s+", "", RegexOptions.None, TimeSpan.FromHours(1));
var outputNoWS = Regex.Replace(output, @"\s+", "", RegexOptions.None, TimeSpan.FromHours(1));
#if NETFRAMEWORK
using var md5 = MD5.Create();
var hashedOutputBytes
= md5.ComputeHash(Encoding.UTF8.GetBytes(outputNoWS));
#else
// Compute MD5 for a better result.
var hashedOutputBytes = MD5.HashData(Encoding.UTF8.GetBytes(outputNoWS));
#endif
var outputMd5 = Convert.ToBase64String(hashedOutputBytes);
#if NETFRAMEWORK
using var md5CSV = MD5.Create();
var hashedCSVBytes
= md5CSV.ComputeHash(Encoding.UTF8.GetBytes(csvStringNoWS));
#else
var hashedCSVBytes = MD5.HashData(Encoding.UTF8.GetBytes(csvStringNoWS));
#endif
var csvMd5 = Convert.ToBase64String(hashedCSVBytes);
Assert.IsTrue(csvMd5.Contains(outputMd5, StringComparison.Ordinal));
new MintLogger("SelectObjectContent_Test", selectObjectSignature,
"Tests whether SelectObjectContent passes for a select query", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("SelectObjectContent_Test", selectObjectSignature,
"Tests whether SelectObjectContent passes for a select query", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
File.Delete(outFileName);
}
}
#endregion
#region Bucket Encryption
internal static async Task BucketEncryptionsAsync_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketEncryptionsAsync_Test1), setBucketEncryptionSignature,
"Tests whether SetBucketEncryptionAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var encryptionArgs = new SetBucketEncryptionArgs()
.WithBucket(bucketName);
await minio.SetBucketEncryptionAsync(encryptionArgs).ConfigureAwait(false);
new MintLogger(nameof(BucketEncryptionsAsync_Test1), setBucketEncryptionSignature,
"Tests whether SetBucketEncryptionAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketEncryptionsAsync_Test1), setBucketEncryptionSignature,
"Tests whether SetBucketEncryptionAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketEncryptionsAsync_Test1), setBucketEncryptionSignature,
"Tests whether SetBucketEncryptionAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var encryptionArgs = new GetBucketEncryptionArgs()
.WithBucket(bucketName);
var config = await minio.GetBucketEncryptionAsync(encryptionArgs).ConfigureAwait(false);
Assert.IsNotNull(config);
Assert.IsNotNull(config.Rule);
Assert.IsNotNull(config.Rule.Apply);
Assert.IsTrue(config.Rule.Apply.SSEAlgorithm.Contains("AES256", StringComparison.OrdinalIgnoreCase));
new MintLogger(nameof(BucketEncryptionsAsync_Test1), getBucketEncryptionSignature,
"Tests whether GetBucketEncryptionAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketEncryptionsAsync_Test1), getBucketEncryptionSignature,
"Tests whether GetBucketEncryptionAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketEncryptionsAsync_Test1), getBucketEncryptionSignature,
"Tests whether GetBucketEncryptionAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var rmEncryptionArgs = new RemoveBucketEncryptionArgs()
.WithBucket(bucketName);
await minio.RemoveBucketEncryptionAsync(rmEncryptionArgs).ConfigureAwait(false);
var encryptionArgs = new GetBucketEncryptionArgs()
.WithBucket(bucketName);
var config = await minio.GetBucketEncryptionAsync(encryptionArgs).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketEncryptionsAsync_Test1), removeBucketEncryptionSignature,
"Tests whether RemoveBucketEncryptionAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
if (ex.Message.Contains("The server side encryption configuration was not found",
StringComparison.OrdinalIgnoreCase))
{
new MintLogger(nameof(BucketEncryptionsAsync_Test1), removeBucketEncryptionSignature,
"Tests whether RemoveBucketEncryptionAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
else
{
new MintLogger(nameof(BucketEncryptionsAsync_Test1), removeBucketEncryptionSignature,
"Tests whether RemoveBucketEncryptionAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Legal Hold Status
internal static async Task LegalHoldStatusAsync_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } };
try
{
await Setup_WithLock_Test(minio, bucketName).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(LegalHoldStatusAsync_Test1), setObjectLegalHoldSignature,
"Tests whether SetObjectLegalHoldAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
return;
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(LegalHoldStatusAsync_Test1), setObjectLegalHoldSignature,
"Tests whether SetObjectLegalHoldAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(null);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var legalHoldArgs = new SetObjectLegalHoldArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithLegalHold(true);
await minio.SetObjectLegalHoldAsync(legalHoldArgs).ConfigureAwait(false);
new MintLogger(nameof(LegalHoldStatusAsync_Test1), setObjectLegalHoldSignature,
"Tests whether SetObjectLegalHoldAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(LegalHoldStatusAsync_Test1), setObjectLegalHoldSignature,
"Tests whether SetObjectLegalHoldAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(LegalHoldStatusAsync_Test1), setObjectLegalHoldSignature,
"Tests whether SetObjectLegalHoldAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var getLegalHoldArgs = new GetObjectLegalHoldArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var enabled = await minio.GetObjectLegalHoldAsync(getLegalHoldArgs).ConfigureAwait(false);
Assert.IsTrue(enabled);
var rmArgs = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectAsync(rmArgs).ConfigureAwait(false);
new MintLogger(nameof(LegalHoldStatusAsync_Test1), getObjectLegalHoldSignature,
"Tests whether GetObjectLegalHoldAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(LegalHoldStatusAsync_Test1), getObjectLegalHoldSignature,
"Tests whether GetObjectLegalHoldAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(LegalHoldStatusAsync_Test1), getObjectLegalHoldSignature,
"Tests whether GetObjectLegalHoldAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Bucket Tagging
internal static async Task BucketTagsAsync_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
var tags = new Dictionary<string, string>
(StringComparer.Ordinal) { { "key1", "value1" }, { "key2", "value2" }, { "key3", "value3" } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
new MintLogger(nameof(BucketTagsAsync_Test1), setBucketTagsSignature,
"Tests whether SetBucketTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var tagsArgs = new SetBucketTagsArgs()
.WithBucket(bucketName)
.WithTagging(Tagging.GetBucketTags(tags));
await minio.SetBucketTagsAsync(tagsArgs).ConfigureAwait(false);
new MintLogger(nameof(BucketTagsAsync_Test1), setBucketTagsSignature,
"Tests whether SetBucketTagsAsync passes", TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketTagsAsync_Test1), setBucketTagsSignature,
"Tests whether SetBucketTagsAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketTagsAsync_Test1), setBucketTagsSignature,
"Tests whether SetBucketTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var tagsArgs = new GetBucketTagsArgs()
.WithBucket(bucketName);
var tagObj = await minio.GetBucketTagsAsync(tagsArgs).ConfigureAwait(false);
Assert.IsNotNull(tagObj);
Assert.IsNotNull(tagObj.Tags);
var tagsRes = tagObj.Tags;
Assert.AreEqual(tagsRes.Count, tags.Count);
new MintLogger(nameof(BucketTagsAsync_Test1), getBucketTagsSignature,
"Tests whether GetBucketTagsAsync passes", TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketTagsAsync_Test1), getBucketTagsSignature,
"Tests whether GetBucketTagsAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(BucketTagsAsync_Test1), getBucketTagsSignature,
"Tests whether GetBucketTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
try
{
var tagsArgs = new RemoveBucketTagsArgs()
.WithBucket(bucketName);
await minio.RemoveBucketTagsAsync(tagsArgs).ConfigureAwait(false);
var getTagsArgs = new GetBucketTagsArgs()
.WithBucket(bucketName);
var tagObj = await minio.GetBucketTagsAsync(getTagsArgs).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketTagsAsync_Test1), deleteBucketTagsSignature,
"Tests whether RemoveBucketTagsAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
if (ex.Message.Contains("The TagSet does not exist", StringComparison.OrdinalIgnoreCase))
{
new MintLogger(nameof(BucketTagsAsync_Test1), deleteBucketTagsSignature,
"Tests whether RemoveBucketTagsAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
else
{
new MintLogger(nameof(BucketTagsAsync_Test1), deleteBucketTagsSignature,
"Tests whether RemoveBucketTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Object Tagging
internal static async Task ObjectTagsAsync_Test1(IMinioClient minio)
{
// Test will run twice once for file size 1KB amd once
// for 6MB to cover single and multipart upload functions
var sizesList = new List<int> { 1 * KB, 6 * MB };
foreach (var size in sizesList)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "fileSize", size.ToString(CultureInfo.InvariantCulture) }
};
var tags = new Dictionary<string, string>
(StringComparer.Ordinal) { { "key1", "value1" }, { "key2", "value2" }, { "key3", "value3" } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
new MintLogger(nameof(ObjectTagsAsync_Test1), setObjectTagsSignature,
"Tests whether SetObjectTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
var exceptionThrown = false;
try
{
using (var filestream = rsg.GenerateStreamFromSeed(size))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(null);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var tagsArgs = new SetObjectTagsArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithTagging(Tagging.GetObjectTags(tags));
await minio.SetObjectTagsAsync(tagsArgs).ConfigureAwait(false);
new MintLogger(nameof(ObjectTagsAsync_Test1), setObjectTagsSignature,
"Tests whether SetObjectTagsAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
exceptionThrown = true;
new MintLogger(nameof(ObjectTagsAsync_Test1), setObjectTagsSignature,
"Tests whether SetObjectTagsAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
exceptionThrown = true;
new MintLogger(nameof(ObjectTagsAsync_Test1), setObjectTagsSignature,
"Tests whether SetObjectTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
exceptionThrown = false;
var tagsArgs = new GetObjectTagsArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var tagObj = await minio.GetObjectTagsAsync(tagsArgs).ConfigureAwait(false);
Assert.IsNotNull(tagObj);
Assert.IsNotNull(tagObj.Tags);
var tagsRes = tagObj.Tags;
Assert.AreEqual(tagsRes.Count, tags.Count);
new MintLogger(nameof(ObjectTagsAsync_Test1), getObjectTagsSignature,
"Tests whether GetObjectTagsAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
exceptionThrown = true;
new MintLogger(nameof(ObjectTagsAsync_Test1), getObjectTagsSignature,
"Tests whether GetObjectTagsAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
exceptionThrown = true;
new MintLogger(nameof(ObjectTagsAsync_Test1), getObjectTagsSignature,
"Tests whether GetObjectTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
if (exceptionThrown)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
return;
}
try
{
var tagsArgs = new RemoveObjectTagsArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectTagsAsync(tagsArgs).ConfigureAwait(false);
var getTagsArgs = new GetObjectTagsArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var tagObj = await minio.GetObjectTagsAsync(getTagsArgs).ConfigureAwait(false);
Assert.IsNotNull(tagObj);
var tagsRes = tagObj.Tags;
Assert.IsNull(tagsRes);
new MintLogger(nameof(ObjectTagsAsync_Test1), deleteObjectTagsSignature,
"Tests whether RemoveObjectTagsAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ObjectTagsAsync_Test1), deleteObjectTagsSignature,
"Tests whether RemoveObjectTagsAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(ObjectTagsAsync_Test1), deleteObjectTagsSignature,
"Tests whether RemoveObjectTagsAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
}
#endregion
#region Object Versioning
internal static async Task ObjectVersioningAsync_Test1(IMinioClient minio)
{
// Test will run twice once for file size 1KB amd once
// for 6MB to cover single and multipart upload functions
var sizesList = new List<int> { 1 * KB, 6 * MB };
foreach (var size in sizesList)
{
var loopIndex = 1;
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "fileSize", size.ToString(CultureInfo.InvariantCulture) }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
{
// Set versioning enabled test
var setVersioningArgs = new SetVersioningArgs()
.WithBucket(bucketName)
.WithVersioningEnabled();
await minio.SetVersioningAsync(setVersioningArgs).ConfigureAwait(false);
// Put the same object twice to have 2 versions of it
using (var filestream = rsg.GenerateStreamFromSeed(size))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(null);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
using (var filestream = rsg.GenerateStreamFromSeed(size))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(null);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
// In each run, there will be 2 more versions of the object
var objectVersionCount = loopIndex * 2;
await ListObjects_Test(minio, bucketName, "", objectVersionCount, true, true).ConfigureAwait(false);
new MintLogger(nameof(ObjectVersioningAsync_Test1), setVersioningSignature,
"Tests whether SetVersioningAsync/GetVersioningAsync/RemoveVersioningAsync passes",
TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
// Get Versioning Test
var getVersioningArgs = new GetVersioningArgs()
.WithBucket(bucketName);
var versioningConfig = await minio.GetVersioningAsync(getVersioningArgs).ConfigureAwait(false);
Assert.IsNotNull(versioningConfig);
Assert.IsNotNull(versioningConfig.Status);
Assert.IsTrue(versioningConfig.Status.Equals("enabled", StringComparison.OrdinalIgnoreCase));
new MintLogger(nameof(ObjectVersioningAsync_Test1), getVersioningSignature,
"Tests whether SetVersioningAsync/GetVersioningAsync/RemoveVersioningAsync passes",
TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
// Suspend Versioning test
setVersioningArgs = new SetVersioningArgs()
.WithBucket(bucketName)
.WithVersioningSuspended();
await minio.SetVersioningAsync(setVersioningArgs).ConfigureAwait(false);
var objectCount = 1;
await ListObjects_Test(minio, bucketName, "", objectCount, false).ConfigureAwait(false);
new MintLogger(nameof(ObjectVersioningAsync_Test1), removeVersioningSignature,
"Tests whether SetVersioningAsync/GetVersioningAsync/RemoveVersioningAsync passes",
TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ObjectVersioningAsync_Test1), setVersioningSignature,
"Tests whether SetVersioningAsync/GetVersioningAsync/RemoveVersioningAsync passes", TestStatus.NA,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(ObjectVersioningAsync_Test1), setVersioningSignature,
"Tests whether SetVersioningAsync/GetVersioningAsync/RemoveVersioningAsync passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
}
#endregion
#region Object Lock Configuration
[SuppressMessage("Design", "MA0051:Method is too long", Justification = "TODO")]
internal static async Task ObjectLockConfigurationAsync_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
var setLockNotImplemented = false;
var getLockNotImplemented = false;
try
{
await Setup_WithLock_Test(minio, bucketName).ConfigureAwait(false);
//TODO: Use it for testing and remove
{
var objectRetention = new ObjectRetentionConfiguration(DateTime.Today.AddDays(3));
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
// Twice, for 2 versions.
var putObjectArgs1 = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithRetentionConfiguration(objectRetention)
.WithContentType(null);
_ = await minio.PutObjectAsync(putObjectArgs1).ConfigureAwait(false);
}
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs2 = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithRetentionConfiguration(objectRetention)
.WithContentType(null);
_ = await minio.PutObjectAsync(putObjectArgs2).ConfigureAwait(false);
}
}
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), setObjectLockConfigurationSignature,
"Tests whether SetObjectLockConfigurationAsync passes", TestStatus.NA, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
return;
}
catch (Exception ex)
{
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), setObjectLockConfigurationSignature,
"Tests whether SetObjectLockConfigurationAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
try
{
var objectLockArgs = new SetObjectLockConfigurationArgs()
.WithBucket(bucketName)
.WithLockConfiguration(
new ObjectLockConfiguration(ObjectRetentionMode.GOVERNANCE, 33)
);
await minio.SetObjectLockConfigurationAsync(objectLockArgs).ConfigureAwait(false);
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), setObjectLockConfigurationSignature,
"Tests whether SetObjectLockConfigurationAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (NotImplementedException ex)
{
setLockNotImplemented = true;
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), setObjectLockConfigurationSignature,
"Tests whether SetObjectLockConfigurationAsync passes", TestStatus.NA, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), setObjectLockConfigurationSignature,
"Tests whether SetObjectLockConfigurationAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
try
{
var objectLockArgs = new GetObjectLockConfigurationArgs()
.WithBucket(bucketName);
var config = await minio.GetObjectLockConfigurationAsync(objectLockArgs).ConfigureAwait(false);
Assert.IsNotNull(config);
Assert.IsTrue(config.ObjectLockEnabled.Contains(ObjectLockConfiguration.LockEnabled,
StringComparison.OrdinalIgnoreCase));
Assert.IsNotNull(config.Rule);
Assert.IsNotNull(config.Rule.DefaultRetention);
Assert.AreEqual(config.Rule.DefaultRetention.Days, 33);
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), getObjectLockConfigurationSignature,
"Tests whether GetObjectLockConfigurationAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (NotImplementedException ex)
{
getLockNotImplemented = true;
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), getObjectLockConfigurationSignature,
"Tests whether GetObjectLockConfigurationAsync passes", TestStatus.NA, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), getObjectLockConfigurationSignature,
"Tests whether GetObjectLockConfigurationAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
try
{
if (setLockNotImplemented || getLockNotImplemented)
{
// Cannot test Remove Object Lock with Set & Get Object Lock implemented.
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), deleteObjectLockConfigurationSignature,
"Tests whether RemoveObjectLockConfigurationAsync passes", TestStatus.NA, DateTime.Now - startTime,
"Functionality that is not implemented", "", args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
return;
}
var objectLockArgs = new RemoveObjectLockConfigurationArgs()
.WithBucket(bucketName);
await minio.RemoveObjectLockConfigurationAsync(objectLockArgs).ConfigureAwait(false);
var getObjectLockArgs = new GetObjectLockConfigurationArgs()
.WithBucket(bucketName);
var config = await minio.GetObjectLockConfigurationAsync(getObjectLockArgs).ConfigureAwait(false);
Assert.IsNotNull(config);
Assert.IsNull(config.Rule);
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), deleteObjectLockConfigurationSignature,
"Tests whether RemoveObjectLockConfigurationAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), deleteObjectLockConfigurationSignature,
"Tests whether RemoveObjectLockConfigurationAsync passes", TestStatus.NA, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(ObjectLockConfigurationAsync_Test1), deleteObjectLockConfigurationSignature,
"Tests whether RemoveObjectLockConfigurationAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await Task.Delay(1500).ConfigureAwait(false);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Object Retention
[SuppressMessage("Design", "MA0051:Method is too long", Justification = "Refactor later")]
internal static async Task ObjectRetentionAsync_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }
};
try
{
await Setup_WithLock_Test(minio, bucketName).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(ObjectRetentionAsync_Test1), setObjectRetentionSignature,
"Tests whether SetObjectRetentionAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
return;
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(ObjectRetentionAsync_Test1), setObjectRetentionSignature,
"Tests whether SetObjectRetentionAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var plusDays = 10;
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(null);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var untilDate = DateTime.Now.AddDays(plusDays);
var setRetentionArgs = new SetObjectRetentionArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithRetentionMode(ObjectRetentionMode.GOVERNANCE)
.WithRetentionUntilDate(untilDate);
await minio.SetObjectRetentionAsync(setRetentionArgs).ConfigureAwait(false);
new MintLogger(nameof(ObjectRetentionAsync_Test1), setObjectRetentionSignature,
"Tests whether SetObjectRetentionAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ObjectRetentionAsync_Test1), setObjectRetentionSignature,
"Tests whether SetObjectRetentionAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(ObjectRetentionAsync_Test1), setObjectRetentionSignature,
"Tests whether SetObjectRetentionAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var getRetentionArgs = new GetObjectRetentionArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var config = await minio.GetObjectRetentionAsync(getRetentionArgs).ConfigureAwait(false);
var plusDays = 10.0;
Assert.IsNotNull(config);
Assert.AreEqual(config.Mode, ObjectRetentionMode.GOVERNANCE);
var untilDate = DateTime.Parse(config.RetainUntilDate, null, DateTimeStyles.RoundtripKind);
Assert.AreEqual(Math.Ceiling((untilDate - DateTime.Now).TotalDays), plusDays);
new MintLogger(nameof(ObjectRetentionAsync_Test1), getObjectRetentionSignature,
"Tests whether GetObjectRetentionAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ObjectRetentionAsync_Test1), getObjectRetentionSignature,
"Tests whether GetObjectRetentionAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(ObjectRetentionAsync_Test1), getObjectRetentionSignature,
"Tests whether GetObjectRetentionAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var clearRetentionArgs = new ClearObjectRetentionArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.ClearObjectRetentionAsync(clearRetentionArgs).ConfigureAwait(false);
var getRetentionArgs = new GetObjectRetentionArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var config = await minio.GetObjectRetentionAsync(getRetentionArgs).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ObjectRetentionAsync_Test1), clearObjectRetentionSignature,
"Tests whether ClearObjectRetentionAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
var errMsgLock = ex.Message.Contains("The specified object does not have a ObjectLock configuration",
StringComparison.OrdinalIgnoreCase);
if (errMsgLock)
{
new MintLogger(nameof(ObjectRetentionAsync_Test1), clearObjectRetentionSignature,
"Tests whether ClearObjectRetentionAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
else
{
new MintLogger(nameof(ObjectRetentionAsync_Test1), clearObjectRetentionSignature,
"Tests whether ClearObjectRetentionAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
}
try
{
var rmArgs = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectAsync(rmArgs).ConfigureAwait(false);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
new MintLogger(nameof(ObjectRetentionAsync_Test1), clearObjectRetentionSignature,
"TearDown operation ClearObjectRetentionAsync", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
}
#endregion
internal static MemoryStream CreateZipFile(string prefix, int nFiles)
{
// CreateZipFile creates a zip file, populates it with <nFiles> many
// small files, each prefixed with <prefix> and in bytes size plus a single
// 1MB file. It generates and returns a memory stream of the zip file.
// The names of these files are arranged in "<file-size>.bin" format,
// like "127.bin" is created as a small binary file in 127 bytes size.
var outputMemStream = new MemoryStream();
using var zipStream = new ZipOutputStream(outputMemStream);
zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
_ = Directory.CreateDirectory(prefix);
for (var i = 1; i <= nFiles; i++)
{
// Make a single 1Mb file
if (i == nFiles) i = 1000000;
var fileName = prefix + i + ".bin";
var newEntry = new ZipEntry(fileName) { DateTime = DateTime.Now };
zipStream.PutNextEntry(newEntry);
using var stream = rsg.GenerateStreamFromSeed(i);
StreamUtils.Copy(stream, zipStream, new byte[i * 128]);
zipStream.CloseEntry();
}
// Setting ownership to False keeps the underlying stream open
zipStream.IsStreamOwner = false;
// Must finish the ZipOutputStream before using outputMemStream
zipStream.Close();
outputMemStream.Position = 0;
_ = outputMemStream.Seek(0, SeekOrigin.Begin);
return outputMemStream;
}
internal static async Task GetObjectS3Zip_Test1(IMinioClient minio)
{
var path = "test/small/";
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var randomFileName = GetRandomName(15) + ".zip";
var objectName = GetRandomObjectName(15) + ".zip";
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
const int nFiles = 500;
using var memStream = CreateZipFile(path, nFiles);
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(memStream)
.WithObjectSize(memStream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var extractHeader = new Dictionary<string, string>
(StringComparer.Ordinal) { { "x-minio-extract", "true" } };
// GeObject api test
var r = new Random();
var singleFileName = r.Next(1, nFiles - 1) + ".bin";
var singleObjectName = objectName + "/" + path + singleFileName;
// File names in the zip file also show the sizes of the files
// For example file "35.bin" has a size of 35Bytes
var expectedFileSize = Path.GetFileNameWithoutExtension(singleFileName);
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithFile(randomFileName)
.WithObject(singleObjectName)
.WithHeaders(extractHeader);
var resp = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
// Verify the size of the file from the returned info
Assert.AreEqual(expectedFileSize, resp.Size.ToString(CultureInfo.InvariantCulture));
// HeadObject api test
var statArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(singleObjectName)
.WithHeaders(extractHeader);
var stat = await minio.StatObjectAsync(statArgs).ConfigureAwait(false);
// Verify the size of the file from the returned info
Assert.AreEqual(expectedFileSize, resp.Size.ToString(CultureInfo.InvariantCulture));
// ListObject api test with different prefix values
// prefix value="", expected number of files listed=1
var prefix = "";
await ListObjects_Test(minio, bucketName, prefix, 1, headers: extractHeader).ConfigureAwait(false);
// prefix value="/", expected number of files listed=nFiles
prefix = objectName + "/";
await ListObjects_Test(minio, bucketName, prefix, nFiles, headers: extractHeader)
.ConfigureAwait(false);
// prefix value="/test", expected number of files listed=nFiles
prefix = objectName + "/test";
await ListObjects_Test(minio, bucketName, prefix, nFiles, headers: extractHeader)
.ConfigureAwait(false);
// prefix value="/test/", expected number of files listed=nFiles
prefix = objectName + "/test/";
await ListObjects_Test(minio, bucketName, prefix, nFiles, headers: extractHeader)
.ConfigureAwait(false);
// prefix value="/test", expected number of files listed=nFiles
prefix = objectName + "/test/small";
await ListObjects_Test(minio, bucketName, prefix, nFiles, headers: extractHeader)
.ConfigureAwait(false);
// prefix value="/test", expected number of files listed=nFiles
prefix = objectName + "/test/small/";
await ListObjects_Test(minio, bucketName, prefix, nFiles, headers: extractHeader)
.ConfigureAwait(false);
// prefix value="/test", expected number of files listed=1
await ListObjects_Test(minio, bucketName, singleObjectName, 1, headers: extractHeader)
.ConfigureAwait(false);
new MintLogger("GetObjectS3Zip_Test1", getObjectSignature, "Tests s3Zip files", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("GetObjectS3Zip_Test1", getObjectSignature, "Tests s3Zip files", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(randomFileName);
Directory.Delete(path.Split('/')[0], true);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#region Bucket Notifications
internal static async Task ListenBucketNotificationsAsync_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomName(10);
var contentType = "application/octet-stream";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "size", "1KB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var received = new List<MinioNotificationRaw>();
var eventsList = new List<EventType> { EventType.ObjectCreatedAll };
var listenArgs = new ListenBucketNotificationsArgs()
.WithBucket(bucketName)
.WithEvents(eventsList);
var events = minio.ListenBucketNotificationsAsync(listenArgs);
var subscription = events.Subscribe(
received.Add,
ex => { },
() => { }
);
_ = await PutObject_Tester(minio, bucketName, objectName, null, contentType,
0, null, rsg.GenerateStreamFromSeed(1 * KB)).ConfigureAwait(false);
// wait for notifications
var eventDetected = false;
for (var attempt = 0; attempt < 10; attempt++)
if (received.Count > 0)
{
// Check if there is any unexpected error returned
// and captured in the receivedJson list, like
// "NotImplemented" api error. If so, we throw an exception
// and skip running this test
if (received.Count > 1 &&
received[1].Json.StartsWith("<Error><Code>", StringComparison.OrdinalIgnoreCase))
{
// Although the attribute is called "json",
// returned data in list "received" is in xml
// format and it is an error.Here, we convert xml
// into json format.
var receivedJson = XmlStrToJsonStr(received[1].Json);
// Cleanup the "Error" key encapsulating "receivedJson"
// data. This is required to match and convert json data
// "receivedJson" into class "ErrorResponse"
var len = "{'Error':".Length;
var trimmedFront = receivedJson[len..];
var trimmedFull = trimmedFront[..^1];
var err = JsonSerializer.Deserialize<ErrorResponse>(trimmedFull);
Exception ex = new UnexpectedMinioException(err.Message);
if (string.Equals(err.Code, "NotImplemented", StringComparison.OrdinalIgnoreCase))
ex = new NotImplementedException(err.Message);
await TearDown(minio, bucketName).ConfigureAwait(false);
throw ex;
}
var notification = JsonSerializer.Deserialize<MinioNotification>(received[0].Json);
if (notification.Records is not null)
{
Assert.AreEqual(1, notification.Records.Count);
Assert.IsTrue(notification.Records[0].EventName
.Contains("s3:ObjectCreated:Put", StringComparison.OrdinalIgnoreCase));
Assert.IsTrue(
objectName.Contains(HttpUtility.UrlDecode(notification.Records[0].S3.ObjectMeta.Key),
StringComparison.OrdinalIgnoreCase));
Assert.IsTrue(contentType.Contains(notification.Records[0].S3.ObjectMeta.ContentType,
StringComparison.OrdinalIgnoreCase));
eventDetected = true;
break;
}
}
// subscription.Dispose();
if (!eventDetected)
throw new UnexpectedMinioException("Failed to detect the expected bucket notification event.");
new MintLogger(nameof(ListenBucketNotificationsAsync_Test1),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for small object",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(ListenBucketNotificationsAsync_Test1),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for small object",
TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
if (string.Equals(ex.Message, "Listening for bucket notification is specific" +
" only to `minio` server endpoints", StringComparison.OrdinalIgnoreCase))
{
// This is expected when bucket notification
// is requested against AWS.
// Check if endPoint is AWS
static bool isAWS(string endPoint)
{
var rgx = new Regex("^s3\\.?.*\\.amazonaws\\.com", RegexOptions.IgnoreCase, TimeSpan.FromHours(1));
var matches = rgx.Matches(endPoint);
return matches.Count > 0;
}
if (Environment.GetEnvironmentVariable("AWS_ENDPOINT") is not null ||
isAWS(Environment.GetEnvironmentVariable("SERVER_ENDPOINT")))
// This is a PASS
new MintLogger(nameof(ListenBucketNotificationsAsync_Test1),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for small object",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
else
{
new MintLogger(nameof(ListenBucketNotificationsAsync_Test1),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for small object",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
}
}
internal static async Task ListenBucketNotificationsAsync_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var events = new List<EventType> { EventType.ObjectCreatedAll };
var rxEventData = new MinioNotificationRaw("");
var rxEventsList = new List<NotificationEvent>();
var bucketName = GetRandomName(15);
var contentType = "application/json";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "contentType", contentType }, { "size", "16B" }
};
try
{
var bucketExistsArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var found = await minio.BucketExistsAsync(bucketExistsArgs).ConfigureAwait(false);
if (!found)
{
var makeBucketArgs = new MakeBucketArgs()
.WithBucket(bucketName);
await minio.MakeBucketAsync(makeBucketArgs).ConfigureAwait(false);
}
void Notify(MinioNotificationRaw data)
{
var notification = JsonSerializer.Deserialize<MinioNotification>(data.Json);
if (notification is not { Records: not null }) return;
rxEventsList.AddRange(notification.Records);
}
var listenArgs = new ListenBucketNotificationsArgs()
.WithBucket(bucketName)
.WithEvents(events);
var observable = minio.ListenBucketNotificationsAsync(listenArgs);
var subscription = observable.Subscribe(
ev =>
{
rxEventData = ev;
Notify(rxEventData);
},
ex => throw new InvalidOperationException($"OnError: {ex.Message}"),
() => throw new InvalidOperationException("STOPPED LISTENING FOR BUCKET NOTIFICATIONS\n"));
// Sleep to give enough time for the subscriber to be ready
var sleepTime = 1000; // Milliseconds
await Task.Delay(sleepTime).ConfigureAwait(false);
var modelJson = "{\"test2\": \"test2\"}";
using var stream = Encoding.UTF8.GetBytes(modelJson).AsMemory().AsStream();
var putObjectArgs = new PutObjectArgs()
.WithObject("test2.json")
.WithBucket(bucketName)
.WithContentType(contentType)
.WithStreamData(stream)
.WithObjectSize(stream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
// Waits until the Put event is detected
// Times out if the event is not caught in 3 seconds
var timeout = 3000; // Milliseconds
var waitTime = 25; // Milliseconds
var stTime = DateTime.UtcNow;
while (string.IsNullOrEmpty(rxEventData.Json))
{
await Task.Delay(waitTime).ConfigureAwait(false);
if ((DateTime.UtcNow - stTime).TotalMilliseconds >= timeout)
throw new TimeoutException("Timeout: while waiting for events");
}
foreach (var ev in rxEventsList) Assert.AreEqual("s3:ObjectCreated:Put", ev.EventName);
new MintLogger(nameof(ListenBucketNotificationsAsync_Test2),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for longer event processing",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(ListenBucketNotificationsAsync_Test2),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for longer event processing",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListenBucketNotificationsAsync_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var events = new List<EventType> { EventType.ObjectCreatedAll };
var rxEventData = new MinioNotificationRaw("");
IDisposable disposable = null;
var bucketName = GetRandomName(15);
var suffix = ".json";
var contentType = "application/json";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "contentType", contentType }, { "suffix", suffix }, { "size", "16B" }
};
try
{
var bucketExistsArgs = new BucketExistsArgs()
.WithBucket(bucketName);
if (!await minio.BucketExistsAsync(bucketExistsArgs).ConfigureAwait(false))
{
var makeBucketArgs = new MakeBucketArgs()
.WithBucket(bucketName);
await minio.MakeBucketAsync(makeBucketArgs).ConfigureAwait(false);
}
var notificationsArgs = new ListenBucketNotificationsArgs()
.WithBucket(bucketName)
.WithSuffix(suffix)
.WithEvents(events);
var modelJson = "{\"test3\": \"test3\"}";
using var stream = Encoding.UTF8.GetBytes(modelJson).AsMemory().AsStream();
var putObjectArgs = new PutObjectArgs()
.WithObject("test3.json")
.WithBucket(bucketName)
.WithContentType(contentType)
.WithStreamData(stream)
.WithObjectSize(stream.Length);
Exception exception = null;
var notifications = minio.ListenBucketNotificationsAsync(notificationsArgs);
disposable = notifications.Subscribe(
x => rxEventData = x,
ex => exception = ex,
() => { });
// Sleep to give enough time for the subscriber to be ready
var sleepTime = 1000; // Milliseconds
await Task.Delay(sleepTime).ConfigureAwait(false);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var stTime = DateTime.UtcNow;
var waitTime = 25; // Milliseconds
var timeout = 3000; // Milliseconds
while (string.IsNullOrEmpty(rxEventData.Json))
{
await Task.Delay(waitTime).ConfigureAwait(false);
if ((DateTime.UtcNow - stTime).TotalMilliseconds >= timeout)
throw new TimeoutException("Timeout: while waiting for events");
}
if (!string.IsNullOrEmpty(rxEventData.Json))
{
var notification = JsonSerializer.Deserialize<MinioNotification>(rxEventData.Json);
Assert.IsTrue(notification.Records[0].EventName
.Equals("s3:ObjectCreated:Put", StringComparison.OrdinalIgnoreCase));
new MintLogger(nameof(ListenBucketNotificationsAsync_Test3),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for no event processing",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
else if (exception is not null)
{
throw exception;
}
else
{
throw new InvalidDataException("Missed Event: Bucket notification failed.");
}
}
catch (Exception ex)
{
new MintLogger(nameof(ListenBucketNotificationsAsync_Test3),
listenBucketNotificationsSignature,
"Tests whether ListenBucketNotifications passes for no event processing",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
disposable?.Dispose();
}
}
#endregion
#region Make Bucket
internal static async Task MakeBucket_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(60);
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName);
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "region", "us-east-1" } };
try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
new MintLogger(nameof(MakeBucket_Test1), makeBucketSignature, "Tests whether MakeBucket passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(MakeBucket_Test1), makeBucketSignature, "Tests whether MakeBucket passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
internal static async Task MakeBucket_Test2(IMinioClient minio, bool aws = false)
{
if (!aws)
return;
var startTime = DateTime.Now;
var bucketName = GetRandomName(10) + ".withperiod";
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName);
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "region", "us-east-1" } };
var testType = "Test whether make bucket passes when bucketname has a period.";
try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
new MintLogger(nameof(MakeBucket_Test2), makeBucketSignature, testType, TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(MakeBucket_Test2), makeBucketSignature, testType, TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
internal static async Task MakeBucket_Test3(IMinioClient minio, bool aws = false)
{
if (!aws)
return;
var startTime = DateTime.Now;
var bucketName = GetRandomName(60);
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName)
.WithLocation("eu-central-1");
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "region", "eu-central-1" } };
try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
new MintLogger(nameof(MakeBucket_Test3), makeBucketSignature, "Tests whether MakeBucket with region passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(MakeBucket_Test3), makeBucketSignature, "Tests whether MakeBucket with region passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
internal static async Task MakeBucket_Test4(IMinioClient minio, bool aws = false)
{
if (!aws)
return;
var startTime = DateTime.Now;
var bucketName = GetRandomName(20) + ".withperiod";
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName)
.WithLocation("us-west-2");
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "region", "us-west-2" } };
try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
new MintLogger(nameof(MakeBucket_Test4), makeBucketSignature,
"Tests whether MakeBucket with region and bucketname with . passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(MakeBucket_Test4), makeBucketSignature,
"Tests whether MakeBucket with region and bucketname with . passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
internal static async Task MakeBucket_Test5(IMinioClient minio)
{
var startTime = DateTime.Now;
string bucketName = null;
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "region", "us-east-1" } };
try
{
_ = await Assert.ThrowsExceptionAsync<InvalidBucketNameException>(() =>
minio.MakeBucketAsync(new MakeBucketArgs()
.WithBucket(bucketName))).ConfigureAwait(false);
new MintLogger(nameof(MakeBucket_Test5), makeBucketSignature,
"Tests whether MakeBucket throws InvalidBucketNameException when bucketName is null", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(MakeBucket_Test5), makeBucketSignature,
"Tests whether MakeBucket throws InvalidBucketNameException when bucketName is null", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
}
internal static async Task MakeBucketLock_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(60);
var mbArgs = new MakeBucketArgs()
.WithBucket(bucketName)
.WithObjectLock();
var beArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var rbArgs = new RemoveBucketArgs()
.WithBucket(bucketName);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "region", "us-east-1" } };
try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
new MintLogger(nameof(MakeBucket_Test1), makeBucketSignature, "Tests whether MakeBucket with Lock passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(MakeBucket_Test1), makeBucketSignature, "Tests whether MakeBucket with Lock passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
}
}
#endregion
#region Put Object
internal static async Task PutObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "application/octet-stream";
var size = 1 * MB;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "size", "1MB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var resp = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
rsg.GenerateStreamFromSeed(size)).ConfigureAwait(false);
Assert.AreEqual(size, resp.Size);
Assert.AreEqual(objectName, objectName);
new MintLogger(nameof(PutObject_Test1), putObjectSignature,
"Tests whether PutObject passes for small object", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test1), putObjectSignature,
"Tests whether PutObject passes for small object", TestStatus.FAIL, DateTime.Now - startTime, "",
ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "binary/octet-stream";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "size", "6MB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
rsg.GenerateStreamFromSeed(6 * MB)).ConfigureAwait(false);
new MintLogger(nameof(PutObject_Test2), putObjectSignature, "Tests whether multipart PutObject passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test2), putObjectSignature, "Tests whether multipart PutObject passes",
TestStatus.FAIL, DateTime.Now - startTime, "", ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "custom-contenttype";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "size", "1MB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
rsg.GenerateStreamFromSeed(1 * MB)).ConfigureAwait(false);
new MintLogger(nameof(PutObject_Test3), putObjectSignature,
"Tests whether PutObject with custom content-type passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test3), putObjectSignature,
"Tests whether PutObject with custom content-type passes", TestStatus.FAIL, DateTime.Now - startTime,
"", ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Test4(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var fileName = CreateFile(1, dataFile1B);
var contentType = "custom/contenttype";
var metaData = new Dictionary<string, string>
(StringComparer.Ordinal) { { "customheader", "minio dotnet" } };
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "data", "1B" },
{ "size", "1B" },
{ "metaData", "customheader:minio-dotnet" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var statObject =
await PutObject_Tester(minio, bucketName, objectName, fileName, contentType, metaData: metaData)
.ConfigureAwait(false);
Assert.IsTrue(statObject is not null);
Assert.IsTrue(statObject.MetaData is not null);
var statMeta = new Dictionary<string, string>(statObject.MetaData, StringComparer.OrdinalIgnoreCase);
Assert.IsTrue(statMeta.ContainsKey("Customheader"));
Assert.IsTrue(statObject.MetaData.ContainsKey("Content-Type") &&
statObject.MetaData["Content-Type"]
.Equals("custom/contenttype", StringComparison.OrdinalIgnoreCase));
new MintLogger(nameof(PutObject_Test4), putObjectSignature,
"Tests whether PutObject with different content-type and custom header passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test4), putObjectSignature,
"Tests whether PutObject with different content-type and custom header passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
if (!IsMintEnv()) File.Delete(fileName);
}
}
internal static async Task PutObject_Test5(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "data", "1B" }, { "size", "1B" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, null, 0, null,
rsg.GenerateStreamFromSeed(1))
.ConfigureAwait(false);
new MintLogger(nameof(PutObject_Test5), putObjectSignature,
"Tests whether PutObject with no content-type passes for small object", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test5), putObjectSignature,
"Tests whether PutObject with no content-type passes for small object", TestStatus.FAIL,
DateTime.Now - startTime, "", ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Test7(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "application/octet-stream";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "data", "10KB" },
{ "size", "-1" }
};
try
{
// Putobject call with unknown stream size. See if PutObjectAsync call succeeds
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(10 * KB))
{
long size = -1;
var file_write_size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(size)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var rmArgs = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectAsync(rmArgs).ConfigureAwait(false);
}
new MintLogger(nameof(PutObject_Test7), putObjectSignature,
"Tests whether PutObject with unknown stream-size passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test7), putObjectSignature,
"Tests whether PutObject with unknown stream-size passes", TestStatus.FAIL, DateTime.Now - startTime,
"", ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Test8(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "application/octet-stream";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "data", "0B" },
{ "size", "-1" }
};
try
{
// Putobject call where unknown stream sent 0 bytes.
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(0))
{
long size = -1;
var file_write_size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(size)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var rmArgs = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectAsync(rmArgs).ConfigureAwait(false);
}
new MintLogger(nameof(PutObject_Test8), putObjectSignature,
"Tests PutObject where unknown stream sends 0 bytes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test8), putObjectSignature,
"Tests PutObject where unknown stream sends 0 bytes", TestStatus.FAIL, DateTime.Now - startTime, "",
ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Test9(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "application/octet-stream";
var percentage = 0;
var totalBytesTransferred = 0L;
var progress = new Progress<ProgressReport>(progressReport =>
{
percentage = progressReport.Percentage;
totalBytesTransferred = progressReport.TotalBytesTransferred;
});
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "size", "1MB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
rsg.GenerateStreamFromSeed(1 * MB), progress).ConfigureAwait(false);
Assert.IsTrue(percentage == 100);
Assert.IsTrue(totalBytesTransferred == 1 * MB);
new MintLogger(nameof(PutObject_Test9), putObjectSignature,
"Tests whether PutObject with progress passes for small object", TestStatus.PASS,
DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test9), putObjectSignature,
"Tests whether PutObject with progress passes for small object", TestStatus.FAIL,
DateTime.Now - startTime, "",
ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PutObject_Test10(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "binary/octet-stream";
var percentage = 0;
var totalBytesTransferred = 0L;
var progress = new Progress<ProgressReport>(progressReport =>
{
percentage = progressReport.Percentage;
totalBytesTransferred = progressReport.TotalBytesTransferred;
//Console.WriteLine(
// $"Percentage: {progressReport.Percentage}% TotalBytesTransferred: {progressReport.TotalBytesTransferred} bytes");
//if (progressReport.Percentage != 100)
// Console.SetCursorPosition(0, Console.CursorTop - 1);
//else Console.WriteLine();
});
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "size", "64MB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
rsg.GenerateStreamFromSeed(64 * MB), progress).ConfigureAwait(false);
Assert.IsTrue(percentage == 100);
Assert.IsTrue(totalBytesTransferred == 64 * MB);
new MintLogger(nameof(PutObject_Test10), putObjectSignature,
"Tests whether multipart PutObject with progress passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(PutObject_Test10), putObjectSignature,
"Tests whether multipart PutObject with progress passes", TestStatus.FAIL, DateTime.Now - startTime, "",
ex.Message, ex.ToString(), args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Copy Object
internal static async Task CopyObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-CopyObject_Test1";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
// .WithHeaders(null);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
File.Delete(outFileName);
var rmArgs1 = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectAsync(rmArgs1).ConfigureAwait(false);
new MintLogger("CopyObject_Test1", copyObjectSignature, "Tests whether CopyObject passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test1", copyObjectSignature, "Tests whether CopyObject passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
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);
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithHeaders(null);
_ = 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,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
try
{
var conditions = new CopyConditions();
conditions.SetMatchETag("TestETag");
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCopyConditions(conditions);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
}
catch (MinioException ex)
{
if (ex.Message.Contains(
"MinIO API responded with message=At least one of the pre-conditions you specified did not hold",
StringComparison.OrdinalIgnoreCase))
{
new MintLogger(nameof(CopyObject_Test2), copyObjectSignature,
"Tests whether CopyObject 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,
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,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-CopyObject_Test3";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// 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))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
var conditions = new CopyConditions();
conditions.SetMatchETag(stats.ETag);
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCopyConditions(conditions);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
statObjectArgs = new StatObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName);
var dstats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsNotNull(dstats);
Assert.IsTrue(dstats.ObjectName.Contains(destObjectName, StringComparison.Ordinal));
new MintLogger("CopyObject_Test3", copyObjectSignature, "Tests whether CopyObject with Etag match passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test3", copyObjectSignature, "Tests whether CopyObject with Etag match passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test4(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var outFileName = "outFileName-CopyObject_Test4";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// Test if objectName is defaulted to source objectName
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var conditions = new CopyConditions();
conditions.SetMatchETag("TestETag");
// omit dest bucket name.
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
var statObjectArgs = new StatObjectArgs()
.WithBucket(destBucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsNotNull(stats);
Assert.IsTrue(stats.ObjectName.Contains(objectName, StringComparison.Ordinal));
new MintLogger("CopyObject_Test4", copyObjectSignature,
"Tests whether CopyObject defaults targetName to objectName", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test4", copyObjectSignature,
"Tests whether CopyObject defaults targetName to objectName", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test5(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "6MB" },
{ "size", "6MB" }
};
try
{
// Test if multi-part copy upload for large files works as expected.
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(6 * MB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var conditions = new CopyConditions();
conditions.SetByteRange(1024, 6291455);
// omit dest object name.
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCopyConditions(conditions);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var statObjectArgs = new StatObjectArgs()
.WithBucket(destBucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsNotNull(stats);
Assert.IsTrue(stats.ObjectName.Contains(objectName, StringComparison.Ordinal));
Assert.AreEqual(6291455 - 1024 + 1, stats.Size);
new MintLogger("CopyObject_Test5", copyObjectSignature,
"Tests whether CopyObject multi-part copy upload for large files works", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger("CopyObject_Test5", copyObjectSignature,
"Tests whether CopyObject multi-part copy upload for large files works", TestStatus.NA,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test5", copyObjectSignature,
"Tests whether CopyObject multi-part copy upload for large files works", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
// File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test6(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-CopyObject_Test6";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// 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))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
var conditions = new CopyConditions();
conditions.SetModified(new DateTime(2017, 8, 18));
// Should copy object since modification date header < object modification date.
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCopyConditions(conditions);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
statObjectArgs = new StatObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName);
var dstats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsNotNull(dstats);
Assert.IsTrue(dstats.ObjectName.Contains(destObjectName, StringComparison.Ordinal));
new MintLogger("CopyObject_Test6", copyObjectSignature,
"Tests whether CopyObject with positive test for modified date passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test6", copyObjectSignature,
"Tests whether CopyObject with positive test for modified date passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test7(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// 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))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
var conditions = new CopyConditions();
var modifiedDate = DateTime.Now;
modifiedDate = modifiedDate.AddDays(5);
conditions.SetModified(modifiedDate);
// Should not copy object since modification date header > object modification date.
try
{
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCopyConditions(conditions);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
}
catch (Exception ex)
{
Assert.AreEqual(
"MinIO API responded with message=At least one of the pre-conditions you specified did not hold",
ex.Message);
}
new MintLogger("CopyObject_Test7", copyObjectSignature,
"Tests whether CopyObject with negative test for modified date passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test7", copyObjectSignature,
"Tests whether CopyObject with negative test for modified date passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test8(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" },
{ "copyconditions", "x-amz-metadata-directive:REPLACE" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithHeaders(new Dictionary<string, string>(StringComparer.Ordinal)
{
{ "Orig", "orig-val with spaces" }
});
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsTrue(stats.MetaData["Orig"] is not null);
var copyCond = new CopyConditions();
copyCond.SetReplaceMetadataDirective();
// set custom metadata
var customMetadata = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "Content-Type", "application/css" },
{ "Mynewkey", "test test" },
{ "Orig", "orig-valwithoutspaces" }
};
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCopyConditions(copyCond);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithHeaders(customMetadata);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
statObjectArgs = new StatObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName);
var dstats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
Assert.IsTrue(dstats.MetaData["Content-Type"] is not null);
Assert.IsTrue(dstats.MetaData["Mynewkey"] is not null);
Assert.IsTrue(dstats.MetaData["Content-Type"]
.Contains("application/css", StringComparison.OrdinalIgnoreCase));
Assert.IsTrue(dstats.MetaData["Mynewkey"].Contains("test test", StringComparison.Ordinal));
new MintLogger("CopyObject_Test8", copyObjectSignature,
"Tests whether CopyObject with metadata replacement passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test8", copyObjectSignature,
"Tests whether CopyObject with metadata replacement passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task CopyObject_Test9(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-CopyObject_Test9";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var putTags = new Dictionary<string, string>
(StringComparer.Ordinal) { { "key1", "PutObjectTags" } };
var setObjectTagsArgs = new SetObjectTagsArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithTagging(Tagging.GetObjectTags(putTags));
await minio.SetObjectTagsAsync(setObjectTagsArgs).ConfigureAwait(false);
}
var copyTags = new Dictionary<string, string>
(StringComparer.Ordinal) { { "key1", "CopyObjectTags" } };
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
// CopyObject test to replace original tags
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithTagging(Tagging.GetObjectTags(copyTags))
.WithReplaceTagsDirective(true);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectTagsArgs = new GetObjectTagsArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName);
var tags = await minio.GetObjectTagsAsync(getObjectTagsArgs).ConfigureAwait(false);
Assert.IsNotNull(tags);
var copiedTags = tags.Tags;
Assert.IsNotNull(tags);
Assert.IsNotNull(copiedTags);
Assert.IsTrue(copiedTags.Count > 0);
Assert.IsNotNull(copiedTags["key1"]);
Assert.IsTrue(copiedTags["key1"].Contains("CopyObjectTags", StringComparison.Ordinal));
new MintLogger("CopyObject_Test9", copyObjectSignature, "Tests whether CopyObject passes", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("CopyObject_Test9", copyObjectSignature, "Tests whether CopyObject passes", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
#endregion
#region Encrypted Copy Object
internal static async Task EncryptedCopyObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-EncryptedCopyObject_Test1";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// Test Copy with SSE-C -> SSE-C encryption
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using var aesEncryption = Aes.Create();
aesEncryption.KeySize = 256;
aesEncryption.GenerateKey();
var ssec = new SSEC(aesEncryption.Key);
var sseCpy = new SSECopy(aesEncryption.Key);
using var destAesEncryption = Aes.Create();
destAesEncryption.KeySize = 256;
destAesEncryption.GenerateKey();
var ssecDst = new SSEC(destAesEncryption.Key);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithServerSideEncryption(ssec);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(sseCpy);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithServerSideEncryption(ssecDst);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithServerSideEncryption(ssecDst)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
new MintLogger("EncryptedCopyObject_Test1", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.PASS, DateTime.Now - startTime, args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger("EncryptedCopyObject_Test1", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger("EncryptedCopyObject_Test1", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task EncryptedCopyObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-EncryptedCopyObject_Test2";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// Test Copy of SSE-C encrypted object to unencrypted on destination side
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using var aesEncryption = Aes.Create();
aesEncryption.KeySize = 256;
aesEncryption.GenerateKey();
var ssec = new SSEC(aesEncryption.Key);
var sseCpy = new SSECopy(aesEncryption.Key);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithServerSideEncryption(ssec);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(sseCpy);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithServerSideEncryption(null);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
new MintLogger("EncryptedCopyObject_Test2", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.PASS, DateTime.Now - startTime, args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger("EncryptedCopyObject_Test2", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger("EncryptedCopyObject_Test2", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task EncryptedCopyObject_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-EncryptedCopyObject_Test3";
var args = new Dictionary<string, string>(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// Test Copy of SSE-C encrypted object to unencrypted on destination side
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using var aesEncryption = Aes.Create();
aesEncryption.KeySize = 256;
aesEncryption.GenerateKey();
var ssec = new SSEC(aesEncryption.Key);
var sseCpy = new SSECopy(aesEncryption.Key);
var sses3 = new SSES3();
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithServerSideEncryption(ssec);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(sseCpy);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithServerSideEncryption(sses3);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
new MintLogger("EncryptedCopyObject_Test3", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.PASS, DateTime.Now - startTime, args: args)
.Log();
}
catch (Exception ex)
{
new MintLogger("EncryptedCopyObject_Test3", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
internal static async Task EncryptedCopyObject_Test4(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var outFileName = "outFileName-EncryptedCopyObject_Test4";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
};
try
{
// Test Copy of SSE-S3 encrypted object to SSE-S3 on destination side
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
var sses3 = new SSES3();
var sseDest = new SSES3();
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithServerSideEncryption(sses3);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var copySourceObjectArgs = new CopySourceObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(null);
var copyObjectArgs = new CopyObjectArgs()
.WithCopyObjectSource(copySourceObjectArgs)
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithServerSideEncryption(sses3);
await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
new MintLogger("EncryptedCopyObject_Test4", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.PASS, DateTime.Now - startTime, args: args)
.Log();
}
catch (Exception ex)
{
new MintLogger("EncryptedCopyObject_Test4", copyObjectSignature,
"Tests whether encrypted CopyObject passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
}
}
#endregion
#region Get Object
internal static async Task GetObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
string contentType = null;
var tempFileName = "tempFile-" + GetRandomName();
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "contentType", contentType }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * MB))
{
var file_write_size = filestream.Length;
long file_read_size = 0;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCallbackStream(async (stream, cancellationToken) =>
{
var fileStream = File.Create(tempFileName);
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
await fileStream.DisposeAsync().ConfigureAwait(false);
var writtenInfo = new FileInfo(tempFileName);
file_read_size = writtenInfo.Length;
Assert.AreEqual(file_write_size, file_read_size);
File.Delete(tempFileName);
});
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
}
await Task.Delay(1000).ConfigureAwait(false);
new MintLogger("GetObject_Test1", getObjectSignature, "Tests whether GetObject as stream works",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("GetObject_Test1", getObjectSignature, "Tests whether GetObject as stream works",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
if (File.Exists(tempFileName))
File.Delete(tempFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task GetObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var fileName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "fileName", fileName }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var filestream = rsg.GenerateStreamFromSeed(1 * MB);
// long file_write_size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
catch (Exception ex)
{
new MintLogger("GetObject_Test2", getObjectSignature, "Test setup for GetObject with a filename",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
try
{
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithFile(fileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
Assert.IsTrue(File.Exists(fileName));
new MintLogger("GetObject_Test2", getObjectSignature, "Tests whether GetObject with a file name works",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (ObjectNotFoundException)
{
new MintLogger("GetObject_Test2", getObjectSignature, "Tests for GetObject with a file name",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (InvalidOperationException ex)
{
new MintLogger("GetObject_Test2", getObjectSignature, "Tests for GetObject with a file name",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
catch (Exception ex)
{
new MintLogger("GetObject_Test2", getObjectSignature, "Tests for GetObject with a file name",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
if (File.Exists(fileName))
File.Delete(fileName);
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
// and length parameters. Tests will be reported as GetObject_Test3,
// GetObject_Test4 and GetObject_Test5.
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
string contentType = null;
var tempFileName = "tempFile-" + GetRandomName();
var tempSource = "tempSourceFile-" + GetRandomName();
var offsetLengthTests = new Dictionary<string, List<int>>
(StringComparer.Ordinal)
{
// list is {offset, length} values
{ "GetObject_Test3", new List<int> { 14, 20 } },
{ "GetObject_Test4", new List<int> { 30, 0 } },
{ "GetObject_Test5", new List<int> { 0, 25 } }
};
foreach (var test in offsetLengthTests)
{
var testName = test.Key;
var offsetToStartFrom = test.Value[0];
var lengthToBeRead = test.Value[1];
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "contentType", contentType },
{ "offset", offsetToStartFrom.ToString(CultureInfo.InvariantCulture) },
{ "length", lengthToBeRead.ToString(CultureInfo.InvariantCulture) }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
// Create a file with distintc byte characters to test partial
// get object.
var line = new[] { "abcdefghijklmnopqrstuvwxyz0123456789" };
// abcdefghijklmnopqrstuvwxyz0123456789
// 012345678911234567892123456789312345
// ^1stChr, ^10thChr, ^20thChr, ^30th ^35thChr => characters' sequence
// Example: offset 10 and length 4, the expected size and content
// getObjectAsync will return are 4 and "klmn" respectively.
#if NETFRAMEWORK
File.WriteAllLines(tempSource, line);
#else
await File.WriteAllLinesAsync(tempSource, line).ConfigureAwait(false);
#endif
using (var filestream = File.Open(tempSource, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var objectSize = (int)filestream.Length;
var expectedFileSize = lengthToBeRead;
var expectedContent = string.Concat(line).Substring(offsetToStartFrom, expectedFileSize);
if (lengthToBeRead == 0)
{
expectedFileSize = objectSize - offsetToStartFrom;
var noOfCtrlChars = 1;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) noOfCtrlChars = 2;
expectedContent = string.Concat(line)
.Substring(offsetToStartFrom, expectedFileSize - noOfCtrlChars);
}
long actualFileSize;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(objectSize)
.WithContentType(contentType);
await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithOffsetAndLength(offsetToStartFrom, lengthToBeRead)
.WithCallbackStream(async (stream, cancellationToken) =>
{
var fileStream = File.Create(tempFileName);
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
await fileStream.DisposeAsync().ConfigureAwait(false);
var writtenInfo = new FileInfo(tempFileName);
actualFileSize = writtenInfo.Length;
Assert.AreEqual(expectedFileSize, actualFileSize);
// Checking the content
#if NETFRAMEWORK
var actualContent = File.ReadAllText(tempFileName);
#else
var actualContent = await File.ReadAllTextAsync(tempFileName, cancellationToken)
.ConfigureAwait(false);
#endif
actualContent = actualContent.Replace("\n", "", StringComparison.Ordinal)
.Replace("\r", "", StringComparison.Ordinal);
Assert.AreEqual(actualContent, expectedContent);
});
await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
}
new MintLogger(testName, getObjectSignature, "Tests whether GetObject returns all the data",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
if (File.Exists(tempFileName)) File.Delete(tempFileName);
if (File.Exists(tempSource)) File.Delete(tempSource);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
new MintLogger(testName, getObjectSignature, "Tests whether GetObject returns all the data",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
if (File.Exists(tempFileName)) File.Delete(tempFileName);
if (File.Exists(tempSource)) File.Delete(tempSource);
await TearDown(minio, bucketName).ConfigureAwait(false);
throw;
}
}
}
#if NET6_0_OR_GREATER
internal static async Task GetObject_AsyncCallback_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
string contentType = null;
var fileName = GetRandomName(10);
var destFileName = GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "contentType", contentType }
};
try
{
// Create a local 500MB file
GenerateRandom500MB_File(fileName);
// Create the bucket
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var file = File.OpenHandle(fileName);
using var filestream = new FileStream(file, FileAccess.Read);
// Upload the large file, "fileName", into the bucket
var size = filestream.Length;
long file_read_size = 0;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
async Task callbackAsync(Stream stream, CancellationToken cancellationToken)
{
var dest = new FileStream(destFileName, FileMode.Create, FileAccess.Write);
await stream.CopyToAsync(dest, cancellationToken).ConfigureAwait(false);
await dest.DisposeAsync().ConfigureAwait(false);
}
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCallbackStream(async (stream, cancellationToken) =>
await callbackAsync(stream, cancellationToken).ConfigureAwait(false));
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
var writtenInfo = new FileInfo(destFileName);
file_read_size = writtenInfo.Length;
Assert.AreEqual(size, file_read_size);
new MintLogger("GetObject_AsyncCallback_Test1", getObjectSignature,
"Tests whether GetObject as stream works",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("GetObject_AsyncCallback_Test1", getObjectSignature,
"Tests whether GetObject as stream works",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
if (File.Exists(fileName))
File.Delete(fileName);
if (File.Exists(destFileName))
File.Delete(destFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endif
internal static async Task FGetObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var outFileName = "outFileName-FGetObject_Test1";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "fileName", outFileName }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var getObjectArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithFile(outFileName);
_ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
new MintLogger("FGetObject_Test1", getObjectSignature, "Tests whether FGetObject passes for small upload",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("FGetObject_Test1", getObjectSignature, "Tests whether FGetObject passes for small upload",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(outFileName);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region List Objects
internal static async Task ListObjects_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var prefix = "minix";
var objectName = prefix + GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "prefix", prefix },
{ "recursive", "false" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var tasks = new Task[2];
for (var i = 0; i < 2; i++)
tasks[i] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(1));
await Task.WhenAll(tasks).ConfigureAwait(false);
await ListObjects_Test(minio, bucketName, prefix, 2, false).ConfigureAwait(false);
await Task.Delay(2000).ConfigureAwait(false);
new MintLogger("ListObjects_Test1", listObjectsSignature,
"Tests whether ListObjects lists all objects matching a prefix non-recursive", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListObjects_Test1", listObjectsSignature,
"Tests whether ListObjects lists all objects matching a prefix non-recursive", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListObjects_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await ListObjects_Test(minio, bucketName, null, 0).ConfigureAwait(false);
await Task.Delay(2000).ConfigureAwait(false);
new MintLogger("ListObjects_Test2", listObjectsSignature,
"Tests whether ListObjects passes when bucket is empty", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListObjects_Test2", listObjectsSignature,
"Tests whether ListObjects passes when bucket is empty", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListObjects_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var prefix = "minix";
var objectName = prefix + "/" + GetRandomName(10) + "/suffix";
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "prefix", prefix },
{ "recursive", "true" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var tasks = new Task[2];
for (var i = 0; i < 2; i++)
tasks[i] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(1 * KB));
await Task.WhenAll(tasks).ConfigureAwait(false);
await ListObjects_Test(minio, bucketName, prefix, 2).ConfigureAwait(false);
await Task.Delay(2000).ConfigureAwait(false);
new MintLogger("ListObjects_Test3", listObjectsSignature,
"Tests whether ListObjects lists all objects matching a prefix and recursive", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListObjects_Test3", listObjectsSignature,
"Tests whether ListObjects lists all objects matching a prefix and recursive", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListObjects_Test4(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectName }, { "recursive", "false" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var tasks = new Task[2];
for (var i = 0; i < 2; i++)
tasks[i] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(1 * KB));
await Task.WhenAll(tasks).ConfigureAwait(false);
await ListObjects_Test(minio, bucketName, "", 2, false).ConfigureAwait(false);
await Task.Delay(2000).ConfigureAwait(false);
new MintLogger("ListObjects_Test4", listObjectsSignature,
"Tests whether ListObjects lists all objects when no prefix is specified", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListObjects_Test4", listObjectsSignature,
"Tests whether ListObjects lists all objects when no prefix is specified", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListObjects_Test5(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectNamePrefix = GetRandomName(10);
var numObjects = 100;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectNamePrefix }, { "recursive", "false" }
};
var objectNames = new List<string>();
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var tasks = new Task[numObjects];
for (var i = 1; i <= numObjects; i++)
{
var objName = objectNamePrefix + i;
tasks[i - 1] = PutObject_Task(minio, bucketName, objName, null, null, 0, null,
rsg.GenerateStreamFromSeed(1));
objectNames.Add(objName);
// Add sleep to avoid flooding server with concurrent requests
if (i % 50 == 0)
await Task.Delay(2000).ConfigureAwait(false);
}
await Task.WhenAll(tasks).ConfigureAwait(false);
await ListObjects_Test(minio, bucketName, objectNamePrefix, numObjects, false).ConfigureAwait(false);
await Task.Delay(5000).ConfigureAwait(false);
new MintLogger("ListObjects_Test5", listObjectsSignature,
"Tests whether ListObjects lists all objects when number of objects == 100", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListObjects_Test5", listObjectsSignature,
"Tests whether ListObjects lists all objects when number of objects == 100", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListObjects_Test6(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectNamePrefix = GetRandomName(10);
var numObjects = 1015;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectName", objectNamePrefix }, { "recursive", "false" }
};
var objectNamesSet = new HashSet<string>(StringComparer.Ordinal);
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var tasks = new Task[numObjects];
for (var i = 1; i <= numObjects; i++)
{
var obj = objectNamePrefix + i;
tasks[i - 1] = PutObject_Task(minio, bucketName, obj, null, null, 0, null,
rsg.GenerateStreamFromSeed(1));
// Add sleep to avoid flooding server with concurrent requests
if (i % 25 == 0)
await Task.Delay(2000).ConfigureAwait(false);
}
await Task.WhenAll(tasks).ConfigureAwait(false);
var count = 0;
var listArgs = new ListObjectsArgs()
.WithBucket(bucketName)
.WithPrefix(objectNamePrefix)
.WithRecursive(false)
.WithVersions(false);
var observable = minio.ListObjectsAsync(listArgs);
var subscription = observable.Subscribe(
item =>
{
Assert.IsTrue(item.Key.StartsWith(objectNamePrefix, StringComparison.OrdinalIgnoreCase));
if (!objectNamesSet.Add(item.Key))
new MintLogger("ListObjects_Test6", listObjectsSignature,
"Tests whether ListObjects lists more than 1000 objects correctly(max-keys = 1000)",
TestStatus.FAIL, DateTime.Now - startTime,
"Failed to add. Object already exists: " + item.Key, "", args: args).Log();
count++;
},
ex => throw ex,
() => Assert.AreEqual(count, numObjects));
await Task.Delay(3500).ConfigureAwait(false);
new MintLogger("ListObjects_Test6", listObjectsSignature,
"Tests whether ListObjects lists more than 1000 objects correctly(max-keys = 1000)", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListObjects_Test6", listObjectsSignature,
"Tests whether ListObjects lists more than 1000 objects correctly(max-keys = 1000)", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListObjectVersions_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var prefix = "minix";
var objectName = prefix + GetRandomName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "prefix", prefix },
{ "recursive", "false" },
{ "versions", "true" }
};
var objectVersions = new List<Tuple<string, string>>();
try
{
await Setup_WithLock_Test(minio, bucketName).ConfigureAwait(false);
var tasks = new Task[8];
for (int i = 0, taskIdx = 0; i < 4; i++)
{
tasks[taskIdx++] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(1));
tasks[taskIdx++] = PutObject_Task(minio, bucketName, objectName + i, null, null, 0, null,
rsg.GenerateStreamFromSeed(1));
}
await Task.WhenAll(tasks).ConfigureAwait(false);
await ListObjects_Test(minio, bucketName, prefix, 2, false, true).ConfigureAwait(false);
await Task.Delay(2000).ConfigureAwait(false);
var listObjectsArgs = new ListObjectsArgs()
.WithBucket(bucketName)
.WithRecursive(true)
.WithVersions(true);
var count = 0;
var numObjectVersions = 8;
var observable = minio.ListObjectsAsync(listObjectsArgs);
var subscription = observable.Subscribe(
item =>
{
Assert.IsTrue(item.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
count++;
objectVersions.Add(new Tuple<string, string>(item.Key, item.VersionId));
},
ex => throw ex,
() => Assert.AreEqual(count, numObjectVersions));
await Task.Delay(4000).ConfigureAwait(false);
new MintLogger("ListObjectVersions_Test1", listObjectsSignature,
"Tests whether ListObjects with versions lists all objects along with all version ids for each object matching a prefix non-recursive",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListObjectVersions_Test1", listObjectsSignature,
"Tests whether ListObjects with versions lists all objects along with all version ids for each object matching a prefix non-recursive",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListObjects_Test(IMinioClient minio, string bucketName, string prefix, int numObjects,
bool recursive = true, bool versions = false, Dictionary<string, string> headers = null)
{
var startTime = DateTime.Now;
var count = 0;
var args = new ListObjectsArgs()
.WithBucket(bucketName)
.WithPrefix(prefix)
.WithHeaders(headers)
.WithRecursive(recursive)
.WithVersions(versions);
if (!versions)
{
var observable = minio.ListObjectsAsync(args);
var subscription = observable.Subscribe(
item =>
{
if (!string.IsNullOrEmpty(prefix))
Assert.IsTrue(item.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
count++;
},
ex => throw ex,
() => { });
}
else
{
var observable = minio.ListObjectsAsync(args);
var subscription = observable.Subscribe(
item =>
{
Assert.IsTrue(item.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
count++;
},
ex => throw ex,
() => { });
}
await Task.Delay(40000).ConfigureAwait(false);
Assert.AreEqual(numObjects, count);
}
#endregion
#region Presigned Get Object
internal static async Task PresignedGetObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var expiresInt = 1000;
var downloadFile = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "expiresInt", expiresInt.ToString(CultureInfo.InvariantCulture) }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
var preArgs = new PresignedGetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(expiresInt);
var presigned_url = await minio.PresignedGetObjectAsync(preArgs).ConfigureAwait(false);
await DownloadObjectAsync(minio, presigned_url, downloadFile).ConfigureAwait(false);
var writtenInfo = new FileInfo(downloadFile);
var file_read_size = writtenInfo.Length;
// Compare the size of the file downloaded using the generated
// presigned_url (expected value) and the actual object size on the server
Assert.AreEqual(file_read_size, stats.Size);
new MintLogger("PresignedGetObject_Test1", presignedGetObjectSignature,
"Tests whether PresignedGetObject url retrieves object from bucket", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("PresignedGetObject_Test1", presignedGetObjectSignature,
"Tests whether PresignedGetObject url retrieves object from bucket", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(downloadFile);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PresignedGetObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var expiresInt = 0;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "expiresInt", expiresInt.ToString(CultureInfo.InvariantCulture) }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
var preArgs = new PresignedGetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(0);
var presigned_url = await minio.PresignedGetObjectAsync(preArgs).ConfigureAwait(false);
throw new InvalidOperationException(
"PresignedGetObjectAsync expected to throw an InvalidExpiryRangeException.");
}
catch (InvalidExpiryRangeException)
{
new MintLogger("PresignedGetObject_Test2", presignedGetObjectSignature,
"Tests whether PresignedGetObject url retrieves object from bucket when invalid expiry is set.",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (InvalidOperationException ex)
{
new MintLogger("PresignedGetObject_Test2", presignedGetObjectSignature,
"Tests whether PresignedGetObject url retrieves object from bucket when invalid expiry is set.",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
catch (Exception ex)
{
new MintLogger("PresignedGetObject_Test2", presignedGetObjectSignature,
"Tests whether PresignedGetObject url retrieves object from bucket when invalid expiry is set.",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task PresignedGetObject_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var expiresInt = 1000;
var reqDate = DateTime.UtcNow.AddSeconds(-50);
var downloadFile = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "expiresInt", expiresInt.ToString(CultureInfo.InvariantCulture) },
{
"reqParams",
"response-content-type:application/json,response-content-disposition:attachment;filename= MyDoc u m e nt.json ;"
},
{ "reqDate", reqDate.ToString(CultureInfo.InvariantCulture) }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
var reqParams = new Dictionary<string, string>
(StringComparer.Ordinal)
{
["response-content-type"] = "application/json",
["response-content-disposition"] = "attachment;filename= MyDoc u m e nt.json ;"
};
var preArgs = new PresignedGetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(1000)
.WithHeaders(reqParams)
.WithRequestDate(reqDate);
var presigned_url = await minio.PresignedGetObjectAsync(preArgs).ConfigureAwait(false);
using var response = await minio.WrapperGetAsync(presigned_url).ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK ||
string.IsNullOrEmpty(Convert.ToString(response.Content, CultureInfo.InvariantCulture)))
throw new InvalidOperationException("Unable to download via presigned URL " + nameof(response.Content));
Assert.IsTrue(response.Content.Headers.GetValues("Content-Type")
.Contains(reqParams["response-content-type"], StringComparer.Ordinal));
Assert.IsTrue(response.Content.Headers.GetValues("Content-Disposition")
.Contains(reqParams["response-content-disposition"], StringComparer.Ordinal));
Assert.IsTrue(response.Content.Headers.GetValues("Content-Length")
.Contains(stats.Size.ToString(CultureInfo.InvariantCulture), StringComparer.Ordinal));
using (var fs = new FileStream(downloadFile, FileMode.CreateNew))
{
await response.Content.CopyToAsync(fs).ConfigureAwait(false);
}
var writtenInfo = new FileInfo(downloadFile);
var file_read_size = writtenInfo.Length;
// Compare the size of the file downloaded with the generated
// presigned_url (expected) and the actual object size on the server
Assert.AreEqual(file_read_size, stats.Size);
new MintLogger("PresignedGetObject_Test3", presignedGetObjectSignature,
"Tests whether PresignedGetObject url retrieves object from bucket when override response headers sent",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("PresignedGetObject_Test3", presignedGetObjectSignature,
"Tests whether PresignedGetObject url retrieves object from bucket when override response headers sent",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
File.Delete(downloadFile);
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Presigned Put Object
internal static async Task PresignedPutObject_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var expiresInt = 1000;
var fileName = CreateFile(10 * KB, dataFile10KB);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "expiresInt", expiresInt.ToString(CultureInfo.InvariantCulture) }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
// Upload with presigned url
var presignedPutObjectArgs = new PresignedPutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(1000);
var presigned_url = await minio.PresignedPutObjectAsync(presignedPutObjectArgs).ConfigureAwait(false);
await UploadObjectAsync(minio, presigned_url, fileName).ConfigureAwait(false);
// Get stats for object from server
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
// Compare with file used for upload
var writtenInfo = new FileInfo(fileName);
var file_written_size = writtenInfo.Length;
Assert.AreEqual(file_written_size, stats.Size);
new MintLogger("PresignedPutObject_Test1", presignedPutObjectSignature,
"Tests whether PresignedPutObject url uploads object to bucket", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("PresignedPutObject_Test1", presignedPutObjectSignature,
"Tests whether PresignedPutObject url uploads object to bucket", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
if (!IsMintEnv()) File.Delete(fileName);
}
}
internal static async Task PresignedPutObject_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var expiresInt = 0;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName },
{ "objectName", objectName },
{ "expiresInt", expiresInt.ToString(CultureInfo.InvariantCulture) }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
var stats = await minio.StatObjectAsync(statObjectArgs).ConfigureAwait(false);
var presignedPutObjectArgs = new PresignedPutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(0);
var presigned_url = await minio.PresignedPutObjectAsync(presignedPutObjectArgs).ConfigureAwait(false);
new MintLogger("PresignedPutObject_Test2", presignedPutObjectSignature,
"Tests whether PresignedPutObject url retrieves object from bucket when invalid expiry is set.",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (InvalidExpiryRangeException)
{
new MintLogger("PresignedPutObject_Test2", presignedPutObjectSignature,
"Tests whether PresignedPutObject url retrieves object from bucket when invalid expiry is set.",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("PresignedPutObject_Test2", presignedPutObjectSignature,
"Tests whether PresignedPutObject url retrieves object from bucket when invalid expiry is set.",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region List Incomplete Upload
internal static async Task ListIncompleteUpload_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var contentType = "gzip";
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "recursive", "true" } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMilliseconds(15));
try
{
using var filestream = rsg.GenerateStreamFromSeed(50 * MB);
var file_write_size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs, cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
var listArgs = new ListIncompleteUploadsArgs()
.WithBucket(bucketName);
var observable = minio.ListIncompleteUploads(listArgs);
var subscription = observable.Subscribe(
item => Assert.IsTrue(item.Key.Contains(objectName, StringComparison.Ordinal)),
ex => Assert.Fail());
}
catch (Exception ex)
{
new MintLogger("ListIncompleteUpload_Test1", listIncompleteUploadsSignature,
"Tests whether ListIncompleteUpload passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString()).Log();
return;
}
new MintLogger("ListIncompleteUpload_Test1", listIncompleteUploadsSignature,
"Tests whether ListIncompleteUpload passes", TestStatus.PASS, DateTime.Now - startTime).Log();
}
catch (Exception ex)
{
new MintLogger("ListIncompleteUpload_Test1", listIncompleteUploadsSignature,
"Tests whether ListIncompleteUpload passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString()).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListIncompleteUpload_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var prefix = "minioprefix/";
var objectName = prefix + GetRandomName(10);
var contentType = "gzip";
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "prefix", prefix }, { "recursive", "false" } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMilliseconds(15));
try
{
using var filestream = rsg.GenerateStreamFromSeed(50 * MB);
var file_write_size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs, cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
var listArgs = new ListIncompleteUploadsArgs()
.WithBucket(bucketName)
.WithPrefix("minioprefix")
.WithRecursive(false);
var observable = minio.ListIncompleteUploads(listArgs);
var subscription = observable.Subscribe(
item => Assert.AreEqual(item.Key, objectName),
ex => Assert.Fail());
}
new MintLogger("ListIncompleteUpload_Test2", listIncompleteUploadsSignature,
"Tests whether ListIncompleteUpload passes when qualified by prefix", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListIncompleteUpload_Test2", listIncompleteUploadsSignature,
"Tests whether ListIncompleteUpload passes when qualified by prefix", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task ListIncompleteUpload_Test3(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var prefix = "minioprefix";
var objectName = prefix + "/" + GetRandomName(10) + "/suffix";
var contentType = "gzip";
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName }, { "prefix", prefix }, { "recursive", "true" } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMilliseconds(15));
try
{
using var filestream = rsg.GenerateStreamFromSeed(100 * MB);
var file_write_size = filestream.Length;
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs, cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
var listArgs = new ListIncompleteUploadsArgs()
.WithBucket(bucketName)
.WithPrefix(prefix)
.WithRecursive(true);
var observable = minio.ListIncompleteUploads(listArgs);
var subscription = observable.Subscribe(
item => Assert.AreEqual(item.Key, objectName),
ex => Assert.Fail());
}
new MintLogger("ListIncompleteUpload_Test3", listIncompleteUploadsSignature,
"Tests whether ListIncompleteUpload passes when qualified by prefix and recursive", TestStatus.PASS,
DateTime.Now - startTime, args: args).Log();
}
catch (Exception ex)
{
new MintLogger("ListIncompleteUpload_Test3", listIncompleteUploadsSignature,
"Tests whether ListIncompleteUpload passes when qualified by prefix and recursive", TestStatus.FAIL,
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Bucket Policy
/// <summary>
/// Set a policy for given bucket
/// </summary>
/// <param name="minio"></param>
/// <returns></returns>
internal static async Task SetBucketPolicy_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
{ "bucketName", bucketName }, { "objectPrefix", objectName[5..] }, { "policyType", "readonly" }
};
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var policyJson =
$@"{{""Version"":""2012-10-17"",""Statement"":[{{""Action"":[""s3:GetObject""],""Effect"":""Allow"",""Principal"":{{""AWS"":[""*""]}},""Resource"":[""arn:aws:s3:::{bucketName}/foo*"",""arn:aws:s3:::{bucketName}/prefix/*""],""Sid"":""""}}]}}";
var setPolicyArgs = new SetPolicyArgs()
.WithBucket(bucketName)
.WithPolicy(policyJson);
await minio.SetPolicyAsync(setPolicyArgs).ConfigureAwait(false);
new MintLogger("SetBucketPolicy_Test1", setBucketPolicySignature, "Tests whether SetBucketPolicy passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger("SetBucketPolicy_Test1", setBucketPolicySignature, "Tests whether SetBucketPolicy passes",
TestStatus.NA, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger("SetBucketPolicy_Test1", setBucketPolicySignature, "Tests whether SetBucketPolicy passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
/// <summary>
/// Get a policy for given bucket
/// </summary>
/// <param name="minio"></param>
/// <returns></returns>
internal static async Task GetBucketPolicy_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
var policyJson =
$@"{{""Version"":""2012-10-17"",""Statement"":[{{""Action"":[""s3:GetObject""],""Effect"":""Allow"",""Principal"":{{""AWS"":[""*""]}},""Resource"":[""arn:aws:s3:::{bucketName}/foo*"",""arn:aws:s3:::{bucketName}/prefix/*""],""Sid"":""""}}]}}";
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
var setPolicyArgs = new SetPolicyArgs()
.WithBucket(bucketName)
.WithPolicy(policyJson);
var getPolicyArgs = new GetPolicyArgs()
.WithBucket(bucketName);
var rmPolicyArgs = new RemovePolicyArgs()
.WithBucket(bucketName);
await minio.SetPolicyAsync(setPolicyArgs).ConfigureAwait(false);
var policy = await minio.GetPolicyAsync(getPolicyArgs).ConfigureAwait(false);
await minio.RemovePolicyAsync(rmPolicyArgs).ConfigureAwait(false);
new MintLogger("GetBucketPolicy_Test1", getBucketPolicySignature, "Tests whether GetBucketPolicy passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
}
catch (NotImplementedException ex)
{
new MintLogger("GetBucketPolicy_Test1", getBucketPolicySignature, "Tests whether GetBucketPolicy passes",
TestStatus.NA, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger("GetBucketPolicy_Test1", getBucketPolicySignature, "Tests whether GetBucketPolicy passes",
TestStatus.FAIL, DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
throw;
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
#region Bucket Lifecycle
internal static async Task BucketLifecycleAsync_Test1(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".0", setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
var rules = new List<LifecycleRule>();
var baseDate = DateTime.Now;
var expDate = baseDate.AddYears(1);
var exp = new Expiration(expDate);
var calcDateTime = DateTime.Parse(exp.ExpiryDate, null, DateTimeStyles.RoundtripKind);
var expInDays = (calcDateTime.Date - baseDate.ToUniversalTime().Date).TotalDays;
var rule1 = new LifecycleRule(null, "txt", exp,
null, new RuleFilter(null, "txt/", null), null,
null, LifecycleRule.LifecycleRuleStatusEnabled);
rules.Add(rule1);
var lfc = new LifecycleConfiguration(rules);
try
{
var lfcArgs = new SetBucketLifecycleArgs()
.WithBucket(bucketName)
.WithLifecycleConfiguration(lfc);
await minio.SetBucketLifecycleAsync(lfcArgs).ConfigureAwait(false);
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".1", setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".1", setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".1", setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var lfcArgs = new GetBucketLifecycleArgs()
.WithBucket(bucketName);
var lfcObj = await minio.GetBucketLifecycleAsync(lfcArgs).ConfigureAwait(false);
Assert.IsNotNull(lfcObj);
Assert.IsNotNull(lfcObj.Rules);
Assert.IsTrue(lfcObj.Rules.Count > 0);
Assert.AreEqual(lfcObj.Rules.Count, lfc.Rules.Count);
var lfcDate = DateTime.Parse(lfcObj.Rules[0].Expiration.ExpiryDate, null, DateTimeStyles.RoundtripKind);
var lfcExpInDays = (lfcDate.Date - baseDate.ToUniversalTime().Date).TotalDays;
Assert.AreEqual(lfcExpInDays, expInDays);
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".2", getBucketLifecycleSignature,
"Tests whether GetBucketLifecycleAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".2", getBucketLifecycleSignature,
"Tests whether GetBucketLifecycleAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".2", getBucketLifecycleSignature,
"Tests whether GetBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var lfcArgs = new RemoveBucketLifecycleArgs()
.WithBucket(bucketName);
await minio.RemoveBucketLifecycleAsync(lfcArgs).ConfigureAwait(false);
var getLifecycleArgs = new GetBucketLifecycleArgs()
.WithBucket(bucketName);
var lfcObj = await minio.GetBucketLifecycleAsync(getLifecycleArgs).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".3", deleteBucketLifecycleSignature,
"Tests whether RemoveBucketLifecycleAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
if (ex.Message.Contains("The lifecycle configuration does not exist", StringComparison.OrdinalIgnoreCase))
{
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".3", deleteBucketLifecycleSignature,
"Tests whether RemoveBucketLifecycleAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
else
{
new MintLogger(nameof(BucketLifecycleAsync_Test1) + ".3", deleteBucketLifecycleSignature,
"Tests whether RemoveBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
internal static async Task BucketLifecycleAsync_Test2(IMinioClient minio)
{
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var args = new Dictionary<string, string>
(StringComparer.Ordinal) { { "bucketName", bucketName } };
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketLifecycleAsync_Test2), setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
var rules = new List<LifecycleRule>();
var exp = new Expiration { Days = 30 };
var rule1 = new LifecycleRule(null, "txt", exp, null,
new RuleFilter(null, "txt/", null),
null, null, LifecycleRule.LifecycleRuleStatusEnabled
);
rules.Add(rule1);
var lfc = new LifecycleConfiguration(rules);
try
{
var lfcArgs = new SetBucketLifecycleArgs()
.WithBucket(bucketName)
.WithLifecycleConfiguration(lfc);
await minio.SetBucketLifecycleAsync(lfcArgs).ConfigureAwait(false);
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".1", setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".1", setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".1", setBucketLifecycleSignature,
"Tests whether SetBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var lfcArgs = new GetBucketLifecycleArgs()
.WithBucket(bucketName);
var lfcObj = await minio.GetBucketLifecycleAsync(lfcArgs).ConfigureAwait(false);
Assert.IsNotNull(lfcObj);
Assert.IsNotNull(lfcObj.Rules);
Assert.IsTrue(lfcObj.Rules.Count > 0);
Assert.AreEqual(lfcObj.Rules.Count, lfc.Rules.Count);
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".2", getBucketLifecycleSignature,
"Tests whether GetBucketLifecycleAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args)
.Log();
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".2", getBucketLifecycleSignature,
"Tests whether GetBucketLifecycleAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".2", getBucketLifecycleSignature,
"Tests whether GetBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
throw;
}
try
{
var lfcArgs = new RemoveBucketLifecycleArgs()
.WithBucket(bucketName);
await minio.RemoveBucketLifecycleAsync(lfcArgs).ConfigureAwait(false);
var getLifecycleArgs = new GetBucketLifecycleArgs()
.WithBucket(bucketName);
var lfcObj = await minio.GetBucketLifecycleAsync(getLifecycleArgs).ConfigureAwait(false);
}
catch (NotImplementedException ex)
{
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".3", deleteBucketLifecycleSignature,
"Tests whether RemoveBucketLifecycleAsync passes", TestStatus.NA, DateTime.Now - startTime, ex.Message,
ex.ToString(), args: args).Log();
}
catch (Exception ex)
{
if (ex.Message.Contains("The lifecycle configuration does not exist", StringComparison.OrdinalIgnoreCase))
{
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".3", deleteBucketLifecycleSignature,
"Tests whether RemoveBucketLifecycleAsync passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
else
{
new MintLogger(nameof(BucketLifecycleAsync_Test2) + ".3", deleteBucketLifecycleSignature,
"Tests whether RemoveBucketLifecycleAsync passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
}
finally
{
await TearDown(minio, bucketName).ConfigureAwait(false);
}
}
#endregion
}