-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
58012f7
commit d870e6c
Showing
22 changed files
with
1,077 additions
and
0 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
name: Plumsy CD Pipeline | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build: | ||
environment: Default | ||
strategy: | ||
matrix: | ||
targetplatform: [x64] | ||
|
||
runs-on: windows-latest | ||
|
||
env: | ||
Configuration: Release | ||
Solution_Path: Plumsy.sln | ||
Test_Project_Path: Plumsy.Tests\Plumsy.Tests.csproj | ||
Source_Project_Path: Plumsy\Plumsy.csproj | ||
Actions_Allow_Unsecure_Commands: true | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Install .NET Core | ||
uses: actions/setup-dotnet@v1 | ||
with: | ||
dotnet-version: '7.x' | ||
|
||
- name: Setup MSBuild.exe | ||
uses: microsoft/[email protected] | ||
|
||
- name: Restore project | ||
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier | ||
env: | ||
RuntimeIdentifier: win-${{ matrix.targetplatform }} | ||
|
||
- name: Build Plumsy project | ||
run: dotnet build Plumsy -c $env:Configuration | ||
|
||
- name: Package Plumsy | ||
run: dotnet pack -c Release -o . $env:Source_Project_Path | ||
|
||
- name: Publish | ||
run: dotnet nuget push *.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
name: Plumsy CI Pipeline | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build: | ||
strategy: | ||
matrix: | ||
targetplatform: [x64] | ||
|
||
runs-on: windows-latest | ||
|
||
env: | ||
Solution_Path: Plumsy.sln | ||
Test_Project_Path: Plumsy.Tests\Plumsy.Tests.csproj | ||
Test_Plugin_Project_Path: Plumsy.Tests.SimplePlugin\Plumsy.Tests.SimplePlugin.csproj | ||
Source_Project_Path: Plumsy\Plumsy.csproj | ||
Actions_Allow_Unsecure_Commands: true | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Install .NET Core | ||
uses: actions/setup-dotnet@v1 | ||
with: | ||
dotnet-version: '6.x' | ||
|
||
- name: Setup MSBuild.exe | ||
uses: microsoft/[email protected] | ||
|
||
- name: Build SimplePlugin project | ||
run: dotnet build $env:Test_Plugin_Project_Path | ||
|
||
- name: Prepare plugin files # Needs to be done manually in this pipeline | ||
run: | | ||
mkdir ${{ github.workspace }}\SimplePlugin | ||
cp ${{ github.workspace }}\Plumsy.Tests.SimplePlugin\bin\Debug\net6.0\Plumsy.Tests.SimplePlugin.dll ${{ github.workspace }}\SimplePlugin\Plumsy.Tests.SimplePlugin.dll | ||
cp ${{ github.workspace }}\Plumsy.Tests.SimplePlugin\bin\Debug\net6.0\SystemExtensions.NetStandard.dll ${{ github.workspace }}\SimplePlugin\SystemExtensions.NetStandard.dll | ||
- name: Echo solution path | ||
run: echo /p:SolutionDir=${{ github.workspace }}\ | ||
|
||
- name: Execute Plumsy Unit Tests | ||
run: dotnet test $env:Test_Project_Path /p:SolutionDir=${{ github.workspace }}\ --logger:"console;verbosity=normal" # Need to manually set the SolutionDir, otherwise it's unspecified | ||
|
||
- name: Restore Project | ||
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier | ||
env: | ||
Configuration: Debug | ||
RuntimeIdentifier: win-${{ matrix.targetplatform }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 Macocian Alexandru Victor | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System.Extensions; | ||
|
||
namespace Plum.Net.Tests.SimplePlugin; | ||
|
||
public sealed class Main | ||
{ | ||
public Main() | ||
{ | ||
this.ThrowIfNull("this"); | ||
} | ||
|
||
public bool ReturnTrue() => true; | ||
} |
22 changes: 22 additions & 0 deletions
22
Plumsy.Tests.SimplePlugin/Plumsy.Tests.SimplePlugin.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup> | ||
<DestinationFolder>$(SolutionDir)SimplePlugin</DestinationFolder> | ||
</PropertyGroup> | ||
|
||
<Target Name="CopyAssembliesToSolution" AfterTargets="PostBuildEvent"> | ||
<Copy SourceFiles="$(OutputPath)$(AssemblyName).dll" DestinationFolder="$(DestinationFolder)" /> | ||
<Copy SourceFiles="$(OutputPath)SystemExtensions.NetStandard.dll" DestinationFolder="$(DestinationFolder)" /> | ||
</Target> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.6.2" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
using FluentAssertions; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using NSubstitute; | ||
using Plum.Net.Models; | ||
using Plum.Net.Tests.Resolvers; | ||
using Plum.Net.Tests.SimplePlugin; | ||
using Plum.Net.Validators; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Reflection.Metadata; | ||
using System.Runtime.Loader; | ||
|
||
namespace Plum.Net.Tests; | ||
|
||
[TestClass] | ||
public class PluginManagerTests | ||
{ | ||
private readonly string pluginDirectory; | ||
private readonly PluginManager pluginManager; | ||
|
||
public PluginManagerTests() | ||
{ | ||
this.pluginDirectory = Path.Combine(Environment.CurrentDirectory, "Plugins"); | ||
this.pluginManager = new(this.pluginDirectory); | ||
this.pluginManager.WithDependencyResolver(new SimpleDependencyResolver()); | ||
} | ||
|
||
[TestInitialize] | ||
public void TestInitialize() | ||
{ | ||
var assemblyLoadEventHandlerField = typeof(AssemblyLoadContext).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).First(f => f.Name == "AssemblyLoad"); | ||
assemblyLoadEventHandlerField.SetValue(AssemblyLoadContext.Default, null); | ||
|
||
var resolveDependencyEventHandlerField = typeof(AssemblyLoadContext).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).First(f => f.Name == "AssemblyResolve"); | ||
resolveDependencyEventHandlerField.SetValue(AssemblyLoadContext.Default, null); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_MissingPluginDirectory_ShouldReturnNoPlugins() | ||
{ | ||
var pluginManager = new PluginManager(Path.Combine(this.pluginDirectory, Guid.NewGuid().ToString())); | ||
|
||
var plugins = pluginManager.GetAvailablePlugins(); | ||
|
||
plugins.Should().HaveCount(0); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_ExistingPlugin_ShouldReturnExpectedPlugin() | ||
{ | ||
var plugins = this.pluginManager.GetAvailablePlugins(); | ||
|
||
plugins.Should().HaveCount(1); | ||
plugins.First().Name.Should().Be("Plum.Net.Tests.SimplePlugin"); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_VersionValidator_ValidatesVersion() | ||
{ | ||
var called = false; | ||
var validator = Substitute.For<IEnvironmentVersionValidator>(); | ||
this.pluginManager.WithEnvironmentVersionValidator(validator); | ||
validator.Validate(Arg.Any<Version>(), Arg.Any<Version>()).Returns(callinfo => | ||
{ | ||
called = true; | ||
return true; | ||
}); | ||
|
||
var plugins = this.pluginManager.GetAvailablePlugins().ToList(); | ||
|
||
called.Should().BeTrue(); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_VersionValidator_CurrentVersionMatchesEnvironment() | ||
{ | ||
var validator = Substitute.For<IEnvironmentVersionValidator>(); | ||
this.pluginManager.WithEnvironmentVersionValidator(validator); | ||
validator.Validate(Arg.Any<Version>(), Arg.Any<Version>()).Returns(callinfo => | ||
{ | ||
var currentVersion = callinfo.ArgAt<Version>(0); | ||
currentVersion.Should().Be(Environment.Version); | ||
return true; | ||
}); | ||
|
||
var plugins = this.pluginManager.GetAvailablePlugins().ToList(); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_VersionValidatorDenies_ReturnsNoPlugins() | ||
{ | ||
var validator = Substitute.For<IEnvironmentVersionValidator>(); | ||
this.pluginManager.WithEnvironmentVersionValidator(validator); | ||
validator.Validate(Arg.Any<Version>(), Arg.Any<Version>()).Returns(callinfo => | ||
{ | ||
return false; | ||
}); | ||
|
||
var plugins = this.pluginManager.GetAvailablePlugins().ToList(); | ||
|
||
plugins.Should().HaveCount(0); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_TypeDefinitionsValidator_CallsValidator() | ||
{ | ||
var called = false; | ||
var validator = Substitute.For<ITypeDefinitionsValidator>(); | ||
this.pluginManager.WithTypeDefinitionsValidator(validator); | ||
validator.Validate(Arg.Any<IEnumerable<TypeDefinition>>(), Arg.Any<MetadataReader>()).Returns(callinfo => | ||
{ | ||
called = true; | ||
return true; | ||
}); | ||
|
||
var plugins = this.pluginManager.GetAvailablePlugins().ToList(); | ||
called.Should().BeTrue(); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_TypeDefinitionsValidator_ReceivesMainType() | ||
{ | ||
var validator = Substitute.For<ITypeDefinitionsValidator>(); | ||
this.pluginManager.WithTypeDefinitionsValidator(validator); | ||
validator.Validate(Arg.Any<IEnumerable<TypeDefinition>>(), Arg.Any<MetadataReader>()).Returns(callinfo => | ||
{ | ||
var typeDefinitions = callinfo.ArgAt<IEnumerable<TypeDefinition>>(0); | ||
var metadataReader = callinfo.ArgAt<MetadataReader>(1); | ||
typeDefinitions.Select(t => metadataReader.GetString(t.Name)).Any(t => t == "Main").Should().BeTrue(); | ||
return true; | ||
}); | ||
|
||
var plugins = this.pluginManager.GetAvailablePlugins().ToList(); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_MetadataValidator_CallsValidator() | ||
{ | ||
var called = false; | ||
var validator = Substitute.For<IMetadataValidator>(); | ||
this.pluginManager.WithMetadataValidator(validator); | ||
validator.Validate(Arg.Any<MetadataReader>()).Returns(callinfo => | ||
{ | ||
var metadataReader = callinfo.ArgAt<MetadataReader>(0); | ||
metadataReader.Should().NotBeNull(); | ||
called = true; | ||
return true; | ||
}); | ||
|
||
var plugins = this.pluginManager.GetAvailablePlugins().ToList(); | ||
called.Should().BeTrue(); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_LoadPlugins_ShouldSucceed() | ||
{ | ||
var plugins = this.pluginManager.GetAvailablePlugins(); | ||
|
||
var results = this.pluginManager.LoadPlugins(plugins); | ||
|
||
results.Should().HaveCount(1); | ||
results.First().Should().BeOfType<PluginLoadOperation.Success>(); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_LoadPlugins_ReturnsExpectedAssembly() | ||
{ | ||
this.pluginManager.WithForceLoadDependencies(true); | ||
var plugins = this.pluginManager.GetAvailablePlugins(); | ||
|
||
var results = this.pluginManager.LoadPlugins(plugins); | ||
var assembly = results.OfType<PluginLoadOperation.Success>().First().Plugin.Assembly; | ||
var mainType = assembly.GetTypes().First(t => t.Name == nameof(Main)); | ||
var main = Activator.CreateInstance(mainType).As<Main>(); | ||
|
||
main.Should().NotBeNull(); | ||
main.ReturnTrue().Should().BeTrue(); | ||
} | ||
|
||
[TestMethod] | ||
[Ignore("This test fails when run together with the other tests, as the dependent assembly is loaded into the AppDomain by other tests")] | ||
public void PluginManager_LoadPlugins_WithNoResolver_FailsToResolveAssembly() | ||
{ | ||
var pluginManager = new PluginManager(this.pluginDirectory); | ||
pluginManager.WithForceLoadDependencies(true); | ||
var plugins = pluginManager.GetAvailablePlugins(); | ||
|
||
var results = pluginManager.LoadPlugins(plugins); | ||
|
||
results.First().Should().BeOfType<PluginLoadOperation.ExceptionEncountered>(); | ||
} | ||
|
||
[TestMethod] | ||
public void PluginManager_LoadPlugins_WithNoResolverAndNoForcedDependencyResolve_Succeeds() | ||
{ | ||
var pluginManager = new PluginManager(this.pluginDirectory); | ||
pluginManager.WithForceLoadDependencies(false); | ||
var plugins = pluginManager.GetAvailablePlugins(); | ||
|
||
var results = pluginManager.LoadPlugins(plugins); | ||
|
||
results.First().Should().BeOfType<PluginLoadOperation.Success>(); | ||
} | ||
} |
Oops, something went wrong.