diff --git a/.github/workflows/dotnet_test.yml b/.github/workflows/dotnet_test.yml
index 84c57e2..f7daf84 100644
--- a/.github/workflows/dotnet_test.yml
+++ b/.github/workflows/dotnet_test.yml
@@ -14,13 +14,13 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 8.0.x
- - name: Restore dependencies
- run: dotnet restore
- - name: Build
- run: dotnet build --no-restore
+ dotnet-version: 10.0.x
- name: Test
- run: dotnet test --no-build --verbosity normal
+ run: |
+ dotnet test test/FileParty.Core.Tests/FileParty.Core.Tests.csproj --configuration Release --verbosity normal
+ dotnet test test/FileParty.Handlers.FileSystem.Tests/FileParty.Handlers.FileSystem.Tests.csproj --configuration Release --verbosity normal
+ dotnet test test/FileParty.Handlers.AWS.S3.Tests/FileParty.Handlers.AWS.S3.Tests.csproj --configuration Release-V3 --verbosity normal
+ dotnet test test/FileParty.Handlers.AWS.S3.Tests/FileParty.Handlers.AWS.S3.Tests.csproj --configuration Release-V4 --verbosity normal
env:
"fileparty_s3_region": ${{ secrets.TEST_S3_REGION }}
"fileparty_s3_bucket": ${{ secrets.TEST_S3_BUCKET }}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index bda256e..2b29ade 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -13,7 +13,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 8.0.x
+ dotnet-version: 10.0.x
- name: Build and Publish Nuget Packages
id: csharp_nuget_publish
uses: JankwareDotCom/nuget_publish@0.4.0
diff --git a/FileParty.sln b/FileParty.sln
index d0bd762..ccd1f3a 100644
--- a/FileParty.sln
+++ b/FileParty.sln
@@ -27,36 +27,58 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
+ Debug-V4|Any CPU = Debug-V4|Any CPU
+ Release-V4|Any CPU = Release-V4|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Debug-V4|Any CPU.ActiveCfg = Debug|Any CPU
+ {F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Debug-V4|Any CPU.Build.0 = Debug|Any CPU
+ {F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Release-V4|Any CPU.ActiveCfg = Release|Any CPU
+ {F4F0963C-2998-4B87-8BFD-2CF12A5ABDA4}.Release-V4|Any CPU.Build.0 = Release|Any CPU
{792B430A-5277-44B8-9284-2D0C256DF22D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{792B430A-5277-44B8-9284-2D0C256DF22D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{792B430A-5277-44B8-9284-2D0C256DF22D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{792B430A-5277-44B8-9284-2D0C256DF22D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {792B430A-5277-44B8-9284-2D0C256DF22D}.Debug-V4|Any CPU.ActiveCfg = Debug|Any CPU
+ {792B430A-5277-44B8-9284-2D0C256DF22D}.Debug-V4|Any CPU.Build.0 = Debug|Any CPU
+ {792B430A-5277-44B8-9284-2D0C256DF22D}.Release-V4|Any CPU.ActiveCfg = Release|Any CPU
+ {792B430A-5277-44B8-9284-2D0C256DF22D}.Release-V4|Any CPU.Build.0 = Release|Any CPU
{739F3D2D-5541-47A3-9C97-5329FB8583CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{739F3D2D-5541-47A3-9C97-5329FB8583CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{739F3D2D-5541-47A3-9C97-5329FB8583CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{739F3D2D-5541-47A3-9C97-5329FB8583CE}.Release|Any CPU.Build.0 = Release|Any CPU
- {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {739F3D2D-5541-47A3-9C97-5329FB8583CE}.Debug-V4|Any CPU.ActiveCfg = Debug-V4|Any CPU
+ {739F3D2D-5541-47A3-9C97-5329FB8583CE}.Debug-V4|Any CPU.Build.0 = Debug-V4|Any CPU
+ {739F3D2D-5541-47A3-9C97-5329FB8583CE}.Release-V4|Any CPU.ActiveCfg = Release-V4|Any CPU
+ {739F3D2D-5541-47A3-9C97-5329FB8583CE}.Release-V4|Any CPU.Build.0 = Release-V4|Any CPU
{C17D1DB1-7C20-413E-BC69-A0656720FA33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C17D1DB1-7C20-413E-BC69-A0656720FA33}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C17D1DB1-7C20-413E-BC69-A0656720FA33}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C17D1DB1-7C20-413E-BC69-A0656720FA33}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C17D1DB1-7C20-413E-BC69-A0656720FA33}.Debug-V4|Any CPU.ActiveCfg = Debug|Any CPU
+ {C17D1DB1-7C20-413E-BC69-A0656720FA33}.Debug-V4|Any CPU.Build.0 = Debug|Any CPU
+ {C17D1DB1-7C20-413E-BC69-A0656720FA33}.Release-V4|Any CPU.ActiveCfg = Release|Any CPU
+ {C17D1DB1-7C20-413E-BC69-A0656720FA33}.Release-V4|Any CPU.Build.0 = Release|Any CPU
{4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Release|Any CPU.Build.0 = Release|Any CPU
- {22ED881A-4D94-4A4E-B908-BD1F4CCFB026}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {22ED881A-4D94-4A4E-B908-BD1F4CCFB026}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {22ED881A-4D94-4A4E-B908-BD1F4CCFB026}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {22ED881A-4D94-4A4E-B908-BD1F4CCFB026}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Debug-V4|Any CPU.ActiveCfg = Debug|Any CPU
+ {4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Debug-V4|Any CPU.Build.0 = Debug|Any CPU
+ {4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Release-V4|Any CPU.ActiveCfg = Release|Any CPU
+ {4ADB9737-3274-4E6C-ABA0-FE214D89807D}.Release-V4|Any CPU.Build.0 = Release|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Debug|Any CPU.ActiveCfg = Debug-V3|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Debug|Any CPU.Build.0 = Debug-V3|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Debug-V4|Any CPU.ActiveCfg = Debug-V4|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Debug-V4|Any CPU.Build.0 = Debug-V4|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Release|Any CPU.ActiveCfg = Release-V3|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Release|Any CPU.Build.0 = Release-V3|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Release-V4|Any CPU.ActiveCfg = Release-V4|Any CPU
+ {E557D9D3-A8B9-4D31-BD7A-631C13025ABA}.Release-V4|Any CPU.Build.0 = Release-V4|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4ADB9737-3274-4E6C-ABA0-FE214D89807D} = {5C3F1ED6-EBB2-443C-8222-CC938FF2EB21}
diff --git a/src/FileParty.Core/FileParty.Core.csproj b/src/FileParty.Core/FileParty.Core.csproj
index 3be2eda..25955c4 100644
--- a/src/FileParty.Core/FileParty.Core.csproj
+++ b/src/FileParty.Core/FileParty.Core.csproj
@@ -1,15 +1,17 @@
- 1.3.0
+ 2.0.0
Jankware
Agnostic File Storage, Core Project, Service Registration
https://github.com/JankwareDotCom/FileParty
https://github.com/JankwareDotCom/FileParty
- net6.0;net8.0;netstandard2.0;netstandard2.1
+ net8.0;net10.0;netstandard2.0;netstandard2.1
true
Jankware FileParty
https://raw.githubusercontent.com/JankwareDotCom/FileParty/main/README.md
+ Debug;Release;Debug-V4;Release-V4
+ AnyCPU
@@ -24,7 +26,7 @@
-
+
diff --git a/src/FileParty.Providers.AWS.S3/AWS.S3Module.cs b/src/FileParty.Providers.AWS.S3/AWS.S3Module.cs
index 08a2f11..a48b163 100644
--- a/src/FileParty.Providers.AWS.S3/AWS.S3Module.cs
+++ b/src/FileParty.Providers.AWS.S3/AWS.S3Module.cs
@@ -1,4 +1,5 @@
-using FileParty.Core;
+using System;
+using FileParty.Core;
using FileParty.Core.Registration;
using FileParty.Providers.AWS.S3.Interfaces;
@@ -6,6 +7,8 @@ namespace FileParty.Providers.AWS.S3
{
public class AWS_S3Module : BaseFilePartyModule
{
+ public static readonly bool IsAwsSdkV4 = Type.GetType("Amazon.Runtime.Credentials.DefaultAWSCredentialsIdentityResolver, AWSSDK.Core") != null;
+
public AWS_S3Module()
{
this.RegisterModuleDependency AssumeRoleAsync(IFilePartyAWSCredentialFacto
? nameof(FileParty) + "_" + nameof(AWS_S3Module) + "_" + _internalIdentifier
: RoleSessionName;
- using (var stsClient = new AmazonSecurityTokenServiceClient(credFactory.GetAmazonCredentials(_baseConfig)))
+ var creds = credFactory.GetAmazonCredentials(_baseConfig);
+ var config = new AmazonSecurityTokenServiceConfig
+ {
+ RegionEndpoint = this.GetRegionEndpoint()
+ };
+
+ using (var stsClient = new AmazonSecurityTokenServiceClient(creds, config))
{
try
{
diff --git a/src/FileParty.Providers.AWS.S3/Config/AWSSessionCredentials.cs b/src/FileParty.Providers.AWS.S3/Config/AWSSessionCredentials.cs
index 5beb8f8..c11ae5b 100644
--- a/src/FileParty.Providers.AWS.S3/Config/AWSSessionCredentials.cs
+++ b/src/FileParty.Providers.AWS.S3/Config/AWSSessionCredentials.cs
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
+using Amazon;
using Amazon.Runtime;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
@@ -43,7 +44,14 @@ internal async Task GetTemporaryCredentialsAsync(
return _sessionCredentials;
}
- using (var stsClient = new AmazonSecurityTokenServiceClient(credFactory.GetAmazonCredentials(_baseConfig)))
+ var creds = credFactory.GetAmazonCredentials(_baseConfig);
+
+ var config = new AmazonSecurityTokenServiceConfig
+ {
+ RegionEndpoint = this.GetRegionEndpoint()
+ };
+
+ using (var stsClient = new AmazonSecurityTokenServiceClient(creds, config))
{
var getSessionTokenRequest = new GetSessionTokenRequest
{
diff --git a/src/FileParty.Providers.AWS.S3/Config/AWSStoredProfileConfiguration.cs b/src/FileParty.Providers.AWS.S3/Config/AWSStoredProfileConfiguration.cs
index 4399303..f99c8ef 100644
--- a/src/FileParty.Providers.AWS.S3/Config/AWSStoredProfileConfiguration.cs
+++ b/src/FileParty.Providers.AWS.S3/Config/AWSStoredProfileConfiguration.cs
@@ -33,16 +33,5 @@ public AWSStoredProfileConfiguration(string profileName, string profileLocation)
public string ProfileName { get; set; } = "default";
public string ProfileLocation { get; set; }
-
- internal StoredProfileAWSCredentials GetConfig()
- {
- return string.IsNullOrWhiteSpace(ProfileLocation)
- ? string.IsNullOrWhiteSpace(ProfileName)
- ? new StoredProfileAWSCredentials()
- : new StoredProfileAWSCredentials(ProfileName)
- : string.IsNullOrWhiteSpace(ProfileName)
- ? new StoredProfileAWSCredentials("default", ProfileLocation)
- : new StoredProfileAWSCredentials(ProfileName, ProfileLocation);
- }
}
}
\ No newline at end of file
diff --git a/src/FileParty.Providers.AWS.S3/FileParty.Providers.AWS.S3.csproj b/src/FileParty.Providers.AWS.S3/FileParty.Providers.AWS.S3.csproj
index cef3887..e491904 100644
--- a/src/FileParty.Providers.AWS.S3/FileParty.Providers.AWS.S3.csproj
+++ b/src/FileParty.Providers.AWS.S3/FileParty.Providers.AWS.S3.csproj
@@ -1,22 +1,49 @@
- net6.0;net8.0;netstandard2.0;netstandard2.1
- 1.3.0
+ net8.0;net10.0;netstandard2.0;netstandard2.1
+ 2.0.0
Agnostic File Storage, AWS S3 Module
https://github.com/JankwareDotCom/FileParty
https://github.com/JankwareDotCom/FileParty
true
+ Debug;Release;Debug-V3;Release-V3;Debug-V4;Release-V4
+ AnyCPU
+
+ $(DefineConstants);AWS_SDK_ANY
+
+
+
+ $(DefineConstants);AWS_SDK_V3
+
+
+
+ $(DefineConstants);AWS_SDK_V4
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/FileParty.Providers.AWS.S3/FilePartyAWSCredentialFactory.cs b/src/FileParty.Providers.AWS.S3/FilePartyAWSCredentialFactory.cs
index 4529364..1ffde02 100644
--- a/src/FileParty.Providers.AWS.S3/FilePartyAWSCredentialFactory.cs
+++ b/src/FileParty.Providers.AWS.S3/FilePartyAWSCredentialFactory.cs
@@ -1,5 +1,10 @@
using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
using Amazon.Runtime;
+using Amazon.Runtime.CredentialManagement;
+using Amazon.Runtime.Credentials;
using Amazon.S3;
using Amazon.SecurityToken;
using FileParty.Core.Exceptions;
@@ -31,9 +36,27 @@ public virtual AWSCredentials GetAmazonCredentials(StorageProviderConfiguration<
.GetAwaiter()
.GetResult();
case AWSDefaultConfiguration _:
- return FallbackCredentialsFactory.GetCredentials(false);
+ return GetDefaultCredentials();
case AWSStoredProfileConfiguration storedProfileConfiguration:
- return storedProfileConfiguration.GetConfig();
+ {
+ var profileLocation = string.IsNullOrWhiteSpace(storedProfileConfiguration.ProfileLocation)
+ ? null
+ : Directory.Exists(storedProfileConfiguration.ProfileLocation)
+ ? Path.Combine(storedProfileConfiguration.ProfileLocation, "credentials")
+ : storedProfileConfiguration.ProfileLocation;
+
+ var profileName = string.IsNullOrWhiteSpace(storedProfileConfiguration.ProfileName)
+ ? "default"
+ : storedProfileConfiguration.ProfileName;
+
+ var chain = string.IsNullOrWhiteSpace(profileLocation)
+ ? new CredentialProfileStoreChain()
+ : new CredentialProfileStoreChain(profileLocation);
+
+ return chain.TryGetAWSCredentials(profileName, out var creds)
+ ? creds
+ : throw Errors.InvalidConfiguration;
+ }
case AWSInstanceProfileConfiguration instanceConfiguration:
return new InstanceProfileAWSCredentials(instanceConfiguration.Role);
}
@@ -57,5 +80,31 @@ public virtual AWSCredentials GetAmazonCredentials(StorageProviderConfiguration<
throw Errors.InvalidConfiguration;
}
+
+ private static AWSCredentials GetDefaultCredentials()
+ {
+ return !AWS_S3Module.IsAwsSdkV4
+ ? (AWSCredentials) V3GetCredentialsMethod
+ ?.Invoke(null, new object[]{false})
+ ?? throw new InvalidOperationException("Unable to get v3 credentials")
+ : (AWSCredentials) V4GetCredentialsMethod
+ ?.Invoke(null, V4GetCredentialsMethod.GetParameters()
+ .Select(s => Convert.ChangeType(null, s.ParameterType)).ToArray())
+ ?? throw new InvalidOperationException("Unable to get credentials");
+ }
+
+
+
+ private static readonly MethodInfo V4GetCredentialsMethod =
+ AWS_S3Module.IsAwsSdkV4
+ ? Type.GetType("Amazon.Runtime.Credentials.DefaultAWSCredentialsIdentityResolver, AWSSDK.Core")
+ ?.GetMethod("GetCredentials")
+ : null;
+
+ private static readonly MethodInfo V3GetCredentialsMethod =
+ !AWS_S3Module.IsAwsSdkV4
+ ? Type.GetType("Amazon.Runtime.FallbackCredentialsFactory, AWSSDK.Core")
+ ?.GetMethod("GetCredentials", new[]{typeof(bool)})
+ : null;
}
}
\ No newline at end of file
diff --git a/src/FileParty.Providers.AWS.S3/S3StorageProvider.cs b/src/FileParty.Providers.AWS.S3/S3StorageProvider.cs
index ce12270..0e802fe 100644
--- a/src/FileParty.Providers.AWS.S3/S3StorageProvider.cs
+++ b/src/FileParty.Providers.AWS.S3/S3StorageProvider.cs
@@ -142,7 +142,7 @@ public virtual async Task ExistsAsync(string storagePointer,
using (var s3Wrapper = new FilePartyS3ClientWrapper(_s3ClientFactory))
{
var _ = await s3Wrapper.ExecuteAsync(
- (s3Client) => GetInformationAsync(s3Client, storagePointer, cancellationToken));
+ async (s3Client) => await GetInformationAsync(s3Client, storagePointer, cancellationToken));
}
return true;
@@ -153,12 +153,12 @@ public virtual async Task ExistsAsync(string storagePointer,
}
}
- public virtual Task> ExistsAsync(IEnumerable storagePointers,
+ public virtual async Task> ExistsAsync(IEnumerable storagePointers,
CancellationToken cancellationToken = default)
{
using (var s3Wrapper = new FilePartyS3ClientWrapper(_s3ClientFactory))
{
- return s3Wrapper.ExecuteAsync((s3Client) =>
+ return await s3Wrapper.ExecuteAsync((s3Client) =>
{
IDictionary result = storagePointers
.ToDictionary(
@@ -170,12 +170,12 @@ public virtual Task> ExistsAsync(IEnumerable s
}
}
- public Task TryGetStoredItemTypeAsync(string storagePointer,
+ public async Task TryGetStoredItemTypeAsync(string storagePointer,
CancellationToken cancellationToken = default)
{
using (var s3Wrapper = new FilePartyS3ClientWrapper(_s3ClientFactory))
{
- return s3Wrapper.ExecuteAsync((s3Client) =>
+ return await s3Wrapper.ExecuteAsync((s3Client) =>
TryGetStoredItemTypeAsync(s3Client, storagePointer, cancellationToken));
}
}
@@ -276,7 +276,7 @@ protected virtual async Task GetFileInformation(AmazonS3C
result.StoredType = StoredItemType.File;
result.Size = omInfo.ContentLength;
- result.LastModifiedTimestamp = omInfo.LastModified.ToUniversalTime();
+ result.LastModifiedTimestamp = (omInfo.LastModified as DateTime?).GetValueOrDefault().ToUniversalTime();
result.StoragePointer = storagePointer;
return result;
}
@@ -452,9 +452,9 @@ protected virtual async Task DeleteAsync(AmazonS3Client s3Client, IEnumerable s.Key).ToArray(), cancellationToken);
+ await DeleteAsync(directoryContents.S3Objects?.Select(s => s.Key).ToArray(), cancellationToken);
}
}
}
diff --git a/src/FileParty.Providers.FileSystem/FileParty.Providers.FileSystem.csproj b/src/FileParty.Providers.FileSystem/FileParty.Providers.FileSystem.csproj
index bb7fef4..9ac7ed5 100644
--- a/src/FileParty.Providers.FileSystem/FileParty.Providers.FileSystem.csproj
+++ b/src/FileParty.Providers.FileSystem/FileParty.Providers.FileSystem.csproj
@@ -1,12 +1,14 @@
- net6.0;net8.0;netstandard2.0;netstandard2.1
- 1.3.0
+ net8.0;net10.0;netstandard2.0;netstandard2.1
+ 2.0.0
Agnostic File Storage, Filesystem Module
https://github.com/JankwareDotCom/FileParty
https://github.com/JankwareDotCom/FileParty
true
+ Debug;Release;Debug-V4;Release-V4
+ AnyCPU
diff --git a/test/FileParty.Core.Tests/FileParty.Core.Tests.csproj b/test/FileParty.Core.Tests/FileParty.Core.Tests.csproj
index e169b08..8dc5f1e 100644
--- a/test/FileParty.Core.Tests/FileParty.Core.Tests.csproj
+++ b/test/FileParty.Core.Tests/FileParty.Core.Tests.csproj
@@ -2,24 +2,26 @@
false
- net8.0
+ net10.0
FileParty.Core.Tests
FileParty.Core.Tests
FileParty.Core.Tests
FileParty.Core.Tests
FileParty.Core.Tests
FileParty.Core.Tests
+ Debug;Release;Debug-V4;Release-V4
+ AnyCPU
-
+
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/test/FileParty.Handlers.AWS.S3.Tests/AwsSdkVersionTest.cs b/test/FileParty.Handlers.AWS.S3.Tests/AwsSdkVersionTest.cs
new file mode 100644
index 0000000..9f49dad
--- /dev/null
+++ b/test/FileParty.Handlers.AWS.S3.Tests/AwsSdkVersionTest.cs
@@ -0,0 +1,28 @@
+using System.Reflection;
+using Xunit;
+
+namespace FileParty.Handlers.AWS.S3.Tests;
+
+public class AwsSdkVersionTest
+{
+ [Theory]
+#if AWS_SDK_V3
+ [InlineData(3)]
+#endif
+#if AWS_SDK_V4
+ [InlineData(4)]
+#endif
+ public void ShouldUseExpectedAwsSdkVersion(int expectedVersion)
+ {
+ var awsS3Assembly = Assembly.Load("AWSSDK.S3");
+
+ Assert.NotNull(awsS3Assembly);
+
+ var version = awsS3Assembly.GetName().Version;
+
+ // Assert expected version
+ Assert.True(
+ version?.Major == expectedVersion,
+ $"Expected AWS SDK v{expectedVersion}, but got v{version?.Major ?? 0}");
+ }
+}
\ No newline at end of file
diff --git a/test/FileParty.Handlers.AWS.S3.Tests/CredentialFactoryShould.cs b/test/FileParty.Handlers.AWS.S3.Tests/CredentialFactoryShould.cs
index c1771ac..7791f7e 100644
--- a/test/FileParty.Handlers.AWS.S3.Tests/CredentialFactoryShould.cs
+++ b/test/FileParty.Handlers.AWS.S3.Tests/CredentialFactoryShould.cs
@@ -12,6 +12,7 @@
using FileParty.Providers.AWS.S3.Config;
using FileParty.Providers.AWS.S3.Interfaces;
using Microsoft.Extensions.DependencyInjection;
+using Moq;
using Xunit;
namespace FileParty.Handlers.AWS.S3.Tests;
@@ -116,20 +117,34 @@ public async Task CreateCredentials_UsingSession()
await EnsureFileCreationAndDeletion(cfg);
}
- [Fact(Skip = "Long Running Test")]
+ [Fact(Skip = "Long Running Test")] // last manually verified 2025-11-20
public async Task CreateCredentials_ButThrowDueToExpired_UsingSession()
{
+ var sc = new ServiceCollection();
+ sc.AddFileParty(c => c.AddModule(null));
+ await using var sp = sc.BuildServiceProvider();
+
var cfg = new AWSSessionCredentials(_accessKey, _secretKey)
{
Region = _regionName,
Name = _bucketName,
- DurationSeconds = 15 * 60
+ DurationSeconds = 15 * 60 // 15 minute duration is minimum
};
-
- await _credFactory.GetAmazonCredentials(cfg).GetCredentialsAsync();
-
- await Task.Delay(TimeSpan.FromSeconds(cfg.DurationSeconds), CancellationToken.None);
- await Assert.ThrowsAnyAsync(async () => { await EnsureFileCreationAndDeletion(cfg); });
+
+ var clientFactory = sp.GetRequiredService();
+
+ var client = clientFactory.GetClient(cfg);
+
+ Assert.True((await client.ListObjectsAsync(cfg.Name)).HttpStatusCode == System.Net.HttpStatusCode.OK);
+
+ await Task.Delay(TimeSpan.FromSeconds(cfg.DurationSeconds + 10), CancellationToken.None);
+
+ var exc = await Assert.ThrowsAsync(async () =>
+ {
+ await client.ListObjectsAsync(cfg.Name);
+ });
+
+ Assert.Equal("The provided token has expired.", exc.Message);
}
[Fact]
@@ -150,6 +165,7 @@ public async Task CreateCredentials_UsingRole()
}
}
+ //[Fact] // last manually verified 2025-11-22
[Fact(Skip = "Requires External AWS Account")]
public async Task CreateCredentials_UsingRole_ExternalAccount()
{
@@ -160,7 +176,7 @@ public async Task CreateCredentials_UsingRole_ExternalAccount()
var cfg = new AWSRoleBasedConfiguration
{
Name = externalConfig[0],
- Region = _regionName,
+ Region = externalConfig[3],
RoleArn = externalConfig[1],
ExternalId = externalConfig[2]
};
diff --git a/test/FileParty.Handlers.AWS.S3.Tests/FileParty.Handlers.AWS.S3.Tests.csproj b/test/FileParty.Handlers.AWS.S3.Tests/FileParty.Handlers.AWS.S3.Tests.csproj
index ec8d85b..24754da 100644
--- a/test/FileParty.Handlers.AWS.S3.Tests/FileParty.Handlers.AWS.S3.Tests.csproj
+++ b/test/FileParty.Handlers.AWS.S3.Tests/FileParty.Handlers.AWS.S3.Tests.csproj
@@ -1,18 +1,36 @@
- net8.0
+ net10.0
+ Debug-V3;Debug-V4;Release-V3;Release-V4
+
+
+
+ $(DefineConstants);AWS_SDK_V3
+
+
+
+ $(DefineConstants);AWS_SDK_V4
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+
+
+
+
+
+
+
diff --git a/test/FileParty.Handlers.FileSystem.Tests/FileParty.Handlers.FileSystem.Tests.csproj b/test/FileParty.Handlers.FileSystem.Tests/FileParty.Handlers.FileSystem.Tests.csproj
index 89c6205..dfc809b 100644
--- a/test/FileParty.Handlers.FileSystem.Tests/FileParty.Handlers.FileSystem.Tests.csproj
+++ b/test/FileParty.Handlers.FileSystem.Tests/FileParty.Handlers.FileSystem.Tests.csproj
@@ -4,17 +4,19 @@
false
FileParty.Providers.FileSystem.Tests
FileParty.Providers.FileSystem.Tests
- net8.0
+ net10.0
+ Debug;Release;Debug-V4;Release-V4
+ AnyCPU
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all