From ba523ac075be1b5cc31095e47ba1d7229b620981 Mon Sep 17 00:00:00 2001 From: Westin Miller Date: Tue, 29 Aug 2017 20:01:56 -0700 Subject: [PATCH 1/4] Test project and new versioning system. --- Essentials.Tests/Essentials.Tests.csproj | 93 +++++++++++++++++++++ Essentials.Tests/Properties/AssemblyInfo.cs | 17 ++++ Essentials.Tests/ReflectionTestManager.cs | 72 ++++++++++++++++ Essentials.Tests/TestUtils.cs | 35 ++++++++ Essentials.Tests/TorchReflectionTest.cs | 72 ++++++++++++++++ Essentials.Tests/packages.config | 12 +++ Essentials.sln | 6 ++ Essentials/Essentials.csproj | 3 + Essentials/Properties/AssemblyInfo.cs | 33 ++------ Jenkinsfile | 9 +- Versioning/AssemblyVersion.cs | 4 + Versioning/version.ps1 | 20 +++++ 12 files changed, 346 insertions(+), 30 deletions(-) create mode 100644 Essentials.Tests/Essentials.Tests.csproj create mode 100644 Essentials.Tests/Properties/AssemblyInfo.cs create mode 100644 Essentials.Tests/ReflectionTestManager.cs create mode 100644 Essentials.Tests/TestUtils.cs create mode 100644 Essentials.Tests/TorchReflectionTest.cs create mode 100644 Essentials.Tests/packages.config create mode 100644 Versioning/AssemblyVersion.cs create mode 100644 Versioning/version.ps1 diff --git a/Essentials.Tests/Essentials.Tests.csproj b/Essentials.Tests/Essentials.Tests.csproj new file mode 100644 index 0000000..dac495e --- /dev/null +++ b/Essentials.Tests/Essentials.Tests.csproj @@ -0,0 +1,93 @@ + + + + + {59A47A68-8B18-4942-B082-BCB52ED6D66D} + Library + Properties + Essentials.Tests + Essentials.Tests + v4.6.1 + 512 + + + + 1591,0649 + + + true + $(SolutionDir)\bin-test\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + + + $(SolutionDir)\bin-test\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + $(SolutionDir)\bin-test\x64\Release\Essentials.Tests.xml + + + + ..\packages\NLog.4.4.12\lib\net45\NLog.dll + True + + + + + + + + + + + ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll + + + ..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll + + + ..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll + + + ..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll + + + $(SolutionDir)\TorchBinaries\Torch.dll + True + + + $(SolutionDir)\TorchBinaries\Torch.API.dll + True + + + + + Properties\AssemblyVersion.cs + + + + + + + + + {A4C5FC37-5848-4A75-8CDC-4A1ADB2E01A2} + Essentials + True + + + + + + + + + + \ No newline at end of file diff --git a/Essentials.Tests/Properties/AssemblyInfo.cs b/Essentials.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1551025 --- /dev/null +++ b/Essentials.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Torch Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Torch")] +[assembly: AssemblyCopyright("Copyright © Torch API 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] + +#if DEBUG +[assembly: AssemblyConfiguration("Debug")] +#else +[assembly: AssemblyConfiguration("Release")] +#endif \ No newline at end of file diff --git a/Essentials.Tests/ReflectionTestManager.cs b/Essentials.Tests/ReflectionTestManager.cs new file mode 100644 index 0000000..425024e --- /dev/null +++ b/Essentials.Tests/ReflectionTestManager.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Torch.Utils; + +namespace Torch.Tests +{ + public class ReflectionTestManager + { + #region FieldProvider + public struct FieldRef + { + public FieldInfo Field; + + public FieldRef(FieldInfo f) + { + Field = f; + } + + public override string ToString() + { + if (Field == null) + return "Ignored"; + return Field.DeclaringType?.FullName + "." + Field.Name; + } + } + + private readonly HashSet _getters = new HashSet(); + private readonly HashSet _setters = new HashSet(); + private readonly HashSet _invokers = new HashSet(); + + public ReflectionTestManager() + { + _getters.Add(new object[] { new FieldRef(null) }); + _setters.Add(new object[] { new FieldRef(null) }); + _invokers.Add(new object[] { new FieldRef(null) }); + } + + public ReflectionTestManager Init(Assembly asm) + { + foreach (Type type in asm.GetTypes()) + Init(type); + return this; + } + + public ReflectionTestManager Init(Type type) + { + foreach (FieldInfo field in type.GetFields(BindingFlags.Static | + BindingFlags.Instance | + BindingFlags.Public | + BindingFlags.NonPublic)) + { + if (field.GetCustomAttribute() != null) + _invokers.Add(new object[] { new FieldRef(field) }); + if (field.GetCustomAttribute() != null) + _getters.Add(new object[] { new FieldRef(field) }); + if (field.GetCustomAttribute() != null) + _setters.Add(new object[] { new FieldRef(field) }); + } + return this; + } + + public IEnumerable Getters => _getters; + + public IEnumerable Setters => _setters; + + public IEnumerable Invokers => _invokers; + + #endregion + + } +} diff --git a/Essentials.Tests/TestUtils.cs b/Essentials.Tests/TestUtils.cs new file mode 100644 index 0000000..323186b --- /dev/null +++ b/Essentials.Tests/TestUtils.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Torch.Utils; + +namespace Torch.Tests +{ + public sealed class TestUtils + { + public static void Init() + { + if (_torchResolver == null) + _torchResolver = new TorchAssemblyResolver(GetGameBinaries()); + } + + private static string GetGameBinaries() + { + string dir = Environment.CurrentDirectory; + while (!string.IsNullOrWhiteSpace(dir)) + { + string gameBin = Path.Combine(dir, "GameBinaries"); + if (Directory.Exists(gameBin)) + return gameBin; + + dir = Path.GetDirectoryName(dir); + } + throw new Exception("GetGameBinaries failed to find a folder named GameBinaries in the directory tree"); + } + + private static TorchAssemblyResolver _torchResolver; + } +} diff --git a/Essentials.Tests/TorchReflectionTest.cs b/Essentials.Tests/TorchReflectionTest.cs new file mode 100644 index 0000000..779225b --- /dev/null +++ b/Essentials.Tests/TorchReflectionTest.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Torch.Tests; +using Torch.Utils; +using Xunit; + +namespace Essentials.Tests +{ + public class TorchReflectionTest + { + static TorchReflectionTest() + { + TestUtils.Init(); + } + + private static ReflectionTestManager _manager; + + private static ReflectionTestManager Manager() + { + TestUtils.Init(); + if (_manager != null) + return _manager; + return _manager = new ReflectionTestManager().Init(typeof(EssentialsPlugin).Assembly); + } + + public static IEnumerable Getters => Manager().Getters; + + public static IEnumerable Setters => Manager().Setters; + + public static IEnumerable Invokers => Manager().Invokers; + + #region Binding + [Theory] + [MemberData(nameof(Getters))] + public void TestBindingGetter(ReflectionTestManager.FieldRef field) + { + if (field.Field == null) + return; + Assert.True(ReflectedManager.Process(field.Field)); + if (field.Field.IsStatic) + Assert.NotNull(field.Field.GetValue(null)); + } + + [Theory] + [MemberData(nameof(Setters))] + public void TestBindingSetter(ReflectionTestManager.FieldRef field) + { + if (field.Field == null) + return; + Assert.True(ReflectedManager.Process(field.Field)); + if (field.Field.IsStatic) + Assert.NotNull(field.Field.GetValue(null)); + } + + [Theory] + [MemberData(nameof(Invokers))] + public void TestBindingInvoker(ReflectionTestManager.FieldRef field) + { + if (field.Field == null) + return; + Assert.True(ReflectedManager.Process(field.Field)); + if (field.Field.IsStatic) + Assert.NotNull(field.Field.GetValue(null)); + } + #endregion + } +} diff --git a/Essentials.Tests/packages.config b/Essentials.Tests/packages.config new file mode 100644 index 0000000..30eb495 --- /dev/null +++ b/Essentials.Tests/packages.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Essentials.sln b/Essentials.sln index c3c8348..5c24b3f 100644 --- a/Essentials.sln +++ b/Essentials.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.26730.8 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Essentials", "Essentials\Essentials.csproj", "{A4C5FC37-5848-4A75-8CDC-4A1ADB2E01A2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Essentials.Tests", "Essentials.Tests\Essentials.Tests.csproj", "{59A47A68-8B18-4942-B082-BCB52ED6D66D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -15,6 +17,10 @@ Global {A4C5FC37-5848-4A75-8CDC-4A1ADB2E01A2}.Debug|x64.Build.0 = Debug|x64 {A4C5FC37-5848-4A75-8CDC-4A1ADB2E01A2}.Release|x64.ActiveCfg = Release|x64 {A4C5FC37-5848-4A75-8CDC-4A1ADB2E01A2}.Release|x64.Build.0 = Release|x64 + {59A47A68-8B18-4942-B082-BCB52ED6D66D}.Debug|x64.ActiveCfg = Debug|x64 + {59A47A68-8B18-4942-B082-BCB52ED6D66D}.Debug|x64.Build.0 = Debug|x64 + {59A47A68-8B18-4942-B082-BCB52ED6D66D}.Release|x64.ActiveCfg = Release|x64 + {59A47A68-8B18-4942-B082-BCB52ED6D66D}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Essentials/Essentials.csproj b/Essentials/Essentials.csproj index b0ec430..61552ae 100644 --- a/Essentials/Essentials.csproj +++ b/Essentials/Essentials.csproj @@ -136,6 +136,9 @@ + + Properties\AssemblyVersion.cs + diff --git a/Essentials/Properties/AssemblyInfo.cs b/Essentials/Properties/AssemblyInfo.cs index 8df48d6..7405075 100644 --- a/Essentials/Properties/AssemblyInfo.cs +++ b/Essentials/Properties/AssemblyInfo.cs @@ -1,36 +1,17 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. [assembly: AssemblyTitle("Essentials")] [assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Essentials")] -[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyProduct("Torch")] +[assembly: AssemblyCopyright("Copyright © Torch API 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a4c5fc37-5848-4a75-8cdc-4a1adb2e01a2")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +#if DEBUG +[assembly: AssemblyConfiguration("Debug")] +#else +[assembly: AssemblyConfiguration("Release")] +#endif \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index e09ebf6..7f91112 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -9,12 +9,12 @@ def test_with_torch(branch) } stage('Build + Torch ' + branch) { + currentBuild.description = bat(returnStdout: true, script: '@powershell -File Versioning/version.ps1').trim() bat "\"${tool 'MSBuild'}msbuild\" Essentials.sln /p:Configuration=Release /p:Platform=x64 /t:Clean" - // bat "\"${tool 'MSBuild'}msbuild\" Essentials.sln /p:Configuration=Release /p:Platform=x64 /t:TransformOnBuild" bat "\"${tool 'MSBuild'}msbuild\" Essentials.sln /p:Configuration=Release /p:Platform=x64" } - /* + stage('Test + Torch ' + branch) { bat 'IF NOT EXIST reports MKDIR reports' bat "\"packages/xunit.runner.console.2.2.0/tools/xunit.console.exe\" \"bin-test/x64/Release/Essentials.Tests.dll\" -parallel none -xml \"reports/Essentials.Tests.xml\"" @@ -32,7 +32,7 @@ def test_with_torch(branch) ]] ]) } - */ + return true } catch (e) { return false @@ -42,12 +42,13 @@ def test_with_torch(branch) node { stage('Checkout') { checkout scm + bat 'git pull --tags' } stage('Acquire SE') { bat 'powershell -File Jenkins/jenkins-grab-se.ps1' bat 'IF EXIST GameBinaries RMDIR GameBinaries' - bat 'mklink /J GameBinaries "C:/Steam/Data/DedicatedServer64/"' + bat 'mklink /J GameBinaries "C:/Steam/Data/DedicatedServer64/"' } stage('Acquire NuGet Packages') { diff --git a/Versioning/AssemblyVersion.cs b/Versioning/AssemblyVersion.cs new file mode 100644 index 0000000..ca39cd6 --- /dev/null +++ b/Versioning/AssemblyVersion.cs @@ -0,0 +1,4 @@ +using System.Reflection; + +[assembly: AssemblyVersion("1.5.6695.1")] +[assembly: AssemblyInformationalVersion("1.5.1-8-g8399387")] diff --git a/Versioning/version.ps1 b/Versioning/version.ps1 new file mode 100644 index 0000000..00de9fc --- /dev/null +++ b/Versioning/version.ps1 @@ -0,0 +1,20 @@ +$gitVersion = git describe --tags +$gitSimpleVersion = git describe --tags --abbrev=0 +if ($gitSimpleVersion.Equals($gitVersion)) { + $buildSalt = 0 +} else { + $gitLatestCommit = git rev-parse HEAD + $buildSalt = [System.Numerics.BigInteger]::Abs([System.Numerics.BigInteger]::Parse($gitLatestCommit, [System.Globalization.NumberStyles]::HexNumber) % 9988) + 1 +} +$dotNetVersion = echo $gitSimpleVersion | Select-String -Pattern "([0-9]+)\.([0-9]+)\.([0-9]+)" | % {$_.Matches} | %{$_.Groups[1].Value+"."+$_.Groups[2].Value+".$buildSalt."+$_.Groups[3].Value} + +$fileContent = @" +using System.Reflection; + +[assembly: AssemblyVersion("$dotNetVersion")] +[assembly: AssemblyInformationalVersion("$gitVersion")] +"@ + +echo $fileContent | Set-Content "$PSScriptRoot/AssemblyVersion.cs" + +echo "$gitVersion / $dotNetVersion" \ No newline at end of file From c2b7cd6616e82667fa31a5aef11200d3a8d8b659 Mon Sep 17 00:00:00 2001 From: Westin Miller Date: Wed, 30 Aug 2017 11:19:57 -0700 Subject: [PATCH 2/4] Local dev version is clearly not a standard release. --- Versioning/AssemblyVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Versioning/AssemblyVersion.cs b/Versioning/AssemblyVersion.cs index ca39cd6..c663bea 100644 --- a/Versioning/AssemblyVersion.cs +++ b/Versioning/AssemblyVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("1.5.6695.1")] -[assembly: AssemblyInformationalVersion("1.5.1-8-g8399387")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyInformationalVersion("v0.0.0-dev")] From 92d7bf1c1ada01cb4c50f25e390b342a1b75442c Mon Sep 17 00:00:00 2001 From: Westin Miller Date: Wed, 30 Aug 2017 13:21:57 -0700 Subject: [PATCH 3/4] Salt after revision. --- Versioning/version.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Versioning/version.ps1 b/Versioning/version.ps1 index 00de9fc..2e624b4 100644 --- a/Versioning/version.ps1 +++ b/Versioning/version.ps1 @@ -3,10 +3,10 @@ $gitSimpleVersion = git describe --tags --abbrev=0 if ($gitSimpleVersion.Equals($gitVersion)) { $buildSalt = 0 } else { - $gitLatestCommit = git rev-parse HEAD - $buildSalt = [System.Numerics.BigInteger]::Abs([System.Numerics.BigInteger]::Parse($gitLatestCommit, [System.Globalization.NumberStyles]::HexNumber) % 9988) + 1 + $gitLatestCommit = git rev-parse --short HEAD + $buildSalt = [System.Numerics.BigInteger]::Abs([System.Numerics.BigInteger]::Parse($gitLatestCommit, [System.Globalization.NumberStyles]::HexNumber) % 16383) + 1 } -$dotNetVersion = echo $gitSimpleVersion | Select-String -Pattern "([0-9]+)\.([0-9]+)\.([0-9]+)" | % {$_.Matches} | %{$_.Groups[1].Value+"."+$_.Groups[2].Value+".$buildSalt."+$_.Groups[3].Value} +$dotNetVersion = echo $gitSimpleVersion | Select-String -Pattern "([0-9]+)\.([0-9]+)\.([0-9]+)" | % {$_.Matches} | %{$_.Groups[1].Value+"."+$_.Groups[2].Value+"."+$_.Groups[3].Value+".$buildSalt"} $fileContent = @" using System.Reflection; From e4bbaef8e3c0dbce7f360a61ea4cb825401871ab Mon Sep 17 00:00:00 2001 From: Westin Miller Date: Wed, 30 Aug 2017 22:39:15 -0700 Subject: [PATCH 4/4] Use new versioned attribute. --- Essentials/EssentialsPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/EssentialsPlugin.cs b/Essentials/EssentialsPlugin.cs index 67fcdbb..36edd46 100644 --- a/Essentials/EssentialsPlugin.cs +++ b/Essentials/EssentialsPlugin.cs @@ -17,7 +17,7 @@ namespace Essentials { - [Plugin("Essentials", "1.5.1", "cbfdd6ab-4cda-4544-a201-f73efa3d46c0")] + [Plugin("Essentials", typeof(EssentialsPlugin), "cbfdd6ab-4cda-4544-a201-f73efa3d46c0")] public class EssentialsPlugin : TorchPluginBase, IWpfPlugin { public EssentialsConfig Config => _config?.Data;