8 Commits

Author SHA1 Message Date
Iain Sproat 251d6b7f2d chore(domains): update latest.speckle.dev to latest.speckle.systems (#8) 2024-07-18 16:58:16 +01:00
connorivy d20d3d022a Merge pull request #4 from specklesystems/function-memory
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
Update main.yml
2024-02-16 08:31:27 -06:00
Jedd Morgan b6e9dd9b5d Update main.yml 2024-02-15 15:41:41 +00:00
Claire Kuang fc5a7c680e Update AutomateFunction.cs
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2024-02-07 14:26:55 +00:00
Claire Kuang 5569c0d4fd Update AutomateFunction.cs
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2024-02-07 14:20:32 +00:00
Claire Kuang adc27ae5d3 adds error reporting
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2024-02-07 14:01:24 +00:00
Claire Kuang cacd6f03f5 Update AutomateFunction.cs 2024-02-02 02:20:26 +00:00
Claire Kuang e85e00bff2 Update Utils.cs
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2024-02-02 02:06:55 +00:00
10 changed files with 334 additions and 14 deletions
+1
View File
@@ -34,3 +34,4 @@ jobs:
speckle_token: ${{ secrets.SPECKLE_FUNCTION_TOKEN }}
speckle_function_id: ${{ secrets.SPECKLE_FUNCTION_ID }}
speckle_function_input_schema_file_path: ${{ env.FUNCTION_SCHEMA_FILE_NAME }}
speckle_function_recommended_memory_mi: 8000
+6
View File
@@ -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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestAutomateFunction", "TestAutomateFunction\TestAutomateFunction.csproj", "{B74B115F-D553-4FD5-8E4C-7B13134217DA}"
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
{B74B115F-D553-4FD5-8E4C-7B13134217DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B74B115F-D553-4FD5-8E4C-7B13134217DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B74B115F-D553-4FD5-8E4C-7B13134217DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B74B115F-D553-4FD5-8E4C-7B13134217DA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -4,7 +4,7 @@ using Speckle.Core.Api;
using Speckle.Core.Models;
using SpeckleAutomateDotnetExample;
static class AutomateFunction
public static class AutomateFunction
{
public static string ADDED = "ADDED";
public static string MODIFIED = "MODIFIED";
@@ -19,11 +19,9 @@ static class AutomateFunction
Console.WriteLine("Starting execution");
_ = typeof(ObjectsKit).Assembly; // INFO: Force objects kit to initialize
double tolerance = functionInputs.Tolerance;
// get the testing and release branches
string testBranchName = automationContext.AutomationRunData.BranchName;
string releaseBranchName = testBranchName.Replace("/testing", "/release");
string releaseBranchName = functionInputs.DiffBranch;
Console.WriteLine($"Comparing {testBranchName} against {releaseBranchName}");
Branch? releaseBranch = await automationContext.SpeckleClient
.BranchGet(automationContext.AutomationRunData.ProjectId, releaseBranchName, 1)
@@ -37,7 +35,7 @@ static class AutomateFunction
Commit releaseCommit = releaseBranch.commits.items.First();
if (releaseCommit is null)
{
throw new Exception("Release branch has no commits");
throw new Exception("Diff branch has no commits");
}
// get the test and release commit base
@@ -67,7 +65,7 @@ static class AutomateFunction
out int releaseObjectCount
);
Console.WriteLine(
$"Found {releaseObjectCount} objects in RELEASE with {releaseCommitAppIdDict.Count} unique applicationIds and {releaseCommitSpeckleIdDict} unique speckle ids (for objects with no application id)."
$"Found {releaseObjectCount} objects in RELEASE with {releaseCommitAppIdDict.Count} unique applicationIds and {releaseCommitSpeckleIdDict.Count} unique speckle ids (for objects with no application id)."
);
Utils.CreateDictionaryFromBaseById(
testingCommitObject,
@@ -76,7 +74,7 @@ static class AutomateFunction
out int testingObjectCount
);
Console.WriteLine(
$"Found {testingObjectCount} objects in TESTING with {testingCommitAppIdDict.Count} unique applicationIds and {testingCommitSpeckleIdDict} unique speckle ids (for objects with no application id)."
$"Found {testingObjectCount} objects in TESTING with {testingCommitAppIdDict.Count} unique applicationIds and {testingCommitSpeckleIdDict.Count} unique speckle ids (for objects with no application id)."
);
// COMPARE COMMIT OBJECTS WITH APPLICATION IDS
@@ -249,6 +247,15 @@ static class AutomateFunction
);
}
if (addedAppIdObjects.Count > 0)
{
automationContext.AttachErrorToObjects(
"ADDED",
addedAppIdObjects.Select(o => o.Item1),
"added objects with an application Id"
);
}
foreach (var deleted in deletedAppIdObjects)
{
Console.WriteLine(
@@ -259,7 +266,16 @@ static class AutomateFunction
foreach (var modified in modifiedAppIdObjects)
{
Console.WriteLine(
$"{MODIFIED} {modified.Item3} object: id( {modified.Item1} ), appId: {modified.Item2}. Changed props: {modified.Item4}"
$"{MODIFIED} {modified.Item3} object: id( {modified.Item1} ), appId: {modified.Item2}, category: {modified.Item4}"
);
}
if (modifiedAppIdObjects.Count > 0)
{
automationContext.AttachErrorToObjects(
"MODIFIED",
modifiedAppIdObjects.Select(o => o.Item1),
"modified objects with an application Id"
);
}
@@ -267,6 +283,15 @@ static class AutomateFunction
{
Console.WriteLine($"CHANGED {changed.Item2} object: id( {changed.Item1} )");
}
if (changedSpeckleIdObjects.Count > 0)
{
automationContext.AttachErrorToObjects(
"CHANGED",
changedSpeckleIdObjects.Select(o => o.Item1),
"changed objects with no application Id"
);
}
}
}
}
@@ -5,10 +5,11 @@ using System.ComponentModel.DataAnnotations;
/// </summary>
/// 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 double Tolerance;
//public string Exclusions;
/// <summary>
/// The name of the branch to compare against. This should be the full branch path.
/// </summary>
[Required]
public string DiffBranch;
}
+1 -1
View File
@@ -85,7 +85,7 @@ namespace SpeckleAutomateDotnetExample
);
}
}
else
else if (!string.IsNullOrWhiteSpace(commitObject.id))
{
if (speckleIdDict.ContainsKey(commitObject.id))
{
@@ -0,0 +1,150 @@
# 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
{
// Regression testing function project id
public string projectId = "6ada180f0c";
// e2e release branch and model id
public string releaseBranchName = "e2e/release";
public string releaseModelId = "e4c8cc3802";
// e2e testing branch and model id
public string testingBranchName = "e2e/testing";
public string testingModelId = "c374f0aade";
private async Task<AutomationRunData> AutomationRunData(
Base testObject,
Base releaseObject
)
{
// send the release commit to the release branch
string releaseObjId = await Operations.Send(
releaseObject,
new List<ITransport> { new ServerTransport(client.Account, projectId) }
);
string releaseVersionId = await client.CommitCreate(
new()
{
streamId = projectId,
objectId = releaseObjId,
branchName = releaseBranchName
}
);
// send the test object to the test branch
string testObjId = await Operations.Send(
testObject,
new List<ITransport> { new ServerTransport(client.Account, projectId) }
);
string testingVersionId = await client.CommitCreate(
new()
{
streamId = projectId,
objectId = testObjId,
branchName = testingBranchName
}
);
// create a new automation on the testing branch
var automationName = TestAutomateUtils.RandomString(10);
var automationId = TestAutomateUtils.RandomString(10);
var automationRevisionId = TestAutomateUtils.RandomString(10);
await TestAutomateUtils.RegisterNewAutomation(
projectId,
testingModelId,
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 = testingModelId,
BranchName = testingBranchName,
VersionId = testingVersionId,
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";
Environment.SetEnvironmentVariable(envVarName, "");
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_URL")
?? "https://latest.speckle.systems";
[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(),
TestAutomateUtils.ReleaseObject()
);
var automationContext = await AutomationRunner.RunFunction(
AutomateFunction.Run,
automationRunData,
account.token,
new FunctionInputs { DiffBranch = releaseBranchName }
);
Assert.That(automationContext.RunStatus, Is.EqualTo("FAILED"));
}
public void Dispose()
{
client.Dispose();
}
}
@@ -0,0 +1,11 @@
{
"profiles": {
"TestAutomateFunction": {
"commandName": "Project",
"environmentVariables": {
"SPECKLE_TOKEN": "<YOUR TOKEN HERE>",
"SPECKLE_SERVER_URL": "https://latest.speckle.systems/"
}
}
}
}
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<UserSecretsId>0b5cf4dd-cfa3-4982-9722-ca6c6672b8dd</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="Speckle.Automate.Sdk" Version="2.18.0-fileInput" />
<PackageReference Include="Speckle.Objects" Version="2.18.0-fileInput" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SpeckleAutomateDotnetExample\SpeckleAutomateDotnetExample.csproj" />
</ItemGroup>
</Project>
+98
View File
@@ -0,0 +1,98 @@
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());
}
/// <summary>
/// The test object to compare against the release object
/// </summary>
/// <returns></returns>
/// <remarks>Contains 3 children objects to capture the Added, Deleted, Modified, and Unchanged categories</remarks>
public static Base TestObject()
{
Base unchanged = new() { ["unchangedProp"] = true };
Base added = new() { ["addedProp"] = "added" };
Base modified = new() { ["modifiedProp"] = 1 };
Base testObject = new();
testObject["unchanged"] = unchanged;
testObject["added"] = added;
testObject["modified"] = modified;
return testObject;
}
/// <summary>
/// The release object to compare the test object against
/// </summary>
/// <returns>Contains 3 children objects to capture the Added, Deleted, Modified, and Unchanged categories</returns>
public static Base ReleaseObject()
{
Base unchanged = new() { ["unchangedProp"] = true };
Base deleted = new() { ["deletedProp"] = "deleted" };
Base modified = new() { ["modifiedProp"] = 0.5 };
Base releaseObject = new();
releaseObject["unchanged"] = unchanged;
releaseObject["deleted"] = deleted;
releaseObject["modified"] = modified;
return releaseObject;
}
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<object>(query);
}
}
+1
View File
@@ -0,0 +1 @@
global using NUnit.Framework;