public void GetHubMethodFromValidHubWhenInvalidHubIsRegisteredDoesNotThrow() { var validHub = new HubDescriptor() { Name = "Valid" }; var invalidHub = new HubDescriptor() { Name = "this.is.not.valid" }; var method = new MethodDescriptor() { Name = "Method", Parameters = new List <ParameterDescriptor>() }; var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IHubDescriptorProvider), () => new TestHubDescriptorProvider(validHub, invalidHub)); resolver.Register(typeof(IMethodDescriptorProvider), () => new TestMethodDescriptorProvider(validHub.Name, method)); var hubManager = new DefaultHubManager(resolver); Assert.Same( method, hubManager.GetHubMethod(validHub.Name, "Method", Array.Empty <IJsonValue>())); }
public void UncleanDisconnectFiresOnDisconnected() { // Arrange var req = new Mock <IRequest>(); req.Setup(m => m.Url).Returns(new Uri("http://foo")); req.Setup(m => m.LocalPath).Returns(""); var qs = new NameValueCollection(); qs["connectionToken"] = "1"; req.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs)); var res = new Mock <IResponse>(); res.SetupProperty(m => m.StatusCode); var dr = new DefaultDependencyResolver(); var context = new HostContext(req.Object, res.Object); var transport = new Mock <ITransport>(); transport.SetupProperty(m => m.Disconnected); transport.SetupProperty(m => m.ConnectionId); transport.Setup(m => m.GetGroupsToken()).Returns(TaskAsyncHelper.FromResult(string.Empty)); transport.Setup(m => m.ProcessRequest(It.IsAny <Connection>())).Returns(TaskAsyncHelper.Empty); var transportManager = new Mock <ITransportManager>(); transportManager.Setup(m => m.GetTransport(context)).Returns(transport.Object); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); dr.Register(typeof(ITransportManager), () => transportManager.Object); dr.Register(typeof(IProtectedData), () => protectedData.Object); var connection = new Mock <PersistentConnection>() { CallBase = true }; var onDisconnectedCalled = false; connection.Protected().Setup("OnDisconnected", req.Object, "1", false).Callback(() => { onDisconnectedCalled = true; }); connection.Object.Initialize(dr); // Act connection.Object.ProcessRequest(context).Wait(); transport.Object.Disconnected(/* clean: */ false); // Assert Assert.True(onDisconnectedCalled); }
protected override IObjectStorage GetStorage() { var resolver = new DefaultDependencyResolver(); resolver.Register <IJsonSerializer, DefaultJsonSerializer>(); resolver.Register <IStorageSerializer, DefaultJsonSerializer>(); return(new IsolatedStorageObjectStorage(resolver)); }
public IsolatedStorageFileExceptionlessLogTests() { var resolver = new DefaultDependencyResolver(); resolver.Register <IExceptionlessLog, NullExceptionlessLog>(); resolver.Register <IJsonSerializer, DefaultJsonSerializer>(); _storage = new IsolatedStorageObjectStorage(resolver); }
protected override IObjectStorage GetStorage() { var resolver = new DefaultDependencyResolver(); resolver.Register <IJsonSerializer, DefaultJsonSerializer>(); resolver.Register <IStorageSerializer, DefaultJsonSerializer>(); resolver.Register <IExceptionlessLog, NullExceptionlessLog>(); return(new FolderObjectStorage(resolver, "temp")); }
private static IDependencyResolver GetDefaultResolver(IReadOnlyList <string> hubs, out IServiceConnectionManager scm) { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IServiceProtocol), () => new ServiceProtocol()); var connectionManager = new ServiceConnectionManager(AppName, hubs); resolver.Register(typeof(IServiceConnectionManager), () => connectionManager); resolver.Register(typeof(IMessageParser), () => new SignalRMessageParser(hubs, resolver)); scm = connectionManager; return(resolver); }
public void CanInjectConstructors() { var resolver = new DefaultDependencyResolver(); resolver.Register <IServiceA, ServiceA>(); resolver.Register <IServiceB, ServiceB>(); var a = resolver.Resolve <IServiceA>(); var b = resolver.Resolve <IServiceB>(); Assert.Equal(a, b.ServiceA); Assert.NotNull(b.ServiceC); }
public void DetailedErrorsFromFaultedTasksCanBeEnabled() { // Arrange var dispatcher = new HubDispatcher(new HubConfiguration() { EnableDetailedErrors = true }); var request = new Mock <IRequest>(); request.Setup(m => m.Url).Returns(new Uri("http://something/signalr/send")); request.Setup(m => m.QueryString).Returns(new NameValueCollection() { { "transport", "longPolling" }, { "connectionToken", "0" }, { "data", "{\"H\":\"ErrorHub\",\"M\":\"ErrorTask\",\"A\":[],\"I\":0}" } }); request.Setup(m => m.Form).Returns(new NameValueCollection()); string contentType = null; var buffer = new List <string>(); var response = new Mock <IResponse>(); response.SetupGet(m => m.CancellationToken).Returns(CancellationToken.None); response.SetupSet(m => m.ContentType = It.IsAny <string>()).Callback <string>(type => contentType = type); response.Setup(m => m.Write(It.IsAny <ArraySegment <byte> >())).Callback <ArraySegment <byte> >(data => buffer.Add(Encoding.UTF8.GetString(data.Array, data.Offset, data.Count))); response.Setup(m => m.End()).Returns(TaskAsyncHelper.Empty); // Act var context = new HostContext(request.Object, response.Object); var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData()); resolver.Register(typeof(ErrorHub), () => new ErrorHub()); dispatcher.Initialize(resolver, context); dispatcher.ProcessRequest(context).Wait(); var json = JsonSerializer.Create(new JsonSerializerSettings()); // Assert Assert.Equal("application/json; charset=UTF-8", contentType); Assert.True(buffer.Count > 0); using (var reader = new StringReader(String.Join(String.Empty, buffer))) { var hubResponse = (HubResponse)json.Deserialize(reader, typeof(HubResponse)); Assert.Equal("Custom Error from task.", hubResponse.Error); } }
public async Task FarmDisconnectRaisesUncleanDisconnects() { // Each node shares the same bus but are independent servers const int nodeCount = 3; var counters = new PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); configurationManager.DisconnectTimeout = TimeSpan.FromSeconds(6); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount)) { var broadcasters = new List <IConnection>(); var disconnectCounter = new DisconnectCounter(); loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); resolver.Register(typeof(IConfigurationManager), () => configurationManager); resolver.Register(typeof(FarmConnection), () => new FarmConnection(disconnectCounter)); var connectionManager = resolver.Resolve <IConnectionManager>(); broadcasters.Add(connectionManager.GetConnectionContext <FarmConnection>().Connection); app.MapSignalR <FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); }); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); await connection.Start(transport); for (int i = 0; i < nodeCount; i++) { broadcasters[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)).Wait(); await Task.Delay(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); await Task.Delay(TimeSpan.FromTicks(TimeSpan.FromSeconds(5).Ticks *nodeCount)); Assert.Equal(0, disconnectCounter.CleanDisconnectCount); Assert.Equal(3, disconnectCounter.UncleanDisconnectCount); } }
public async Task FarmDisconnectRaisesUncleanDisconnects() { // Each node shares the same bus but are independent servers const int nodeCount = 3; var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); configurationManager.DisconnectTimeout = TimeSpan.FromSeconds(6); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount)) { var broadcasters = new List<IConnection>(); var disconnectCounter = new DisconnectCounter(); loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); resolver.Register(typeof(IConfigurationManager), () => configurationManager); resolver.Register(typeof(FarmConnection), () => new FarmConnection(disconnectCounter)); var connectionManager = resolver.Resolve<IConnectionManager>(); broadcasters.Add(connectionManager.GetConnectionContext<FarmConnection>().Connection); app.MapSignalR<FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); }); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); await connection.Start(transport); for (int i = 0; i < nodeCount; i++) { broadcasters[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)).Wait(); await Task.Delay(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); await Task.Delay(TimeSpan.FromTicks(TimeSpan.FromSeconds(5).Ticks * nodeCount)); Assert.Equal(0, disconnectCounter.CleanDisconnectCount); Assert.Equal(3, disconnectCounter.UncleanDisconnectCount); } }
public void Configuration(IAppBuilder app) { DefaultDependencyResolver resolver = new DefaultDependencyResolver(); resolver.Register(typeof(PersistentConnectionListener), () => new PersistentConnectionListener(this.mAdapter)); ConnectionConfiguration connectionConfiguration = new ConnectionConfiguration() { Resolver = resolver, }; if (mSettings.EnableJSONP) { connectionConfiguration.EnableJSONP = true; } app.Map (mSettings.PathMatch, map => { if (mSettings.EnableCors) { map.UseCors(CorsOptions.AllowAll); } map.RunSignalR <PersistentConnectionListener>(connectionConfiguration); }); }
public async Task DisconnectFiresForPersistentConnectionWhenClientDisconnects() { using (var host = new MemoryHost()) { var connectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = dr }; app.MapSignalR <MyConnection>("/echo", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyConnection), () => new MyConnection(connectWh, disconnectWh)); }); var connection = new Client.Connection("http://foo/echo"); await connection.Start(host); Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired"); ((Client.IConnection)connection).Disconnect(); Assert.True(await disconnectWh.WaitAsync(TimeSpan.FromSeconds(20)), "Disconnect never fired"); } }
public async Task TryGetConnectionIdReturningFalseCausesResponseToEndWithProvidedMessageAndStatusCode() { var manager = new TestTransportManager(); var connection = new TokenValidatingPersistentConnection(); var req = new TestRequest(); var resp = new TestResponse(); req.QueryString["connectionToken"] = "wrongToken"; req.QueryString["transport"] = TestTransportManager.TestTransportName; req.LocalPath = "/connect"; var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(ITransportManager), () => manager); // Initialize the connection connection.Initialize(resolver); // Run the request var context = new HostContext(req, resp); await connection.ProcessRequest(context); // Check the connection ID wasn't set and ProcessRequest wasn't called on the transport. Assert.Null(manager.TestTransport.ConnectionId); Assert.Equal(0, manager.TestTransport.ProcessRequestCalls); // Check the response Assert.Equal(TokenValidatingPersistentConnection.ExpectedErrorStatusCode, resp.StatusCode); Assert.Equal(TokenValidatingPersistentConnection.ExpectedErrorMessage, resp.GetBodyAsString()); }
public async Task TryGetConnectionIdIsUsedToExtractConnectionIdFromToken() { var manager = new TestTransportManager(); var connection = new TokenValidatingPersistentConnection(); var req = new TestRequest(); var resp = new TestResponse(); req.QueryString["connectionToken"] = TokenValidatingPersistentConnection.ExpectedConnectionToken; req.QueryString["transport"] = TestTransportManager.TestTransportName; req.LocalPath = "/connect"; var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(ITransportManager), () => manager); // Initialize the connection connection.Initialize(resolver); // Run the request var context = new HostContext(req, resp); await connection.ProcessRequest(context); // Check the connection ID and that the transport was called Assert.Equal(TokenValidatingPersistentConnection.ExpectedConnectionId, manager.TestTransport.ConnectionId); Assert.Equal(1, manager.TestTransport.ProcessRequestCalls); }
public void SubscriptionWithMultipleExistingCursors() { var dr = new DefaultDependencyResolver(); var passThroughMinfier = new PassThroughStringMinifier(); dr.Register(typeof(IStringMinifier), () => passThroughMinfier); using (var bus = new MessageBus(dr)) { Func <ISubscriber> subscriberFactory = () => new TestSubscriber(new[] { "key", "key2" }); var cdKey = new CountDownRange <int>(Enumerable.Range(2, 4)); var cdKey2 = new CountDownRange <int>(new[] { 1, 2, 10 }); IDisposable subscription = null; // Pretend like we had an initial subscription bus.Subscribe(subscriberFactory(), null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); // This simulates a reconnect bus.Publish("test", "key", "1").Wait(); bus.Publish("test", "key", "2").Wait(); bus.Publish("test", "key", "3").Wait(); bus.Publish("test", "key", "4").Wait(); bus.Publish("test", "key2", "1").Wait(); bus.Publish("test", "key2", "2").Wait(); try { subscription = bus.Subscribe(subscriberFactory(), "key,00000001|key2,00000000", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); if (m.Key == "key") { Assert.True(cdKey.Mark(n)); } else { Assert.True(cdKey2.Mark(n)); } } return(TaskAsyncHelper.True); }, 10, null); bus.Publish("test", "key", "5"); bus.Publish("test", "key2", "10"); Assert.True(cdKey.Wait(TimeSpan.FromSeconds(5))); Assert.True(cdKey2.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public async Task DisconnectFiresForHubsWhenClientDisconnects() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); var connectWh = new TaskCompletionSource <object>(); var disconnectWh = new TaskCompletionSource <object>(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); await connection.Start(host); await connectWh.Task.OrTimeout(TimeSpan.FromSeconds(10)); ((Client.IConnection)connection).Disconnect(); await disconnectWh.Task.OrTimeout(TimeSpan.FromSeconds(20)); } }
public void AuthenticatedUserNameMatches() { var connection = new Mock <PersistentConnection>() { CallBase = true }; var req = new Mock <IRequest>(); req.Setup(m => m.User).Returns(new GenericPrincipal(new GenericIdentity("Name"), new string[] { })); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())).Returns <string, string>((value, purpose) => value); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr); var connectionId = connection.Object.GetConnectionId(context, "1:Name"); Assert.Equal("1", connectionId); }
public void UnauthenticatedUserWithAuthenticatedTokenFails() { var connection = new Mock <PersistentConnection>() { CallBase = true }; var req = new Mock <IRequest>(); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())).Returns <string, string>((value, purpose) => value); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr); string connectionId; string message; int statusCode; Assert.Equal(false, connection.Object.TryGetConnectionId(context, "1:::11:::::::1:1", out connectionId, out message, out statusCode)); Assert.Equal(403, statusCode); }
private static IList <string> DoVerifyGroups(string groupsToken, string connectionId, bool hasProtectedData = true) { var connection = new Mock <PersistentConnection>() { CallBase = true }; var req = new Mock <IRequest>(); req.Setup(m => m.Url).Returns(new Uri("http://foo")); req.Setup(m => m.LocalPath).Returns(""); var qs = new NameValueCollection(); qs["transport"] = "serverSentEvents"; qs["connectionToken"] = "1"; qs["groupsToken"] = groupsToken; req.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs)); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => hasProtectedData ? value : null); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr); return(connection.Object.VerifyGroups(connectionId, groupsToken)); }
public void AuthenticatedUserWithColonsInUserName() { var connection = new Mock <PersistentConnection>() { CallBase = true }; var req = new Mock <IRequest>(); req.Setup(m => m.User).Returns(new GenericPrincipal(new GenericIdentity("::11:::::::1:1"), new string[] { })); string connectionId = Guid.NewGuid().ToString("d"); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())).Returns <string, string>((value, purpose) => value); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr); string cid; string message; int statusCode; Assert.Equal(true, connection.Object.TryGetConnectionId(context, connectionId + ":::11:::::::1:1", out cid, out message, out statusCode)); Assert.Equal(connectionId, cid); }
static SignalRGlobalHost() { Resolver = new DefaultDependencyResolver(); RegisterHub <ClientNotificationServiceHub>(); var hubDescriptorProvider = new SignalRHubDescriptorProvider(Hubs); Resolver.Register(typeof(IHubDescriptorProvider), () => hubDescriptorProvider); }
private DefaultDependencyResolver GetDependencyResolver() { var dr = new DefaultDependencyResolver(); var traceManager = new TraceManager(); dr.Register(typeof(ITraceManager), () => traceManager); return(dr); }
public void DisposablesAreTrackedAndDisposed() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(MyDisposable), () => new MyDisposable()); var disposable = resolver.Resolve<MyDisposable>(); resolver.Dispose(); Assert.True(disposable.Disposed); }
public void CanRegisterAndResolveTypes() { var resolver = new DefaultDependencyResolver(); resolver.Register <IServiceA, ServiceA>(); var s1 = resolver.Resolve <IServiceA>(); var s2 = resolver.Resolve <IServiceA>(); Assert.Equal(s1, s2); }
public void Compile_Greeting_Success() { // Arrange var muteCompiler = new Compiler(); var result = muteCompiler.Compile("module foo;\r\nlet s <- import 'greeting' as string;"); var serializer = new StateSerializer(); var deserializer = new StateDeserializer(); var dependencyResolver = new DefaultDependencyResolver(); dependencyResolver.Register <Transaction>(TransactionFactory.CreateNew(null), null); dependencyResolver.Register <ITimeService>(Substitute.For <ITimeService>(), null); dependencyResolver.Register("Hello World!", "greeting"); // Act var state = result.Result(serializer, deserializer, dependencyResolver); // Assert Assert.True(result.Success); }
public void DisposablesAreTrackedAndDisposed() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(MyDisposable), () => new MyDisposable()); var disposable = resolver.Resolve <MyDisposable>(); resolver.Dispose(); Assert.True(disposable.Disposed); }
public void CanUseDataDirectory() { var resolver = new DefaultDependencyResolver(); resolver.Register <IJsonSerializer, DefaultJsonSerializer>(); var storage = new FolderObjectStorage(resolver, DATA_DIRECTORY_QUEUE_FOLDER); Assert.NotNull(storage.Folder); Assert.NotEqual(DATA_DIRECTORY_QUEUE_FOLDER, storage.Folder); Assert.True(storage.Folder.EndsWith("Queue" + Path.DirectorySeparatorChar) || storage.Folder.EndsWith("Queue" + Path.AltDirectorySeparatorChar), storage.Folder); }
public void CanHaveIsolatedContainers() { var resolver1 = new DefaultDependencyResolver(); var resolver2 = new DefaultDependencyResolver(); resolver1.Register <IServiceA, ServiceA>(); resolver2.Register <IServiceA, ServiceA>(); var s1 = resolver1.Resolve <IServiceA>(); var s2 = resolver2.Resolve <IServiceA>(); Assert.NotEqual(s1, s2); }
public void RegisterType_WithDependency_Resolves() { // Arrange var resolver = new DefaultDependencyResolver(); resolver.Register <IDisposable, Instance>(); // Act var result = resolver.GetService <TypeWithDependency>(null); // Assert Assert.NotNull(result.Dependency); }
public void UntrackedDisposablesAreNotTracked() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(MyUntrackedDisposable), () => new MyUntrackedDisposable()); var untrackedDisposable = resolver.Resolve<MyUntrackedDisposable>(); var untrackedDisposableWeakRef = new WeakReference<MyUntrackedDisposable>(untrackedDisposable); untrackedDisposable = null; GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(untrackedDisposableWeakRef.TryGetTarget(out untrackedDisposable)); }
public void RegisterType_ReturnsNewInstance() { // Arrange var resolver = new DefaultDependencyResolver(); resolver.Register <IDisposable, Instance>(); // Act var result = resolver.GetService <IDisposable>(null); // Assert Assert.NotNull(result); }
public static HubConfiguration GetActualHubConfig(ILoggerFactory loggerFactory) { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(ILoggerFactory), () => loggerFactory); var hubConfig = new HubConfiguration { // Resolver is shared in GloblHost, use a new one instead Resolver = resolver }; return(hubConfig); }
public async Task ContextGroupAddCompletesSuccessfully() { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers var counters = new PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); using (EnableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var memoryHost = new MemoryHost()) { memoryHost.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(new HubConfiguration { Resolver = resolver }); }); using (var connection = new HubConnection("http://goo/")) { var proxy = connection.CreateHubProxy("FarmGroupHub"); const string group = "group"; const string message = "message"; var mre = new AsyncManualResetEvent(); proxy.On <string>("message", m => { if (m == message) { mre.Set(); } }); await connection.Start(memoryHost); // Add the connection to a group via an IHubContext on a "second" server. var secondResolver = new DefaultDependencyResolver(); secondResolver.Register(typeof(IMessageBus), () => bus); var secondConnectionManager = secondResolver.Resolve <IConnectionManager>(); var secondHubContext = secondConnectionManager.GetHubContext <FarmGroupHub>(); await secondHubContext.Groups.Add(connection.ConnectionId, group); await proxy.Invoke("SendToGroup", group, message); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public void HubReferencesAreNotRetained() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(DontLeakMeHub), () => new DontLeakMeHub()); var hub = resolver.Resolve<DontLeakMeHub>(); Assert.NotNull(hub); var hubWeakRef = new WeakReference<DontLeakMeHub>(hub); hub.Dispose(); hub = null; GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(hubWeakRef.TryGetTarget(out hub)); }
public void NullUnprotectedConnectionTokenThrows() { var connection = new Mock<PersistentConnection>() { CallBase = true }; var req = new Mock<IRequest>(); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())).Returns((string)null); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr, context); Assert.Throws<InvalidOperationException>(() => connection.Object.GetConnectionId(context, "1")); }
public void AuthenticatedUserNameMatches() { var connection = new Mock<PersistentConnection>() { CallBase = true }; var req = new Mock<IRequest>(); req.Setup(m => m.User).Returns(new GenericPrincipal(new GenericIdentity("Name"), new string[] { })); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())).Returns<string, string>((value, purpose) => value); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr, context); var connectionId = connection.Object.GetConnectionId(context, "1:Name"); Assert.Equal("1", connectionId); }
public void DisconnectFiresForHubsWhenConnectionGoesAway() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); var connectWh = new ManualResetEventSlim(); var disconnectWh = new ManualResetEventSlim(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapHubs("/signalr", config); configuration.DisconnectTimeout = TimeSpan.Zero; configuration.HeartbeatInterval = TimeSpan.FromSeconds(5); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new Client.Hubs.HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval.Ticks * 3); connection.Start(host).Wait(); Assert.True(connectWh.Wait(TimeSpan.FromSeconds(10)), "Connect never fired"); connection.Stop(); Assert.True(disconnectWh.Wait(disconnectWait), "Disconnect never fired"); } }
public ServerNode(IMessageBus bus) { // Give each server it's own dependency resolver Server = new MemoryHost(); Connection = new FarmConnection(); Resolver = new DefaultDependencyResolver(); Resolver.Register(typeof(FarmConnection), () => Connection); Resolver.Register(typeof(IMessageBus), () => bus); var context = Resolver.Resolve<IConnectionManager>().GetConnectionContext<FarmConnection>(); _connection = context.Connection; }
public void DetailedErrorsFromFaultedTasksCanBeEnabled() { // Arrange var dispatcher = new HubDispatcher(new HubConfiguration() { EnableDetailedErrors = true }); var request = GetRequestForUrl("http://something/signalr/send"); request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(new NameValueCollection() { {"transport", "longPolling"}, {"connectionToken", "0"}, {"data", "{\"H\":\"ErrorHub\",\"M\":\"ErrorTask\",\"A\":[],\"I\":0}"} })); request.Setup(m => m.ReadForm()).Returns(Task.FromResult<INameValueCollection>(new NameValueCollectionWrapper())); string contentType = null; var buffer = new List<string>(); var response = new Mock<IResponse>(); response.SetupGet(m => m.CancellationToken).Returns(CancellationToken.None); response.SetupSet(m => m.ContentType = It.IsAny<string>()).Callback<string>(type => contentType = type); response.Setup(m => m.Write(It.IsAny<ArraySegment<byte>>())).Callback<ArraySegment<byte>>(data => buffer.Add(Encoding.UTF8.GetString(data.Array, data.Offset, data.Count))); // Act var context = new HostContext(request.Object, response.Object); var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData()); resolver.Register(typeof(ErrorHub), () => new ErrorHub()); dispatcher.Initialize(resolver); dispatcher.ProcessRequest(context).Wait(); var json = JsonSerializer.Create(new JsonSerializerSettings()); // Assert Assert.Equal("application/json; charset=UTF-8", contentType); Assert.True(buffer.Count > 0); using (var reader = new StringReader(String.Join(String.Empty, buffer))) { var hubResponse = (HubResponse)json.Deserialize(reader, typeof(HubResponse)); Assert.Equal("Custom Error from task.", hubResponse.Error); } }
public void DuplicateHubNamesThrows() { // Arrange var dispatcher = new HubDispatcher(new HubConfiguration()); var request = new Mock<IRequest>(); var qs = new NameValueCollection(); request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs)); qs["connectionData"] = @"[{name: ""foo""}, {name: ""Foo""}]"; var mockHub = new Mock<IHub>(); var mockHubManager = new Mock<IHubManager>(); mockHubManager.Setup(m => m.GetHub("foo")).Returns(new HubDescriptor { Name = "foo", HubType = mockHub.Object.GetType() }); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IHubManager), () => mockHubManager.Object); dispatcher.Initialize(dr); Assert.Throws<InvalidOperationException>(() => dispatcher.Authorize(request.Object)); }
public void SubscriptionWithMultipleExistingCursors() { var dr = new DefaultDependencyResolver(); var passThroughMinfier = new PassThroughStringMinifier(); dr.Register(typeof(IStringMinifier), () => passThroughMinfier); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key", "key2" }); var cdKey = new CountDownRange<int>(Enumerable.Range(2, 4)); var cdKey2 = new CountDownRange<int>(new[] { 1, 2, 10 }); IDisposable subscription = null; bus.Publish("test", "key", "1").Wait(); bus.Publish("test", "key", "2").Wait(); bus.Publish("test", "key", "3").Wait(); bus.Publish("test", "key", "4").Wait(); bus.Publish("test", "key2", "1").Wait(); bus.Publish("test", "key2", "2").Wait(); try { subscription = bus.Subscribe(subscriber, "key,00000001|key2,00000000", result => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.Value); if (m.Key == "key") { Assert.True(cdKey.Mark(n)); } else { Assert.True(cdKey2.Mark(n)); } } return TaskAsyncHelper.True; }, 10); bus.Publish("test", "key", "5"); bus.Publish("test", "key2", "10"); Assert.True(cdKey.Wait(TimeSpan.FromSeconds(5))); Assert.True(cdKey2.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public async Task DisconnectFiresForHubsWhenClientDisconnects() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); var connectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); await connection.Start(host); Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired"); ((Client.IConnection)connection).Disconnect(); Assert.True(await disconnectWh.WaitAsync(TimeSpan.FromSeconds(20)), "Disconnect never fired"); } }
public void UnauthenticatedUserWithAuthenticatedTokenFails() { var connection = new Mock<PersistentConnection>() { CallBase = true }; var req = new Mock<IRequest>(); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())).Returns<string, string>((value, purpose) => value); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr); string connectionId; string message; int statusCode; Assert.Equal(false, connection.Object.TryGetConnectionId(context, "1:::11:::::::1:1", out connectionId, out message, out statusCode)); Assert.Equal(403, statusCode); }
private DefaultDependencyResolver GetDependencyResolver() { var dr = new DefaultDependencyResolver(); var traceManager = new TraceManager(); dr.Register(typeof(ITraceManager), () => traceManager); return dr; }
public void UncleanDisconnectFiresOnDisconnected() { // Arrange var req = new Mock<IRequest>(); req.Setup(m => m.Url).Returns(new Uri("http://foo")); req.Setup(m => m.LocalPath).Returns(""); var qs = new NameValueCollection(); qs["connectionToken"] = "1"; req.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs)); var res = new Mock<IResponse>(); res.SetupProperty(m => m.StatusCode); var dr = new DefaultDependencyResolver(); var context = new HostContext(req.Object, res.Object); var transport = new Mock<ITransport>(); transport.SetupProperty(m => m.Disconnected); transport.Setup(m => m.ProcessRequest(It.IsAny<Connection>())).Returns(TaskAsyncHelper.Empty); var transportManager = new Mock<ITransportManager>(); transportManager.Setup(m => m.GetTransport(context)).Returns(transport.Object); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); dr.Register(typeof(ITransportManager), () => transportManager.Object); dr.Register(typeof(IProtectedData), () => protectedData.Object); var connection = new Mock<PersistentConnection>() { CallBase = true }; var onDisconnectedCalled = false; connection.Protected().Setup("OnDisconnected", req.Object, "1", false).Callback(() => { onDisconnectedCalled = true; }); connection.Object.Initialize(dr); // Act var processRequestTask = connection.Object.ProcessRequest(context); transport.Object.Disconnected(/* clean: */ false); // Assert Assert.Equal(TaskAsyncHelper.Empty, processRequestTask); Assert.True(onDisconnectedCalled); }
public void AuthenticatedUserWithColonsInUserName() { var connection = new Mock<PersistentConnection>() { CallBase = true }; var req = new Mock<IRequest>(); req.Setup(m => m.User).Returns(new GenericPrincipal(new GenericIdentity("::11:::::::1:1"), new string[] { })); string connectionId = Guid.NewGuid().ToString("d"); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())).Returns<string, string>((value, purpose) => value); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr); string cid; string message; int statusCode; Assert.Equal(true, connection.Object.TryGetConnectionId(context, connectionId + ":::11:::::::1:1", out cid, out message, out statusCode)); Assert.Equal(connectionId, cid); }
private static IList<string> DoVerifyGroups(string groupsToken, bool hasProtectedData = true) { var connection = new Mock<PersistentConnection>() { CallBase = true }; var req = new Mock<IRequest>(); req.Setup(m => m.Url).Returns(new Uri("http://foo")); var qs = new NameValueCollection(); qs["transport"] = "serverSentEvents"; qs["connectionToken"] = "1"; qs["groupsToken"] = groupsToken; req.Setup(m => m.QueryString).Returns(qs); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => hasProtectedData ? value : null); var dr = new DefaultDependencyResolver(); dr.Register(typeof(IProtectedData), () => protectedData.Object); var context = new HostContext(req.Object, null); connection.Object.Initialize(dr, context); return connection.Object.VerifyGroups(context); }
public void SubscriptionWithScaleoutCursorGetsOnlyNewMessages() { var dr = new DefaultDependencyResolver(); var passThroughMinfier = new PassThroughStringMinifier(); dr.Register(typeof(IStringMinifier), () => passThroughMinfier); using (var bus = new MessageBus(dr)) { Func<ISubscriber> subscriberFactory = () => new TestSubscriber(new[] { "key" }); var tcs = new TaskCompletionSource<Message[]>(); IDisposable subscription = null; try { // Set-up dummy subscription so the first Publish doesn't noop bus.Subscribe(subscriberFactory(), null, (result, state) => TaskAsyncHelper.True, 10, null).Dispose(); bus.Publish("test", "key", "badvalue").Wait(); subscription = bus.Subscribe(subscriberFactory(), "s-key,00000000", (result, state) => { tcs.TrySetResult(result.GetMessages().ToArray()); return TaskAsyncHelper.True; }, 10, null); bus.Publish("test", "key", "value"); Assert.True(tcs.Task.Wait(TimeSpan.FromSeconds(5))); foreach (var m in tcs.Task.Result) { Assert.Equal("key", m.Key); Assert.Equal("value", m.GetString()); } } finally { if (subscription != null) { subscription.Dispose(); } } } }
public async Task DisconnectFiresForPersistentConnectionWhenClientCallsStop() { using (var host = new MemoryHost()) { var connectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = dr }; app.MapSignalR<MyConnection>("/echo", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyConnection), () => new MyConnection(connectWh, disconnectWh)); }); var connection = new Client.Connection("http://foo/echo"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval().Ticks * 3); await connection.Start(host); Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired"); connection.Stop(); Assert.True(await disconnectWh.WaitAsync(disconnectWait), "Disconnect never fired"); } }
public async Task ContextGroupAddCompletesSuccessfully() { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var memoryHost = new MemoryHost()) { memoryHost.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(new HubConfiguration { Resolver = resolver }); }); using (var connection = new HubConnection("http://goo/")) { var proxy = connection.CreateHubProxy("FarmGroupHub"); const string group = "group"; const string message = "message"; var mre = new AsyncManualResetEvent(); proxy.On<string>("message", m => { if (m == message) { mre.Set(); } }); await connection.Start(memoryHost); // Add the connection to a group via an IHubContext on a "second" server. var secondResolver = new DefaultDependencyResolver(); secondResolver.Register(typeof(IMessageBus), () => bus); var secondConnectionManager = secondResolver.Resolve<IConnectionManager>(); var secondHubContext = secondConnectionManager.GetHubContext<FarmGroupHub>(); await secondHubContext.Groups.Add(connection.ConnectionId, group); await proxy.Invoke("SendToGroup", group, message); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public async Task ConnectionCanAddAnotherConnectionOnAnotherHostToAGroup() { using (var host1 = new MemoryHost()) using (var host2 = new MemoryHost()) { var sharedBus = new DefaultDependencyResolver().Resolve<IMessageBus>(); host1.Configure(app => { var resolver = new DefaultDependencyResolver(); var ackHandler = new SignalR.Infrastructure.AckHandler( completeAcksOnTimeout: true, ackThreshold: TimeSpan.FromSeconds(10), ackInterval: TimeSpan.FromSeconds(1)); resolver.Register(typeof(SignalR.Infrastructure.IAckHandler), () => ackHandler); resolver.Register(typeof(IMessageBus), () => sharedBus); app.MapSignalR<MyGroupConnection>("/groups", new ConnectionConfiguration { Resolver = resolver }); }); host2.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => sharedBus); app.MapSignalR<MyGroupConnection>("/groups", new ConnectionConfiguration { Resolver = resolver }); }); using (var connection1 = new Connection("http://foo/groups")) using (var connection2 = new Connection("http://foo/groups")) { var messageTcs = new TaskCompletionSource<string>(); connection2.Received += message => { messageTcs.SetResult(message); }; await connection1.Start(host1); await connection2.Start(host2); await connection1.Send(new { // Add to group type = 1, group = "testGroup", connectionId = connection2.ConnectionId }); await connection1.Send(new { // Send to group type = 3, group = "testGroup", message = "testMessage" }); Assert.True(messageTcs.Task.Wait(TimeSpan.FromSeconds(10))); Assert.Equal("testMessage", messageTcs.Task.Result); } } }
public async Task FarmGroupAddCompletesSuccessfully(TransportType transportType) { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers const int nodeCount = 2; var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); // Ensure /send and /connect requests get handled by different servers Func<string, int> scheduler = url => url.Contains("/send") ? 0 : 1; using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount, scheduler)) { loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(new HubConfiguration { Resolver = resolver }); }); using (var connection = new HubConnection("http://goo/")) { var proxy = connection.CreateHubProxy("FarmGroupHub"); const string group = "group"; const string message = "message"; var mre = new AsyncManualResetEvent(); proxy.On<string>("message", m => { if (m == message) { mre.Set(); } }); Client.Transports.IClientTransport transport; switch (transportType) { case TransportType.LongPolling: transport = new Client.Transports.LongPollingTransport(loadBalancer); break; case TransportType.ServerSentEvents: transport = new Client.Transports.ServerSentEventsTransport(loadBalancer); break; default: throw new ArgumentException("transportType"); } await connection.Start(transport); await proxy.Invoke("JoinGroup", group); await proxy.Invoke("SendToGroup", group, message); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public void SubscriptionWithMultipleExistingCursors() { var dr = new DefaultDependencyResolver(); var passThroughMinfier = new PassThroughStringMinifier(); dr.Register(typeof(IStringMinifier), () => passThroughMinfier); using (var bus = new MessageBus(dr)) { Func<ISubscriber> subscriberFactory = () => new TestSubscriber(new[] { "key", "key2" }); var cdKey = new CountDownRange<int>(Enumerable.Range(2, 4)); var cdKey2 = new CountDownRange<int>(new[] { 1, 2, 10 }); IDisposable subscription = null; string prefix = DefaultSubscription._defaultCursorPrefix; // Pretend like we had an initial subscription bus.Subscribe(subscriberFactory(), null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); // This simulates a reconnect bus.Publish("test", "key", "1").Wait(); bus.Publish("test", "key", "2").Wait(); bus.Publish("test", "key", "3").Wait(); bus.Publish("test", "key", "4").Wait(); bus.Publish("test", "key2", "1").Wait(); bus.Publish("test", "key2", "2").Wait(); try { subscription = bus.Subscribe(subscriberFactory(), prefix + "key,00000001|key2,00000000", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); if (m.Key == "key") { Assert.True(cdKey.Mark(n)); } else { Assert.True(cdKey2.Mark(n)); } } return TaskAsyncHelper.True; }, 10, null); bus.Publish("test", "key", "5"); bus.Publish("test", "key2", "10"); Assert.True(cdKey.Wait(TimeSpan.FromSeconds(5))); Assert.True(cdKey2.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void DetailedErrorsAreDisabledByDefault() { // Arrange var dispatcher = new HubDispatcher(new HubConfiguration()); var request = new Mock<IRequest>(); request.Setup(m => m.Url).Returns(new Uri("http://something/signalr/send")); request.Setup(m => m.QueryString).Returns(new NameValueCollection() { {"transport", "longPolling"}, {"connectionToken", "0"}, {"data", "{\"H\":\"ErrorHub\",\"M\":\"Error\",\"A\":[],\"I\":0}"} }); request.Setup(m => m.Form).Returns(new NameValueCollection()); string contentType = null; var buffer = new List<string>(); var response = new Mock<IResponse>(); response.SetupGet(m => m.CancellationToken).Returns(CancellationToken.None); response.SetupSet(m => m.ContentType = It.IsAny<string>()).Callback<string>(type => contentType = type); response.Setup(m => m.Write(It.IsAny<ArraySegment<byte>>())).Callback<ArraySegment<byte>>(data => buffer.Add(Encoding.UTF8.GetString(data.Array, data.Offset, data.Count))); response.Setup(m => m.End()).Returns(TaskAsyncHelper.Empty); // Act var context = new HostContext(request.Object, response.Object); var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData()); resolver.Register(typeof(ErrorHub), () => new ErrorHub()); dispatcher.Initialize(resolver, context); dispatcher.ProcessRequest(context).Wait(); var json = JsonSerializer.Create(new JsonSerializerSettings()); // Assert Assert.Equal("application/json; charset=UTF-8", contentType); Assert.Equal(1, buffer.Count); Assert.NotNull(buffer[0]); using (var reader = new StringReader(buffer[0])) { var hubResponse = (HubResponse)json.Deserialize(reader, typeof(HubResponse)); Assert.Contains("ErrorHub.Error", hubResponse.Error); Assert.DoesNotContain("Custom", hubResponse.Error); } }
public void SubscriptionWithExistingCursor() { var dr = new DefaultDependencyResolver(); var passThroughMinfier = new PassThroughStringMinifier(); dr.Register(typeof(IStringMinifier), () => passThroughMinfier); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var cd = new CountDownRange<int>(Enumerable.Range(2, 4)); IDisposable subscription = null; // Pretend like we had an initial subscription bus.Subscribe(subscriber, null, _ => TaskAsyncHelper.True, 10) .Dispose(); bus.Publish("test", "key", "1").Wait(); bus.Publish("test", "key", "2").Wait(); bus.Publish("test", "key", "3").Wait(); bus.Publish("test", "key", "4").Wait(); try { subscription = bus.Subscribe(subscriber, "key,00000001", result => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.Value); Assert.True(cd.Mark(n)); } return TaskAsyncHelper.True; }, 10); bus.Publish("test", "key", "5"); Assert.True(cd.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }