From c5dd70feea8f189bf6cb919b163e37cd7e12971a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Jedlicska?= <57442769+gjedlicska@users.noreply.github.com> Date: Fri, 16 Feb 2024 12:00:50 +0100 Subject: [PATCH] gergo/localTesting (#18) * feat: add test project * feat: add test project --- SpeckleAutomateDotnetExample.sln | 6 + .../AutomateFunction.cs | 2 +- .../FunctionInputs.cs | 2 +- TestAutomateFunction/AutomationContextTest.cs | 111 ++++++++++++++++++ .../TestAutomateFunction.csproj | 25 ++++ TestAutomateFunction/TestAutomateUtils.cs | 69 +++++++++++ TestAutomateFunction/Usings.cs | 1 + 7 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 TestAutomateFunction/AutomationContextTest.cs create mode 100644 TestAutomateFunction/TestAutomateFunction.csproj create mode 100644 TestAutomateFunction/TestAutomateUtils.cs create mode 100644 TestAutomateFunction/Usings.cs diff --git a/SpeckleAutomateDotnetExample.sln b/SpeckleAutomateDotnetExample.sln index 6aebe93..ac801c6 100644 --- a/SpeckleAutomateDotnetExample.sln +++ b/SpeckleAutomateDotnetExample.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.5.002.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpeckleAutomateDotnetExample", "SpeckleAutomateDotnetExample/SpeckleAutomateDotnetExample.csproj", "{E1DE5809-1111-4817-9B7D-7ADCA087FA1C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAutomateFunction", "TestAutomateFunction\TestAutomateFunction.csproj", "{8107A920-A5E2-459C-9756-04B91FB63F3F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {E1DE5809-1111-4817-9B7D-7ADCA087FA1C}.Debug|Any CPU.Build.0 = Debug|Any CPU {E1DE5809-1111-4817-9B7D-7ADCA087FA1C}.Release|Any CPU.ActiveCfg = Release|Any CPU {E1DE5809-1111-4817-9B7D-7ADCA087FA1C}.Release|Any CPU.Build.0 = Release|Any CPU + {8107A920-A5E2-459C-9756-04B91FB63F3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8107A920-A5E2-459C-9756-04B91FB63F3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8107A920-A5E2-459C-9756-04B91FB63F3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8107A920-A5E2-459C-9756-04B91FB63F3F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SpeckleAutomateDotnetExample/AutomateFunction.cs b/SpeckleAutomateDotnetExample/AutomateFunction.cs index d6e9d04..58e0c01 100644 --- a/SpeckleAutomateDotnetExample/AutomateFunction.cs +++ b/SpeckleAutomateDotnetExample/AutomateFunction.cs @@ -4,7 +4,7 @@ using Speckle.Automate.Sdk; using Speckle.Core.Logging; using Speckle.Core.Models.Extensions; -static class AutomateFunction +public static class AutomateFunction { public static async Task Run( AutomationContext automationContext, diff --git a/SpeckleAutomateDotnetExample/FunctionInputs.cs b/SpeckleAutomateDotnetExample/FunctionInputs.cs index f37a05a..9b03412 100644 --- a/SpeckleAutomateDotnetExample/FunctionInputs.cs +++ b/SpeckleAutomateDotnetExample/FunctionInputs.cs @@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations; /// /// This class is used to generate a JSON Schema to ensure that the user provided values /// are valid and match the required schema. -struct FunctionInputs +public struct FunctionInputs { [Required] public string SpeckleTypeToCount; diff --git a/TestAutomateFunction/AutomationContextTest.cs b/TestAutomateFunction/AutomationContextTest.cs new file mode 100644 index 0000000..525b457 --- /dev/null +++ b/TestAutomateFunction/AutomationContextTest.cs @@ -0,0 +1,111 @@ +# nullable enable +namespace TestAutomateFunction; + +using Speckle.Automate.Sdk.Schema; +using Speckle.Automate.Sdk; +using Speckle.Core.Api; +using Speckle.Core.Credentials; +using Speckle.Core.Models; +using Speckle.Core.Transports; +using Utils = TestAutomateUtils; + +[TestFixture] +public sealed class AutomationContextTest : IDisposable +{ + private async Task AutomationRunData(Base testObject) + { + string projectId = await client.StreamCreate(new() { name = "Automate function e2e test" }); + const string branchName = "main"; + + Branch model = await client.BranchGet(projectId, branchName, 1); + string modelId = model.id; + + string rootObjId = await Operations.Send( + testObject, + new List { new ServerTransport(client.Account, projectId) } + ); + + string versionId = await client.CommitCreate( + new() + { + streamId = projectId, + objectId = rootObjId, + branchName = model.name + } + ); + + var automationName = TestAutomateUtils.RandomString(10); + var automationId = TestAutomateUtils.RandomString(10); + var automationRevisionId = TestAutomateUtils.RandomString(10); + + await TestAutomateUtils.RegisterNewAutomation(projectId, modelId, client, automationId, automationName, automationRevisionId); + + var automationRunId = TestAutomateUtils.RandomString(10); + var functionId = TestAutomateUtils.RandomString(10); + var functionName = "Automation name " + TestAutomateUtils.RandomString(10); + var functionRelease = TestAutomateUtils.RandomString(10); + + return new AutomationRunData + { + ProjectId = projectId, + ModelId = modelId, + BranchName = branchName, + VersionId = versionId, + SpeckleServerUrl = client.ServerUrl, + AutomationId = automationId, + AutomationRevisionId = automationRevisionId, + AutomationRunId = automationRunId, + FunctionId = functionId, + FunctionName = functionName, + FunctionRelease = functionRelease, + }; + } + + private Client client; + private Account account; + + private string GetSpeckleToken() + { + var envVarName = "SPECKLE_TOKEN"; + var token = Environment.GetEnvironmentVariable(envVarName); + if (token is null) + { + throw new Exception($"Cannot run tests without a {envVarName} environment variable"); + } + + return token; + } + + private string GetSpeckleServerUrl() => + Environment.GetEnvironmentVariable("SPECKLE_SERVER_ULR") ?? "http://127.0.0.1:3000"; + + [OneTimeSetUp] + public void Setup() + { + account = new Account + { + token = GetSpeckleToken(), + serverInfo = new ServerInfo { url = GetSpeckleServerUrl()} + }; + client = new Client(account); + } + + [Test] + public async Task TestFunctionRun() + { + var automationRunData = await AutomationRunData(TestAutomateUtils.TestObject()); + var automationContext = await AutomationRunner.RunFunction( + AutomateFunction.Run, + automationRunData, + account.token, + new FunctionInputs { SpeckleTypeToCount = "Base" } + ); + + Assert.That(automationContext.RunStatus, Is.EqualTo("SUCCEEDED")); + } + + public void Dispose() + { + client.Dispose(); + } +} diff --git a/TestAutomateFunction/TestAutomateFunction.csproj b/TestAutomateFunction/TestAutomateFunction.csproj new file mode 100644 index 0000000..efc5480 --- /dev/null +++ b/TestAutomateFunction/TestAutomateFunction.csproj @@ -0,0 +1,25 @@ + + + + net7.0 + enable + enable + + false + + + + + + + + + + + + + + + + + diff --git a/TestAutomateFunction/TestAutomateUtils.cs b/TestAutomateFunction/TestAutomateUtils.cs new file mode 100644 index 0000000..d5bcf25 --- /dev/null +++ b/TestAutomateFunction/TestAutomateUtils.cs @@ -0,0 +1,69 @@ +using System.Diagnostics.CodeAnalysis; +using GraphQL; +using Speckle.Core.Api; +using Speckle.Core.Models; + +namespace TestAutomateFunction; + +public static class TestAutomateUtils +{ + [SuppressMessage("Security", "CA5394:Do not use insecure randomness")] + public static string RandomString(int length) + { + Random rand = new(); + const string pool = "abcdefghijklmnopqrstuvwxyz0123456789"; + var chars = Enumerable.Range(0, length).Select(_ => pool[rand.Next(0, pool.Length)]); + return new string(chars.ToArray()); + } + + public static Base TestObject() + { + Base rootObject = new() { ["foo"] = "bar" }; + return rootObject; + } + + public static async Task RegisterNewAutomation( + string projectId, + string modelId, + Client speckleClient, + string automationId, + string automationName, + string automationRevisionId + ) + { + GraphQLRequest query = + new( + query: """ + mutation CreateAutomation( + $projectId: String! + $modelId: String! + $automationName: String! + $automationId: String! + $automationRevisionId: String! + ) { + automationMutations { + create( + input: { + projectId: $projectId + modelId: $modelId + automationName: $automationName + automationId: $automationId + automationRevisionId: $automationRevisionId + } + ) + } + } + """, + variables: new + { + projectId, + modelId, + automationName, + automationId, + automationRevisionId, + } + ); + + await speckleClient.ExecuteGraphQLRequest(query); + } +} diff --git a/TestAutomateFunction/Usings.cs b/TestAutomateFunction/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/TestAutomateFunction/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file