public void RecentlyConnectedEndpointWithoutDiscoveryPermissions() { var translator = new Mock <ITranslateVersionedChannelInformation>(); var translators = new[] { new Tuple <Version, ITranslateVersionedChannelInformation>(new Version(1, 0), translator.Object), }; var template = new Mock <IDiscoveryChannelTemplate>(); { template.Setup(t => t.GenerateBinding()) .Verifiable(); } Func <ChannelTemplate, IDiscoveryChannelTemplate> templateBuilder = t => { return(template.Object); }; var diagnostics = new SystemDiagnostics((l, s) => { }, null); var discovery = new ManualDiscoverySource( translators, templateBuilder, diagnostics); discovery.RecentlyConnectedEndpoint( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), new Uri("net.pipe://localhost/discovery/invalid")); template.Verify(t => t.GenerateBinding(), Times.Never()); }
public void CloseChannel() { var id = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(); var template = new Mock <IDiscoveryChannelTemplate>(); var versionedEndpoint = new Mock <IVersionedDiscoveryEndpoint>(); Func <Version, ChannelTemplate, Tuple <Type, IVersionedDiscoveryEndpoint> > endpointBuilder = (v, t) => new Tuple <Type, IVersionedDiscoveryEndpoint>(versionedEndpoint.Object.GetType(), versionedEndpoint.Object); var host = new Mock <IHoldServiceConnections>(); { host.Setup(h => h.OpenChannel(It.IsAny <IReceiveInformationFromRemoteEndpoints>(), It.IsAny <Func <ServiceHost, ServiceEndpoint> >())) .Returns <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >( (h, e) => new Uri("http://localhost/invalid")); host.Setup(h => h.CloseConnection()) .Verifiable(); } Func <IHoldServiceConnections> hostBuilder = () => host.Object; Action <Uri> storage = u => { }; var channel = new BootstrapChannel( id, template.Object, endpointBuilder, hostBuilder, storage); channel.OpenChannel(true); channel.CloseChannel(); host.Verify(h => h.CloseConnection(), Times.Exactly(2)); }
public void Create() { var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); var id = new DatasetId(); var endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(); var networkId = NetworkIdentifier.ForLocalMachine(); var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var notifications = new Mock <IDatasetApplicationNotifications>(); var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); { notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>())) .Returns(true); notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(endpoint, e)) .Returns(notifications.Object); } var info = new DatasetOnlineInformation( id, endpoint, networkId, commandHub.Object, notificationHub.Object, systemDiagnostics); Assert.AreSame(id, info.Id); Assert.AreSame(endpoint, info.Endpoint); Assert.AreSame(networkId, info.RunsOn); }
public void CompareWithUnequalObjects() { var proposal1 = new DatasetActivationProposal { Endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), IsAvailable = true, ActivationTime = new TimeSpan(50), TransferTime = new TimeSpan(50), PercentageOfAvailableDisk = 50, PercentageOfMaximumMemory = 50, PercentageOfPhysicalMemory = 50, }; var proposal2 = new DatasetActivationProposal { Endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), IsAvailable = true, ActivationTime = new TimeSpan(500), TransferTime = new TimeSpan(500), PercentageOfAvailableDisk = 50, PercentageOfMaximumMemory = 50, PercentageOfPhysicalMemory = 50, }; var comparer = new DatasetActivationProposalComparer(); Assert.AreEqual(-1, comparer.Compare(proposal1, proposal2)); }
public void OpenChannel() { var id = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(); var baseUri = new Uri("http://localhost/invalid"); var versionedEndpointUri = new Uri("http://localhost/invalid/v1"); var template = new Mock <IDiscoveryChannelTemplate>(); { template.Setup( t => t.AttachDiscoveryEntryEndpoint(It.IsAny <ServiceHost>(), It.IsAny <Type>(), It.IsAny <EndpointId>(), It.IsAny <bool>())) .Returns(new ServiceEndpoint(new ContractDescription("a"), new NetNamedPipeBinding(), new EndpointAddress(baseUri))); } var versionedEndpointCounter = 0; var versionedEndpoint = new Mock <IVersionedDiscoveryEndpoint>(); Func <Version, ChannelTemplate, Tuple <Type, IVersionedDiscoveryEndpoint> > endpointBuilder = (v, t) => { versionedEndpointCounter++; return(new Tuple <Type, IVersionedDiscoveryEndpoint>(versionedEndpoint.Object.GetType(), versionedEndpoint.Object)); }; BootstrapEndpoint baseEndpoint = null; var host = new Mock <IHoldServiceConnections>(); { host.Setup(h => h.OpenChannel(It.IsAny <IReceiveInformationFromRemoteEndpoints>(), It.IsAny <Func <ServiceHost, ServiceEndpoint> >())) .Callback <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >( (h, e) => { e(null); baseEndpoint = h as BootstrapEndpoint; }) .Returns <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >( (h, e) => (h is IVersionedDiscoveryEndpoint) ? versionedEndpointUri : baseUri) .Verifiable(); } Func <IHoldServiceConnections> hostBuilder = () => host.Object; Uri entryAddress = null; Action <Uri> storage = u => entryAddress = u; var channel = new BootstrapChannel( id, template.Object, endpointBuilder, hostBuilder, storage); channel.OpenChannel(true); host.Verify( h => h.OpenChannel(It.IsAny <IReceiveInformationFromRemoteEndpoints>(), It.IsAny <Func <ServiceHost, ServiceEndpoint> >()), Times.Exactly(2)); Assert.AreEqual(1, versionedEndpointCounter); Assert.AreEqual(baseUri, entryAddress); Assert.IsNotNull(baseEndpoint); Assert.AreEqual(1, baseEndpoint.DiscoveryVersions().Length); Assert.AreEqual(versionedEndpointUri, baseEndpoint.UriForVersion(baseEndpoint.DiscoveryVersions()[0])); }
public void Invoke() { var uploads = new WaitingUploads(); var layer = new Mock <IProtocolLayer>(); { layer.Setup(l => l.Id) .Returns(new EndpointId("other")); layer.Setup(l => l.SendMessageTo(It.IsAny <EndpointId>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>())) .Callback <EndpointId, ICommunicationMessage, int>( (e, m, r) => { Assert.IsInstanceOf <SuccessMessage>(m); }) .Verifiable(); layer.Setup(l => l.UploadData( It.IsAny <EndpointId>(), It.IsAny <string>(), It.IsAny <CancellationToken>(), It.IsAny <TaskScheduler>(), It.IsAny <int>())) .Returns(Task.Factory.StartNew( () => { }, new CancellationToken(), TaskCreationOptions.None, new CurrentThreadTaskScheduler())) .Verifiable(); } var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var action = new DataDownloadProcessAction( uploads, layer.Object, systemDiagnostics, new CurrentThreadTaskScheduler()); var path = @"c:\temp\myfile.txt"; var token = uploads.Register(path); var msg = new DataDownloadRequestMessage( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), token); action.Invoke(msg); Assert.IsFalse(uploads.HasRegistration(token)); layer.Verify(l => l.SendMessageTo(It.IsAny <EndpointId>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Once()); layer.Verify( l => l.UploadData( It.IsAny <EndpointId>(), It.IsAny <string>(), It.IsAny <CancellationToken>(), It.IsAny <TaskScheduler>(), It.IsAny <int>()), Times.Once()); }
public void RecentlyConnectedEndpointWithCommunicationFault() { var translator = new Mock <ITranslateVersionedChannelInformation>(); var translators = new[] { new Tuple <Version, ITranslateVersionedChannelInformation>(new Version(1, 0), translator.Object), }; var configuration = new Mock <IConfiguration>(); { configuration.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>())) .Returns(false); } var template = new NamedPipeDiscoveryChannelTemplate(configuration.Object); Func <ChannelTemplate, IDiscoveryChannelTemplate> templateBuilder = t => template; var diagnostics = new SystemDiagnostics((l, s) => { }, null); var discovery = new ManualDiscoverySource( translators, templateBuilder, diagnostics); discovery.OnEndpointBecomingAvailable += (s, e) => Assert.Fail(); discovery.StartDiscovery(); var uri = new Uri("net.pipe://localhost/pipe/discovery"); var receiver = new MockEndpoint( () => { throw new ArgumentException(); }, null); var host = new ServiceHost(receiver, uri); var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { TransferMode = TransferMode.Buffered, }; var address = string.Format("{0}_{1}", "ThroughNamedPipe", Process.GetCurrentProcess().Id); var endpoint = host.AddServiceEndpoint(typeof(IBootstrapEndpoint), binding, address); host.Open(); try { discovery.RecentlyConnectedEndpoint( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), endpoint.ListenUri); } finally { host.Close(); } }
public void AvailableCommands() { var id = new DatasetId(); var endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(); var networkId = NetworkIdentifier.ForLocalMachine(); var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var commandList = new Dictionary <Type, ICommandSet> { { typeof(IMockCommandSetWithTaskReturn), new Mock <IMockCommandSetWithTaskReturn>().Object }, { typeof(IMockCommandSetWithTypedTaskReturn), new Mock <IMockCommandSetWithTaskReturn>().Object }, { typeof(IMockCommandSetForInternalUse), new Mock <IMockCommandSetWithTaskReturn>().Object }, }; var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); { commandHub.Setup(h => h.AvailableCommandsFor(It.IsAny <EndpointId>())) .Returns(commandList.Keys); commandHub.Setup(h => h.CommandsFor(It.IsAny <EndpointId>(), It.IsAny <Type>())) .Returns <EndpointId, Type>((e, t) => commandList[t]); } var notifications = new Mock <IDatasetApplicationNotifications>(); var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); { notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>())) .Returns(true); notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(endpoint, e)) .Returns(notifications.Object); } var info = new DatasetOnlineInformation( id, endpoint, networkId, commandHub.Object, notificationHub.Object, systemDiagnostics); var commands = info.AvailableCommands(); Assert.AreEqual(2, commands.Count()); }
public void Close() { var id = new DatasetId(); var endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(); var networkId = NetworkIdentifier.ForLocalMachine(); var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var datasetCommands = new Mock <IDatasetApplicationCommands>(); { datasetCommands.Setup(d => d.Close()) .Returns( Task.Factory.StartNew( () => { }, new CancellationToken(), TaskCreationOptions.None, new CurrentThreadTaskScheduler())) .Verifiable(); } var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); { commandHub.Setup(h => h.HasCommandFor(It.IsAny <EndpointId>(), It.IsAny <Type>())) .Returns(true); commandHub.Setup(h => h.CommandsFor <IDatasetApplicationCommands>(It.IsAny <EndpointId>())) .Returns(datasetCommands.Object); } var notifications = new Mock <IDatasetApplicationNotifications>(); var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); { notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>())) .Returns(true); notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(endpoint, e)) .Returns(notifications.Object); } var info = new DatasetOnlineInformation( id, endpoint, networkId, commandHub.Object, notificationHub.Object, systemDiagnostics); info.Close(); datasetCommands.Verify(d => d.Close(), Times.Once()); }
public void Command() { var id = new DatasetId(); var endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(); var networkId = NetworkIdentifier.ForLocalMachine(); var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var commandList = new SortedList <Type, ICommandSet> { { typeof(IMockCommandSetWithTaskReturn), new Mock <IMockCommandSetWithTaskReturn>().Object }, }; var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); { commandHub.Setup(h => h.CommandsFor <IMockCommandSetWithTaskReturn>(It.IsAny <EndpointId>())) .Returns((IMockCommandSetWithTaskReturn)commandList.Values[0]); } var notifications = new Mock <IDatasetApplicationNotifications>(); var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); { notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>())) .Returns(true); notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(endpoint, e)) .Returns(notifications.Object); } var info = new DatasetOnlineInformation( id, endpoint, networkId, commandHub.Object, notificationHub.Object, systemDiagnostics); var commands = info.Command <IMockCommandSetWithTaskReturn>(); Assert.AreSame(commandList.Values[0], commands); }
public void ProposeDistributionFor() { var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var offlineInfo = CreateOfflineInfo(new Mock <IPersistenceInformation>().Object); var result = new DatasetActivationProposal { Endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), IsAvailable = true, ActivationTime = new TimeSpan(0, 1, 0), TransferTime = new TimeSpan(0, 1, 0), PercentageOfAvailableDisk = 50, PercentageOfMaximumMemory = 50, PercentageOfPhysicalMemory = 50, }; var localDistributor = new Mock <ICalculateDistributionParameters>(); { localDistributor.Setup(l => l.ProposeForLocalMachine(It.IsAny <ExpectedDatasetLoad>())) .Returns(result); } var communicationLayer = new Mock <ICommunicationLayer>(); { communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.NamedPipe))) .Returns( new Tuple <EndpointId, Uri, Uri>( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), new Uri("net.pipe://localhost/pipe"), new Uri("net.pipe://localhost/pipe/data"))); } var loader = new Mock <IDatasetActivator>(); var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); var uploads = new Mock <IStoreUploads>(); var distributor = new LocalDatasetDistributor( localDistributor.Object, loader.Object, commandHub.Object, notificationHub.Object, uploads.Object, (d, e, n) => { return(new DatasetOnlineInformation( d, e, n, commandHub.Object, notificationHub.Object, systemDiagnostics)); }, communicationLayer.Object, systemDiagnostics, new CurrentThreadTaskScheduler()); var request = new DatasetActivationRequest { DatasetToActivate = offlineInfo, ExpectedLoadPerMachine = new ExpectedDatasetLoad(), PreferredLocations = DistributionLocations.All, }; var plans = distributor.ProposeDistributionFor(request, new CancellationToken()); Assert.AreEqual(1, plans.Count()); var plan = plans.First(); Assert.IsTrue(ReferenceEquals(offlineInfo, plan.DistributionFor)); Assert.AreEqual(new NetworkIdentifier(result.Endpoint.OriginatesOnMachine()), plan.MachineToDistributeTo); Assert.IsTrue(ReferenceEquals(result, plan.Proposal)); }
public void ImplementPlan() { var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var filePath = @"c:\temp\myfile.txt"; var storage = new Mock <IPersistenceInformation>(); { storage.Setup(s => s.AsFile()) .Returns(new FileInfo(filePath)); } var offlineInfo = CreateOfflineInfo(storage.Object); var plan = CreateNewDistributionPlan(new DatasetActivationProposal(), offlineInfo, systemDiagnostics); var localDistributor = new Mock <ICalculateDistributionParameters>(); var datasetEndpoint = new EndpointId("OtherMachine:5678"); var loader = new Mock <IDatasetActivator>(); { loader.Setup(l => l.ActivateDataset(It.IsAny <EndpointId>(), It.IsAny <ChannelType>(), It.IsAny <Uri>())) .Returns(datasetEndpoint); } var commands = new Mock <IDatasetApplicationCommands>(); { commands.Setup(c => c.Load(It.IsAny <EndpointId>(), It.IsAny <UploadToken>())) .Returns( Task.Factory.StartNew( () => { }, new CancellationToken(), TaskCreationOptions.None, new CurrentThreadTaskScheduler())); } var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); { commandHub.Setup(h => h.HasCommandsFor(It.IsAny <EndpointId>())) .Returns(true); commandHub.Setup(h => h.HasCommandFor(It.IsAny <EndpointId>(), It.IsAny <Type>())) .Returns(true); commandHub.Setup(h => h.CommandsFor <IDatasetApplicationCommands>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e)) .Returns(commands.Object); } var notifications = new Mock <IDatasetApplicationNotifications>(); var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); { notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>())) .Returns(true); notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e)) .Returns(notifications.Object); } var communicationLayer = new Mock <ICommunicationLayer>(); { communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.NamedPipe))) .Returns( new Tuple <EndpointId, Uri, Uri>( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), new Uri("net.pipe://localhost/pipe"), new Uri("net.pipe://localhost/pipe/data"))); } var uploads = new Mock <IStoreUploads>(); var distributor = new LocalDatasetDistributor( localDistributor.Object, loader.Object, commandHub.Object, notificationHub.Object, uploads.Object, (d, e, n) => { return(new DatasetOnlineInformation( d, e, n, commandHub.Object, notificationHub.Object, systemDiagnostics)); }, communicationLayer.Object, systemDiagnostics, new CurrentThreadTaskScheduler()); Action <int, string, bool> progress = (p, m, e) => { }; var result = distributor.ImplementPlan(plan, new CancellationToken(), progress); result.Wait(); Assert.AreSame(datasetEndpoint, result.Result.Endpoint); Assert.AreSame(plan.DistributionFor.Id, result.Result.Id); Assert.AreSame(plan.MachineToDistributeTo, result.Result.RunsOn); }
/// <summary> /// Takes the set of distribution plans and loads the given datasets onto the specified machines. /// </summary> /// <param name="planToImplement">The distribution plan that should be implemented.</param> /// <param name="token">The token used to indicate cancellation of the task.</param> /// <param name="progressReporter">The action that handles the reporting of progress.</param> /// <returns> /// A set of objects which allow act as proxies for the loaded datasets. /// </returns> public Task <DatasetOnlineInformation> ImplementPlan( DistributionPlan planToImplement, CancellationToken token, Action <int, string, bool> progressReporter) { Func <DatasetOnlineInformation> result = () => { IDatasetActivationCommands activationCommands; lock (m_Lock) { if (!m_ActivatorCommands.ContainsKey(planToImplement.Proposal.Endpoint)) { throw new EndpointNotContactableException(planToImplement.Proposal.Endpoint); } activationCommands = m_ActivatorCommands[planToImplement.Proposal.Endpoint]; } // We shouldn't have to load the TCP channel at this point because that channel would have // been loaded when the loaders broadcast their message indicating that they exist. var info = m_CommunicationLayer.LocalConnectionFor(ChannelType.TcpIP); var endpointTask = activationCommands.Activate(info.Item1, ChannelType.TcpIP, info.Item2, planToImplement.DistributionFor.Id); endpointTask.Wait(); var endpoint = endpointTask.Result; var resetEvent = new AutoResetEvent(false); var commandAvailabilityNotifier = Observable.FromEventPattern <CommandSetAvailabilityEventArgs>( h => m_CommandHub.OnEndpointSignedIn += h, h => m_CommandHub.OnEndpointSignedIn -= h) .Where(args => args.EventArgs.Endpoint.Equals(endpoint)) .Take(1) .Subscribe( args => { resetEvent.Set(); }); using (commandAvailabilityNotifier) { if (!m_CommandHub.HasCommandsFor(endpoint) || !m_NotificationHub.HasNotificationsFor(endpoint)) { resetEvent.WaitOne(); } } EventHandler <ProgressEventArgs> progressHandler = (s, e) => progressReporter(e.Progress, e.Description, e.HasErrors); var notifications = m_NotificationHub.NotificationsFor <IDatasetApplicationNotifications>(endpoint); notifications.OnProgress += progressHandler; try { // Store the file var file = planToImplement.DistributionFor.StoredAt.AsFile(); var uploadToken = m_Uploads.Register(file.FullName); // The commands have been registered, so now load the dataset Debug.Assert( m_CommandHub.HasCommandFor(endpoint, typeof(IDatasetApplicationCommands)), "No application commands registered."); var applicationCommands = m_CommandHub.CommandsFor <IDatasetApplicationCommands>(endpoint); var task = applicationCommands.Load( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), uploadToken); task.Wait(); return(m_DatasetInformationBuilder( planToImplement.DistributionFor.Id, endpoint, planToImplement.MachineToDistributeTo)); } finally { notifications.OnProgress -= progressHandler; } }; return(Task <DatasetOnlineInformation> .Factory.StartNew( result, token, TaskCreationOptions.LongRunning, m_Scheduler)); }
public void RecentlyConnectedEndpoint() { var uri = new Uri("net.pipe://localhost/pipe/discovery/"); var versionedUri = new Uri(uri, new Uri("/1.0", UriKind.Relative)); var protocolInfo = new ProtocolInformation( new Version(2, 0), new Uri("http://localhost/protocol/message/invalid"), new Uri("http://localhost/protocol/data/invalid")); var translator = new Mock <ITranslateVersionedChannelInformation>(); { translator.Setup(t => t.FromUri(It.IsAny <Uri>())) .Callback <Uri>(u => Assert.AreEqual(versionedUri, u)) .Returns(protocolInfo); } var translators = new[] { new Tuple <Version, ITranslateVersionedChannelInformation>(new Version(1, 0), translator.Object), }; var configuration = new Mock <IConfiguration>(); { configuration.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>())) .Returns(false); } var template = new NamedPipeDiscoveryChannelTemplate(configuration.Object); Func <ChannelTemplate, IDiscoveryChannelTemplate> templateBuilder = t => template; var diagnostics = new SystemDiagnostics((l, s) => { }, null); var discovery = new ManualDiscoverySource( translators, templateBuilder, diagnostics); var eventWasRaised = false; discovery.OnEndpointBecomingAvailable += (s, e) => { eventWasRaised = true; }; discovery.StartDiscovery(); var channels = new[] { new Tuple <Version, Uri>(new Version(1, 0), versionedUri), }; var receiver = new BootstrapEndpoint(channels); var host = new ServiceHost(receiver, uri); var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { TransferMode = TransferMode.Buffered, }; var address = string.Format("{0}_{1}", "ThroughNamedPipe", Process.GetCurrentProcess().Id); var endpoint = host.AddServiceEndpoint(typeof(IBootstrapEndpoint), binding, address); host.Open(); try { discovery.RecentlyConnectedEndpoint( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), endpoint.ListenUri); } finally { host.Close(); } Assert.IsTrue(eventWasRaised); }
public void ProposeDistributionFor() { var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var offlineInfo = CreateOfflineInfo(new Mock <IPersistenceInformation>().Object); var result = new DatasetActivationProposal { Endpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), IsAvailable = true, ActivationTime = new TimeSpan(0, 1, 0), TransferTime = new TimeSpan(0, 1, 0), PercentageOfAvailableDisk = 50, PercentageOfMaximumMemory = 50, PercentageOfPhysicalMemory = 50, }; var loaderCommands = new Mock <IDatasetActivationCommands>(); { loaderCommands.Setup(l => l.ProposeFor(It.IsAny <ExpectedDatasetLoad>())) .Returns( Task.Factory.StartNew( () => result, new CancellationToken(), TaskCreationOptions.None, new CurrentThreadTaskScheduler())) .Verifiable(); } var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); { commandHub.Setup(h => h.CommandsFor <IDatasetActivationCommands>(It.IsAny <EndpointId>())) .Returns(loaderCommands.Object); } var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); var offlimitsMachines = new SortedList <string, object> { { "someKeyStuff", "otherMachine" } }; var config = new Mock <IConfiguration>(); { config.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>())) .Returns(true); config.Setup(c => c.Value <IDictionary <string, object> >(It.IsAny <ConfigurationKey>())) .Returns(offlimitsMachines); } var communicationLayer = new Mock <ICommunicationLayer>(); { communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.TcpIP))) .Returns( new Tuple <EndpointId, Uri, Uri>( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), new Uri("net.tcp://localhost/tcp"), new Uri("net.tcp://localhost/tcp/data"))); } var distributor = new RemoteDatasetDistributor( config.Object, commandHub.Object, notificationHub.Object, new Mock <IStoreUploads>().Object, (d, e, n) => new DatasetOnlineInformation( d, e, n, commandHub.Object, notificationHub.Object, systemDiagnostics), communicationLayer.Object, systemDiagnostics, new CurrentThreadTaskScheduler()); // Add the remote endpoints var forbiddenMachineId = new EndpointId("otherMachine:8080"); commandHub.Raise( h => h.OnEndpointSignedIn += null, new CommandSetAvailabilityEventArgs( forbiddenMachineId, new[] { typeof(IDatasetActivationCommands) })); var legalMachineId = new EndpointId("myMachine:8080"); commandHub.Raise( h => h.OnEndpointSignedIn += null, new CommandSetAvailabilityEventArgs( legalMachineId, new[] { typeof(IDatasetActivationCommands) })); var request = new DatasetActivationRequest { DatasetToActivate = offlineInfo, ExpectedLoadPerMachine = new ExpectedDatasetLoad(), PreferredLocations = DistributionLocations.All, }; var plans = distributor.ProposeDistributionFor(request, new CancellationToken()); var listPlans = plans.ToList(); Assert.AreEqual(1, listPlans.Count()); var plan = listPlans[0]; Assert.IsTrue(ReferenceEquals(offlineInfo, plan.DistributionFor)); Assert.AreEqual(new NetworkIdentifier(result.Endpoint.OriginatesOnMachine()), plan.MachineToDistributeTo); Assert.IsTrue(ReferenceEquals(result, plan.Proposal)); loaderCommands.Verify(l => l.ProposeFor(It.IsAny <ExpectedDatasetLoad>()), Times.Once()); }
public void ImplementPlan() { var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var loaderEndpoint = new EndpointId("myMachine:8080"); var proposal = new DatasetActivationProposal { Endpoint = loaderEndpoint, IsAvailable = true, ActivationTime = new TimeSpan(0, 1, 0), TransferTime = new TimeSpan(0, 1, 0), PercentageOfAvailableDisk = 50, PercentageOfMaximumMemory = 50, PercentageOfPhysicalMemory = 50, }; var filePath = @"c:\temp\myfile.txt"; var storage = new Mock <IPersistenceInformation>(); { storage.Setup(s => s.AsFile()) .Returns(new FileInfo(filePath)); } var plan = CreateNewDistributionPlan(proposal, CreateOfflineInfo(storage.Object), systemDiagnostics); var datasetEndpoint = new EndpointId("OtherMachine:5678"); var loaderCommands = new Mock <IDatasetActivationCommands>(); { loaderCommands.Setup(l => l.Activate(It.IsAny <EndpointId>(), It.IsAny <ChannelType>(), It.IsAny <Uri>(), It.IsAny <DatasetId>())) .Returns( Task.Factory.StartNew( () => datasetEndpoint, new CancellationToken(), TaskCreationOptions.None, new CurrentThreadTaskScheduler())); } var applicationCommands = new Mock <IDatasetApplicationCommands>(); { applicationCommands.Setup(c => c.Load(It.IsAny <EndpointId>(), It.IsAny <UploadToken>())) .Returns( Task.Factory.StartNew( () => { }, new CancellationToken(), TaskCreationOptions.None, new CurrentThreadTaskScheduler())); } var commandHub = new Mock <ISendCommandsToRemoteEndpoints>(); { commandHub.Setup(h => h.HasCommandsFor(It.IsAny <EndpointId>())) .Returns(true); commandHub.Setup(h => h.CommandsFor <IDatasetActivationCommands>(It.IsAny <EndpointId>())) .Returns(loaderCommands.Object); commandHub.Setup(h => h.CommandsFor <IDatasetApplicationCommands>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e)) .Returns(applicationCommands.Object); } var notifications = new Mock <IDatasetApplicationNotifications>(); var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>(); { notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>())) .Returns(true); notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>())) .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e)) .Returns(notifications.Object); } var config = new Mock <IConfiguration>(); { config.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>())) .Returns(false); } var communicationLayer = new Mock <ICommunicationLayer>(); { communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.TcpIP))) .Returns( new Tuple <EndpointId, Uri, Uri>( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), new Uri("net.tcp://localhost/tcp"), new Uri("net.tcp://localhost/tcp/data"))); } var distributor = new RemoteDatasetDistributor( config.Object, commandHub.Object, notificationHub.Object, new Mock <IStoreUploads>().Object, (d, e, n) => new DatasetOnlineInformation( d, e, n, commandHub.Object, notificationHub.Object, systemDiagnostics), communicationLayer.Object, systemDiagnostics, new CurrentThreadTaskScheduler()); // Add the remote endpoints commandHub.Raise( h => h.OnEndpointSignedIn += null, new CommandSetAvailabilityEventArgs( loaderEndpoint, new[] { typeof(IDatasetActivationCommands) })); Action <int, string, bool> progress = (p, m, e) => { }; var result = distributor.ImplementPlan(plan, new CancellationToken(), progress); result.Wait(); Assert.AreSame(datasetEndpoint, result.Result.Endpoint); Assert.AreSame(plan.DistributionFor.Id, result.Result.Id); Assert.AreSame(plan.MachineToDistributeTo, result.Result.RunsOn); }
private static void RunApplication(string[] args, ApplicationContext context) { string hostIdText = null; string channelUriText = null; var communicationSubjects = new List <CommunicationSubject>(); var options = new OptionSet { { Resources.CommandLine_Param_Host_Key, Resources.CommandLine_Param_Host_Description, v => hostIdText = v }, { Resources.CommandLine_Param_ChannelUri_Key, Resources.CommandLine_Param_ChannelUri_Description, v => channelUriText = v }, { Resources.CommandLine_Options_CommunicationSubject_Key, Resources.CommandLine_Options_CommunicationSubject_Description, v => communicationSubjects.Add(new CommunicationSubject(v)) }, }; try { options.Parse(args); } catch (OptionException) { return; } context.ThreadExit += (s, e) => s_Container.Dispose(); var allowChannelDiscovery = (hostIdText == null) || (channelUriText == null); s_Container = DependencyInjection.CreateContainer(context, communicationSubjects, allowChannelDiscovery); s_Container.Resolve <IFormTheApplicationCenter>(); if (!allowChannelDiscovery) { var hostId = EndpointIdExtensions.Deserialize(hostIdText); var diagnostics = s_Container.Resolve <SystemDiagnostics>(); diagnostics.Log( LevelToLog.Debug, string.Format( CultureInfo.InvariantCulture, Resources.Log_Messages_ConnectingToHost_WithConnectionParameters, hostId, channelUriText)); var resolver = s_Container.Resolve <ManualEndpointConnection>(); resolver(hostId, channelUriText); } var window = s_Container.Resolve <IInteractiveWindow>(); ElementHost.EnableModelessKeyboardInterop(window as Window); window.Show(); }
/// <summary> /// Takes the set of distribution plans and loads the given datasets onto the specified machines. /// </summary> /// <param name="planToImplement">The distribution plan that should be implemented.</param> /// <param name="token">The token used to indicate cancellation of the task.</param> /// <param name="progressReporter">The action that handles the reporting of progress.</param> /// <returns> /// A set of objects which allow act as proxies for the loaded datasets. /// </returns> public Task <DatasetOnlineInformation> ImplementPlan( DistributionPlan planToImplement, CancellationToken token, Action <int, string, bool> progressReporter) { Func <DatasetOnlineInformation> result = () => { m_Diagnostics.Log(LevelToLog.Info, BaseConstants.LogPrefix, "Activating dataset"); var info = m_CommunicationLayer.LocalConnectionFor(ChannelType.NamedPipe); EndpointId endpoint; try { endpoint = m_Loader.ActivateDataset(info.Item1, ChannelType.NamedPipe, info.Item2); } catch (Exception e) { m_Diagnostics.Log( LevelToLog.Error, BaseConstants.LogPrefix, string.Format( CultureInfo.InvariantCulture, "Failed to activate the dataset. Error was: {0}", e)); throw; } var resetEvent = new AutoResetEvent(false); var commandAvailabilityNotifier = Observable.FromEventPattern <CommandSetAvailabilityEventArgs>( h => m_CommandHub.OnEndpointSignedIn += h, h => m_CommandHub.OnEndpointSignedIn -= h) .Where(args => args.EventArgs.Endpoint.Equals(endpoint)) .Take(1); var notificationAvailabilityNotifier = Observable.FromEventPattern <NotificationSetAvailabilityEventArgs>( h => m_NotificationHub.OnEndpointSignedIn += h, h => m_NotificationHub.OnEndpointSignedIn -= h) .Where(args => args.EventArgs.Endpoint.Equals(endpoint)) .Take(1); var availability = commandAvailabilityNotifier.Zip( notificationAvailabilityNotifier, (a, b) => { return(true); }) .Subscribe( args => { resetEvent.Set(); }); using (availability) { if (!m_CommandHub.HasCommandsFor(endpoint) || !m_NotificationHub.HasNotificationsFor(endpoint)) { m_Diagnostics.Log(LevelToLog.Trace, BaseConstants.LogPrefix, "Waiting for dataset to connect."); resetEvent.WaitOne(); } } m_Diagnostics.Log(LevelToLog.Trace, "Received commands and notifications from dataset."); IDatasetApplicationNotifications notifications; try { notifications = m_NotificationHub.NotificationsFor <IDatasetApplicationNotifications>(endpoint); } catch (Exception e) { m_Diagnostics.Log( LevelToLog.Error, BaseConstants.LogPrefix, string.Format( CultureInfo.InvariantCulture, "Failed to get the notifications. Error was: {0}", e)); throw; } EventHandler <ProgressEventArgs> progressHandler = (s, e) => progressReporter(e.Progress, e.Description, e.HasErrors); notifications.OnProgress += progressHandler; try { // Store the file var file = planToImplement.DistributionFor.StoredAt.AsFile(); var uploadToken = m_Uploads.Register(file.FullName); // The commands have been registered, so now load the dataset Debug.Assert( m_CommandHub.HasCommandFor(endpoint, typeof(IDatasetApplicationCommands)), "No application commands registered."); var commands = m_CommandHub.CommandsFor <IDatasetApplicationCommands>(endpoint); var task = commands.Load( EndpointIdExtensions.CreateEndpointIdForCurrentProcess(), uploadToken); task.Wait(); // Now the dataset loading is complete return(m_DatasetInformationBuilder( planToImplement.DistributionFor.Id, endpoint, planToImplement.MachineToDistributeTo)); } finally { notifications.OnProgress -= progressHandler; } }; return(Task <DatasetOnlineInformation> .Factory.StartNew( result, token, TaskCreationOptions.LongRunning, m_Scheduler)); }
/// <summary> /// Initializes a new instance of the <see cref="DistributionCalculator"/> class. /// </summary> public DistributionCalculator() { m_LocalEndpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(); }
private static int RunApplication(string[] arguments, ApplicationContext context) { string hostIdText = null; string channelTypeText = null; string channelUriText = null; // Parse the command line options var options = new OptionSet { { "h=|host=", "The {ENDPOINTID} of the host application that requested the start of this application.", v => hostIdText = v }, { "t=|channeltype=", "The {TYPE} of the channel over which the connection should be made.", v => channelTypeText = v }, { "u=|channeluri=", "The {URI} of the connection that can be used to connect to the host application.", v => channelUriText = v }, }; options.Parse(arguments); if (string.IsNullOrWhiteSpace(hostIdText) || string.IsNullOrWhiteSpace(channelTypeText) || string.IsNullOrWhiteSpace(channelUriText)) { throw new InvalidCommandLineArgumentsException(); } // Load the communication system and get it going // All startables are automatically started once the container gets // build. // The container will stay in scope as long as the app runs, because // we won't exit the app until we exit this method, which happens // when we exit the main message loop. var container = DependencyInjection.Load(context); var hostId = EndpointIdExtensions.Deserialize(hostIdText); var channelType = (ChannelType)Enum.Parse(typeof(ChannelType), channelTypeText); // Notify the host app that we're alive, after which the // rest of the app should pick up the loading of the dataset etc. // Note that this call to the container also registers all global commands and initializes the // communication channels etc. var resolver = container.Resolve <ManualEndpointConnection>(); resolver(hostId, channelType, channelUriText); // Connect to the assembly resolve event so that we can intercept assembly loads for plugins etc. var assemblyResolver = container.Resolve <PluginLoadingAssemblyResolver>( new TypedParameter( typeof(EndpointId), EndpointIdExtensions.Deserialize(hostIdText))); AppDomain.CurrentDomain.AssemblyResolve += assemblyResolver.LocatePluginAssembly; // Start with the message processing loop and then we // wait for it to either get terminated or until we kill ourselves. Application.Run(context); return(NormalApplicationExitCode); }