Skip to content

Commit

Permalink
Add copy constructor to VirtualClientComponent to help ensure paramet…
Browse files Browse the repository at this point in the history
…ers, metadata and extensions are passed to components created for client/server scenarios.
  • Loading branch information
brdeyo committed Nov 30, 2024
1 parent b5cebe3 commit a303ba4
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace VirtualClient.Actions
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -41,6 +42,7 @@ public GeekbenchExecutor(IServiceCollection dependencies, IDictionary<string, IC
this.packageManager = dependencies.GetService<IPackageManager>();
this.processManager = dependencies.GetService<ProcessManager>();
this.systemManagement = dependencies.GetService<ISystemManagement>();
this.SupportingExecutables = new List<string>();
}

/// <summary>
Expand All @@ -64,6 +66,13 @@ public string CommandLine
/// </summary>
public string ResultsFilePath { get; set; }

/// <summary>
/// A set of paths for supporting executables of the main process
/// (e.g. geekbench_x86_64, geekbench_aarch64). These typically need to
/// be cleaned up/terminated at the end of each round of processing.
/// </summary>
protected IList<string> SupportingExecutables { get; }

/// <summary>
/// Executes Geek bench
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ namespace VirtualClient.Contracts
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using VirtualClient.Common;
using VirtualClient.Common.Contracts;
using VirtualClient.Common.Telemetry;

[TestFixture]
Expand All @@ -33,6 +35,13 @@ public void VirtualClientComponentConstructorsValidateRequiredParameters()
Assert.Throws<ArgumentException>(() => new TestVirtualClientComponent(null, this.mockFixture.Parameters));
}

[Test]
public void VirtualClientComponentConstructorsValidateRequiredParameters_2()
{
// Copy constructors
Assert.Throws<ArgumentException>(() => new TestVirtualClientComponent(null as VirtualClientComponent));
}

[Test]
public void VirtualClientComponentConstructorsSetPropertiesToExpectedValues()
{
Expand All @@ -48,6 +57,68 @@ public void VirtualClientComponentConstructorsSetPropertiesToExpectedValues()
component.Parameters.Select(p => $"{p.Key}={p.Value}"));
}

[Test]
public void VirtualClientComponentConstructorsSetPropertiesToExpectedValues_2()
{
// The existence of the layout causes the 'Role' parameter to be added automatically.
// We want to do a pure parameter comparison.
this.mockFixture.Dependencies.RemoveAll<EnvironmentLayout>();

// Setup:
// The copy constructor is used more often with client/server implementations. Add in parameters
// common to those scenarios.
this.mockFixture.Parameters[nameof(VirtualClientComponent.ClientRequestId)] = Guid.NewGuid().ToString();
this.mockFixture.Parameters[nameof(VirtualClientComponent.SupportedPlatforms)] = "win-x64,linux-x64";

TestVirtualClientComponent originalComponent = new TestVirtualClientComponent(this.mockFixture.Dependencies, this.mockFixture.Parameters);

// Expectation:
// The following information should be copied from the original component to the new component:
//
// Properties
originalComponent.ExecutionSeed = 7777;
originalComponent.FailFast = true;
originalComponent.LogToFile = true;
originalComponent.SupportedRoles = new List<string> { "Client", "Server" };

// Parameters
originalComponent.Parameters["Parameter"] = 101010;

// Metadata
originalComponent.Metadata.Add("Metadata", 1234);

// Metadata Contract
originalComponent.MetadataContract.Add("ScenarioProperty", 9876, MetadataContractCategory.Scenario);

// Extensions
originalComponent.Extensions.Add("Contacts", JToken.Parse("[ '[email protected]' ]"));

// Copy constructor
VirtualClientComponent component = new TestVirtualClientComponent(originalComponent);

Assert.IsTrue(object.ReferenceEquals(originalComponent.Dependencies, component.Dependencies));
Assert.AreEqual(originalComponent.ClientRequestId, component.ClientRequestId);
Assert.AreEqual(originalComponent.ExecutionSeed, component.ExecutionSeed);
Assert.AreEqual(originalComponent.FailFast, component.FailFast);
Assert.AreEqual(originalComponent.LogToFile, component.LogToFile);
CollectionAssert.AreEquivalent(originalComponent.SupportedPlatforms, component.SupportedPlatforms);
CollectionAssert.AreEquivalent(originalComponent.SupportedRoles, component.SupportedRoles);

CollectionAssert.AreEquivalent(
originalComponent.Parameters.Select(p => $"{p.Key}={p.Value}"),
component.Parameters.Select(p => $"{p.Key}={p.Value}"));

CollectionAssert.AreEquivalent(
originalComponent.Metadata.Select(p => $"{p.Key}={p.Value}"),
component.Metadata.Select(p => $"{p.Key}={p.Value}"));

CollectionAssert.AreEquivalent(
originalComponent.MetadataContract.Get(MetadataContractCategory.Scenario).Select(p => $"{p.Key}={p.Value}"),
component.MetadataContract.Get(MetadataContractCategory.Scenario).Select(p => $"{p.Key}={p.Value}"));

Assert.AreEqual(originalComponent.Extensions["Contacts"], component.Extensions["Contacts"]);
}

[Test]
public void VirtualClientComponentTagsPropertyIsNeverNull()
{
Expand Down Expand Up @@ -601,6 +672,11 @@ public void VirtualClientComponentIsSupportedRespectsSupportedPlatformAttribute(

private class TestVirtualClientComponent : VirtualClientComponent
{
public TestVirtualClientComponent(VirtualClientComponent component)
: base(component)
{
}

public TestVirtualClientComponent(IServiceCollection dependencies, IDictionary<string, IConvertible> parameters)
: base(dependencies, parameters)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,35 @@ public abstract class VirtualClientComponent : IDisposable
private const string Role = "Role";
private ISystemInfo systemInfo;

/// <summary>
/// Initializes a new instance of the <see cref="VirtualClientComponent"/> class.
/// </summary>
/// <param name="component">A component to use as a reference when creating a new instance..</param>
protected VirtualClientComponent(VirtualClientComponent component)
: this(component?.Dependencies, component?.Parameters)
{
this.ClientRequestId = component.ClientRequestId;
this.ExecutionSeed = component.ExecutionSeed;
this.FailFast = component.FailFast;
this.LogToFile = component.LogToFile;
this.MetadataContract = component.MetadataContract;

if (component.Metadata?.Any() == true)
{
this.Metadata.AddRange(component.Metadata);
}

if (component.Extensions?.Any() == true)
{
this.Extensions.AddRange(component.Extensions);
}

if (component.SupportedRoles?.Any() == true)
{
this.SupportedRoles = new List<string>(component.SupportedRoles);
}
}

/// <summary>
/// Initializes a new instance of the <see cref="VirtualClientComponent"/> class.
/// </summary>
Expand Down Expand Up @@ -74,7 +103,7 @@ protected VirtualClientComponent(IServiceCollection dependencies, IDictionary<st
this.MetadataContract = new MetadataContract();
this.PlatformSpecifics = this.systemInfo.PlatformSpecifics;
this.Platform = this.systemInfo.Platform;
this.SupportingExecutables = new List<string>();
this.SupportedRoles = new List<string>();
this.CleanupTasks = new List<Action>();
this.Extensions = new Dictionary<string, JToken>();

Expand Down Expand Up @@ -493,14 +522,7 @@ public IEnumerable<string> SupportedPlatforms
/// The roles that are supported for the executor (e.g. Client, Server). Not all executors support
/// multi-role scenarios.
/// </summary>
public IEnumerable<string> SupportedRoles { get; protected set; }

/// <summary>
/// A set of paths for supporting executables of the main process
/// (e.g. geekbench_x86_64, geekbench_aarch64). These typically need to
/// be cleaned up/terminated at the end of each round of processing.
/// </summary>
public List<string> SupportingExecutables { get; private set; }
public IEnumerable<string> SupportedRoles { get; set; }

/// <summary>
/// The tags defined in the profile arguments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"SupportedPlatforms": "linux-x64,linux-arm64,win-x64,win-arm64"
},
"Parameters": {
"ProfilingEnabled": false,
"ProfilingMode": "None"
"ProfilingEnabled": true,
"ProfilingMode": "OnDemand"
},
"Actions": [
{
Expand Down

0 comments on commit a303ba4

Please sign in to comment.