//[Fact(Skip = "Disabled IIS Express tests because they fail to initialize")] public async Task ABlockedReceivedCallbackWillTriggerAnError() { using (ITestHost host = CreateHost(HostType.IISExpress)) { host.Initialize(); using (var connection = CreateConnection(host, "/echo")) { var wh = new ManualResetEventSlim(); Exception ex = null; connection.DeadlockErrorTimeout = TimeSpan.FromSeconds(1); connection.Received += _ => wh.Wait(TimeSpan.FromSeconds(5)); connection.Error += error => { ex = error; wh.Set(); }; await connection.Start(); // Ensure the received callback is actually called await connection.Send(""); Assert.True(wh.Wait(TimeSpan.FromSeconds(10))); Assert.IsType <SlowCallbackException>(ex); } } }
protected HubConnection CreateAuthHubConnection(ITestHost host, string user, string password) { var path = "/cookieauth/signalr"; var useDefaultUrl = false; var query = new Dictionary <string, string>(); query["test"] = GetTestName() + "." + Interlocked.Increment(ref _id); SetHostData(host, query); var handler = new HttpClientHandler(); handler.CookieContainer = new CookieContainer(); using (var httpClient = new HttpClient(handler)) { var content = string.Format("UserName={0}&Password={1}", user, password); var response = httpClient.PostAsync(host.Url + "/cookieauth/Account/Login", new StringContent(content, Encoding.UTF8, "application/x-www-form-urlencoded")).Result; } var connection = new HubConnection(host.Url + path, query, useDefaultUrl); connection.TransportConnectTimeout = TimeSpan.FromSeconds(10); // Adds 10 seconds to the server's connect timeout (5 seconds) for a total of 15 seconds. connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; connection.CookieContainer = handler.CookieContainer; return(connection); }
public async Task TestLocalRcpEndpointRuntimeVersion(string runtimeVersion, bool enabledExpected) { INameResolver nameResolver = new SimpleNameResolver( new Dictionary <string, string> { { "FUNCTIONS_WORKER_RUNTIME", runtimeVersion }, }); using (ITestHost host = TestHelpers.GetJobHost( this.loggerProvider, nameof(this.TestLocalRcpEndpointRuntimeVersion), enableExtendedSessions: false, localRpcEndpointEnabled: null /* use FUNCTIONS_WORKER_RUNTIME to decide */, nameResolver: nameResolver)) { await host.StartAsync(); // Check to see whether the local RPC endpoint has been opened IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties(); IPEndPoint[] endpoints = ipGlobalProperties.GetActiveTcpListeners(); const string LocalRcpAddress = "127.0.0.1:17071"; if (enabledExpected) { Assert.Contains(LocalRcpAddress, endpoints.Select(ep => ep.ToString())); } else { Assert.DoesNotContain(LocalRcpAddress, endpoints.Select(ep => ep.ToString())); } await host.StopAsync(); } }
public async Task TestLocalRcpEndpointRuntimeVersion(string runtimeVersion, bool enabledExpected) { INameResolver nameResolver = new SimpleNameResolver( new Dictionary <string, string> { { "FUNCTIONS_WORKER_RUNTIME", runtimeVersion }, }); using (ITestHost host = TestHelpers.GetJobHost( this.loggerProvider, nameof(this.TestLocalRcpEndpointRuntimeVersion), enableExtendedSessions: false, localRpcEndpointEnabled: null /* use FUNCTIONS_WORKER_RUNTIME to decide */, nameResolver: nameResolver)) { await host.StartAsync(); // Validate if we opened local RPC endpoint by looking at log statements. var logger = this.loggerProvider.CreatedLoggers.Single(l => l.Category == TestHelpers.LogCategory); var logMessages = logger.LogMessages.ToList(); bool enabledRpcEndpoint = logMessages.Any(msg => msg.Level == Microsoft.Extensions.Logging.LogLevel.Information && msg.FormattedMessage.StartsWith("Opened local RPC endpoint:")); Assert.Equal(enabledExpected, enabledRpcEndpoint); await host.StopAsync(); } }
public static async Task <TestDurableClient> StartOrchestratorAsync( this ITestHost host, string functionName, object input, ITestOutputHelper output, string instanceId = null, bool useTaskHubFromAppSettings = false) { var startFunction = useTaskHubFromAppSettings ? typeof(ClientFunctions).GetMethod(nameof(ClientFunctions.StartFunctionWithTaskHub)) : typeof(ClientFunctions).GetMethod(nameof(ClientFunctions.StartFunction)); var clientRef = new TestDurableClient[1]; var args = new Dictionary <string, object> { { "functionName", functionName }, { "instanceId", instanceId }, { "input", input }, { "clientRef", clientRef }, }; await host.CallAsync(startFunction, args); TestDurableClient client = clientRef[0]; output.WriteLine($"Started {functionName}, Instance ID = {client.InstanceId}"); return(client); }
public CustomTestInstance(CustomTestHost host, TestPath path, TestInstance parent, Type hostType, bool useFixtureInstance) : base(host, path, parent) { HostType = hostType; UseFixtureInstance = useFixtureInstance; customHost = host.Attribute as ITestHost <ITestInstance>; }
//[Fact(Skip = "Disabled IIS Express tests because they fail to initialize")] public async Task ABlockedReceivedCallbackWillTriggerAnError() { using (ITestHost host = CreateHost(HostType.IISExpress)) { host.Initialize(); using (var connection = CreateConnection(host, "/echo")) { var wh = new TaskCompletionSource <object>(); connection.DeadlockErrorTimeout = TimeSpan.FromSeconds(1); connection.Error += error => { wh.TrySetResult(error); }; await connection.Start(); // Ensure the received callback is actually called await connection.Send(""); Assert.IsType <SlowCallbackException>(await wh.Task.OrTimeout(TimeSpan.FromSeconds(10))); } } }
protected void SetHostData(ITestHost host, Dictionary <string, string> query) { foreach (var item in host.ExtraData) { query[item.Key] = item.Value; } }
public async Task BindToBlobViaPOCO(string storageProviderType) { using (ITestHost host = TestHelpers.GetJobHost(this.loggerProvider, nameof(this.BindToBlobViaPOCO), false, storageProviderType)) { await host.StartAsync(); string connectionString = TestHelpers.GetStorageConnectionString(); CloudStorageAccount account = CloudStorageAccount.Parse(connectionString); this.output.WriteLine($"Using storage account: {account.Credentials.AccountName}"); // Blob and container names need to be kept in sync with the activity code. var data = new { InputPrefix = "Input", OutputPrefix = "Output", Suffix = 42, }; const string ContainerName = "test"; string inputBlobName = $"{data.InputPrefix}-{data.Suffix}"; string outputBlobName = $"{data.OutputPrefix}-{data.Suffix}"; CloudBlobClient blobClient = account.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(ContainerName); if (await container.CreateIfNotExistsAsync()) { this.output.WriteLine($"Created container '{container.Name}'."); } string randomData = Guid.NewGuid().ToString("N"); this.output.WriteLine($"Creating blob named {outputBlobName}..."); CloudBlockBlob blob = container.GetBlockBlobReference(inputBlobName); await blob.UploadTextAsync(randomData); this.output.WriteLine($"Uploaded text '{randomData}' to {blob.Name}."); // Using StartOrchestrationArgs to start an activity function because it's easier than creating a new type. var startArgs = new StartOrchestrationArgs(); startArgs.FunctionName = nameof(TestActivities.BindToBlobViaJsonPayload); startArgs.Input = data; var client = await host.StartOrchestratorAsync(nameof(TestOrchestrations.CallActivity), startArgs, this.output); var status = await client.WaitForCompletionAsync(this.output); Assert.Equal(OrchestrationRuntimeStatus.Completed, status?.RuntimeStatus); this.output.WriteLine($"Searching for blob named {outputBlobName}..."); CloudBlockBlob newBlob = container.GetBlockBlobReference(outputBlobName); string copiedData = await newBlob.DownloadTextAsync(); this.output.WriteLine($"Downloaded text '{copiedData}' from {newBlob.Name}."); Assert.Equal(randomData, copiedData); await host.StopAsync(); } }
public CustomTestHost(string name, Type type, Type hostType, TestFlags flags, TestHostAttribute attr, ITestHost <ITestInstance> staticHost, bool useFixtureInstance) : base(TestPathType.Parameter, name, name, type, hostType, flags) { HostType = hostType; Attribute = attr; StaticHost = staticHost; UseFixtureInstance = useFixtureInstance; }
protected Client.Connection CreateConnection(ITestHost host, string path) { var query = new Dictionary<string, string>(); query["test"] = GetTestName(); SetHostData(host, query); var connection = new Client.Connection(host.Url + path, query); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; return connection; }
protected Client.Connection CreateConnection(ITestHost host, string path) { var query = new Dictionary <string, string>(); query["test"] = GetTestName(); SetHostData(host, query); var connection = new Client.Connection(host.Url + path, query); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; return(connection); }
protected HubConnection CreateHubConnection(ITestHost host, string url = null, bool useDefaultUrl = true) { var query = new Dictionary <string, string>(); query["test"] = GetTestName(); SetHostData(host, query); var connection = new HubConnection(url ?? host.Url, query, useDefaultUrl); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; return(connection); }
protected HubConnection CreateHubConnection(ITestHost host, string path = null, bool useDefaultUrl = true) { var query = new Dictionary <string, string>(); query["test"] = GetTestName() + "." + Interlocked.Increment(ref _id); SetHostData(host, query); var connection = new HubConnection(host.Url + path, query, useDefaultUrl); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; return(connection); }
protected Client.Connection CreateConnection(ITestHost host, string path) { var query = new Dictionary <string, string>(); query["test"] = GetTestName() + "." + Interlocked.Increment(ref _id); SetHostData(host, query); var connection = new Client.Connection(host.Url + path, query); connection.TransportConnectTimeout = TimeSpan.FromSeconds(10); // Adds 10 seconds to the server's connect timeout (5 seconds) for a total of 15 seconds. connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; return(connection); }
//[Fact(Skip = "Disabled IIS Express tests because they fail to initialize")] public void WebSocketsTransportFailsIfOnConnectedThrows() { using (ITestHost host = CreateHost(HostType.IISExpress)) { host.Initialize(); var connection = CreateConnection(host, "/fall-back-throws"); using (connection) { Assert.Throws <AggregateException>(() => connection.Start(new WebSocketTransport()).Wait()); } } }
public void ConnectionCanBeEstablishedWithPreSendRequestHeadersEventAttached() { using (ITestHost host = CreateHost(HostType.IISExpress)) { ((IISExpressTestHost)host).AttachToPreSendRequestHeaders = true; host.Initialize(); var connection = CreateConnection(host, "/async-on-connected"); using (connection) { Assert.True(connection.Start().Wait(TimeSpan.FromSeconds(10)), "The connection failed to start."); } } }
public void SelectingDefaultStorageProviderWhenNoTypeIsProvided() { var orchestrationServiceClientMock = new Mock <IOrchestrationServiceClient>(); Mock <IDurabilityProviderFactory> azureStorageMock = GetAzureStorageStorageProviderMock(orchestrationServiceClientMock); Mock <IDurabilityProviderFactory> microsoftSQLMock = GetMicrosoftSQLStorageProviderMock(orchestrationServiceClientMock); Mock <IDurabilityProviderFactory> netheriteMock = GetNetheriteStorageProviderMock(orchestrationServiceClientMock); IEnumerable <IDurabilityProviderFactory> durabilityProviderFactories = new[] { azureStorageMock.Object, microsoftSQLMock.Object, netheriteMock.Object }; using (ITestHost host = TestHelpers.GetJobHostWithMultipleDurabilityProviders( durabilityProviderFactories: durabilityProviderFactories)) { netheriteMock.Verify(n => n.GetDurabilityProvider(), Times.Never()); azureStorageMock.Verify(a => a.GetDurabilityProvider(), Times.Once()); microsoftSQLMock.Verify(m => m.GetDurabilityProvider(), Times.Never()); } }
public void TransportConnectTimeoutDoesNotAddupOverNegotiateRequests() { using (ITestHost host = CreateHost(HostType.IISExpress)) { host.Initialize(); var connection = CreateConnection(host, "/signalr"); connection.TransportConnectTimeout = TimeSpan.FromSeconds(5); using (connection) { connection.Start().Wait(); var totalTransportConnectTimeout = ((Client.IConnection)connection).TotalTransportConnectTimeout; connection.Stop(); connection.Start().Wait(); Assert.Equal(((Client.IConnection)connection).TotalTransportConnectTimeout, totalTransportConnectTimeout); } } }
/// <summary> /// Helper function for the IDurableOrchestrationClientBinding test. Gets an IDurableOrchestrationClient. /// </summary> public static async Task <IDurableOrchestrationClient> GetOrchestrationClientBindingTest( this ITestHost host, ITestOutputHelper output) { var startFunction = typeof(ClientFunctions) .GetMethod(nameof(ClientFunctions.GetOrchestrationClientBindingTest)); var clientRef = new IDurableOrchestrationClient[1]; var args = new Dictionary <string, object> { { "clientRef", clientRef }, }; await host.CallAsync(startFunction, args); IDurableOrchestrationClient client = clientRef[0]; return(client); }
public async Task TimerLengthLessThanMaxTime(bool extendedSessions) { using (ITestHost host = TestHelpers.GetJobHost( this.loggerProvider, nameof(this.TimerLengthLessThanMaxTime), extendedSessions, storageProviderType: "azure_storage", durabilityProviderFactoryType: typeof(AzureStorageShortenedTimerDurabilityProviderFactory))) { await host.StartAsync(); var fireAt = DateTime.UtcNow.AddSeconds(30); var client = await host.StartOrchestratorAsync(nameof(TestOrchestrations.Timer), fireAt, this.output); var status = await client.WaitForCompletionAsync(this.output, timeout : TimeSpan.FromMinutes(2)); Assert.Equal(OrchestrationRuntimeStatus.Completed, status.RuntimeStatus); await host.StopAsync(); } }
public override async Task Initialize(TestContext ctx, CancellationToken cancellationToken) { if (customHost == null) { if (UseFixtureInstance) { customHost = (ITestHost <ITestInstance>)GetFixtureInstance().Instance; } else if (HostType != null) { customHost = (ITestHost <ITestInstance>)Activator.CreateInstance(HostType); } else { throw new InternalErrorException(); } } instance = customHost.CreateInstance(ctx); await instance.Initialize(ctx, cancellationToken); }
public static async Task <TestEntityClient> GetEntityClientAsync( this ITestHost host, EntityId entityId, ITestOutputHelper output) { var startFunction = typeof(ClientFunctions) .GetMethod(nameof(ClientFunctions.GetEntityClient)); var clientRef = new TestEntityClient[1]; var args = new Dictionary <string, object> { { "entityId", entityId }, { "clientRef", clientRef }, }; await host.CallAsync(startFunction, args); TestEntityClient client = clientRef[0]; return(client); }
public async Task WaitForExternalEventAboveMaximumTimerLength() { using (ITestHost host = TestHelpers.GetJobHost( this.loggerProvider, nameof(this.WaitForExternalEventAboveMaximumTimerLength), enableExtendedSessions: false, storageProviderType: "azure_storage", durabilityProviderFactoryType: typeof(AzureStorageShortenedTimerDurabilityProviderFactory))) { await host.StartAsync(); var fireAt = TimeSpan.FromSeconds(90); var client = await host.StartOrchestratorAsync(nameof(TestOrchestrations.ApprovalWithTimeout), (fireAt, "throw"), this.output); var status = await client.WaitForCompletionAsync(this.output, timeout : TimeSpan.FromMinutes(2)); Assert.Equal(OrchestrationRuntimeStatus.Completed, status?.RuntimeStatus); Assert.Equal("TimeoutException", status?.Output); await host.StopAsync(); } }
public async Task InvokeLocalRpcEndpoint() { using (ITestHost host = TestHelpers.GetJobHost( this.loggerProvider, nameof(this.InvokeLocalRpcEndpoint), enableExtendedSessions: false, localRpcEndpointEnabled: true, notificationUrl: null)) { await host.StartAsync(); using (var client = new WebClient()) { string jsonString = client.DownloadString("http://localhost:17071/durabletask/instances"); // The result is expected to be an empty array JArray array = JArray.Parse(jsonString); } await host.StopAsync(); } }
public void StorageProviderTypeSpecified_CorrectStorageProviderFactoryUsed(string storageProvider) { var orchestrationServiceClientMock = new Mock <IOrchestrationServiceClient>(); Mock <IDurabilityProviderFactory> azureStorageMock = GetAzureStorageStorageProviderMock(orchestrationServiceClientMock); Mock <IDurabilityProviderFactory> microsoftSQLMock = GetMicrosoftSQLStorageProviderMock(orchestrationServiceClientMock); Mock <IDurabilityProviderFactory> netheriteMock = GetNetheriteStorageProviderMock(orchestrationServiceClientMock); IEnumerable <IDurabilityProviderFactory> durabilityProviderFactories = new[] { azureStorageMock.Object, microsoftSQLMock.Object, netheriteMock.Object }; DurableTaskOptions options = new DurableTaskOptions(); options.StorageProvider["type"] = storageProvider; using (ITestHost host = TestHelpers.GetJobHostWithMultipleDurabilityProviders( options: options, durabilityProviderFactories: durabilityProviderFactories)) { azureStorageMock.Verify(a => a.GetDurabilityProvider(), string.Equals(storageProvider, "AzureStorage") ? Times.Once() : Times.Never()); microsoftSQLMock.Verify(m => m.GetDurabilityProvider(), string.Equals(storageProvider, "MicrosoftSQL") ? Times.Once() : Times.Never()); netheriteMock.Verify(n => n.GetDurabilityProvider(), string.Equals(storageProvider, "Netherite") ? Times.Once() : Times.Never()); } }
public async Task ActivityTriggerAsNumber(string storageProviderType) { using (ITestHost host = TestHelpers.GetJobHost(this.loggerProvider, nameof(this.ActivityTriggerAsNumber), false, storageProviderType)) { await host.StartAsync(); // Using StartOrchestrationArgs to start an activity function because it's easier than creating a new type. var startArgs = new StartOrchestrationArgs(); startArgs.FunctionName = nameof(TestActivities.BindToDouble); startArgs.Input = 3.14; var client = await host.StartOrchestratorAsync(nameof(TestOrchestrations.CallActivity), startArgs, this.output); var status = await client.WaitForCompletionAsync(this.output); // The function echos back the input value Assert.Equal(OrchestrationRuntimeStatus.Completed, status?.RuntimeStatus); Assert.Equal((double)startArgs.Input, status?.Output); await host.StopAsync(); } }
protected Client.Connection CreateAuthConnection(ITestHost host, string path, string user, string password) { var query = new Dictionary <string, string>(); query["test"] = GetTestName() + "." + Interlocked.Increment(ref _id); SetHostData(host, query); var handler = new HttpClientHandler(); handler.CookieContainer = new CookieContainer(); using (var httpClient = new HttpClient(handler)) { var content = string.Format("UserName={0}&Password={1}", user, password); var response = httpClient.PostAsync(host.Url + "/cookieauth/Account/Login", new StringContent(content, Encoding.UTF8, "application/x-www-form-urlencoded")).Result; } var connection = new Client.Connection(host.Url + "/cookieauth" + path, query); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; connection.CookieContainer = handler.CookieContainer; return(connection); }
protected ITestHost CreateHost(HostType hostType, TransportType transportType) { ITestHost host = null; switch (hostType) { case HostType.IISExpress: host = new IISExpressTestHost(); host.Transport = CreateTransport(transportType); break; case HostType.Memory: var mh = new MemoryHost(); host = new MemoryTestHost(mh); host.Transport = CreateTransport(transportType, mh); break; default: break; } return(host); }
private async Task ActivityTriggerAsJObject(string storageProviderType) { using (ITestHost host = TestHelpers.GetJobHost(this.loggerProvider, nameof(this.ActivityTriggerAsJObject), false, storageProviderType)) { await host.StartAsync(); // Using StartOrchestrationArgs to start an activity function because it's easier than creating a new type. var startArgs = new StartOrchestrationArgs(); startArgs.FunctionName = nameof(TestActivities.BindToJObject); startArgs.Input = new { Foo = "Bar" }; var client = await host.StartOrchestratorAsync(nameof(TestOrchestrations.CallActivity), startArgs, this.output); var status = await client.WaitForCompletionAsync(this.output); // The function checks to see if there is a property called "Foo" which is set to a value // called "Bar" and returns true if this is the case. Otherwise returns false. Assert.Equal(OrchestrationRuntimeStatus.Completed, status?.RuntimeStatus); Assert.True((bool)status?.Output); await host.StopAsync(); } }
public void FallbackToLongPollingIIS() { using (ITestHost host = CreateHost(HostType.IISExpress)) { // Reduce transportConnectionTimeout to 5 seconds host.Initialize(transportConnectTimeout: 5); var connection = CreateConnection(host, "/fall-back"); using (connection) { var tcs = new TaskCompletionSource <object>(); connection.StateChanged += change => { if (change.NewState == ConnectionState.Reconnecting) { tcs.TrySetException(new Exception("The connection should not be reconnecting")); } }; var client = new DefaultHttpClient(); var transports = new IClientTransport[] { new ServerSentEventsTransport(client), new LongPollingTransport(client) }; var transport = new AutoTransport(client, transports); connection.Start(transport).Wait(); Assert.Equal(connection.Transport.Name, "longPolling"); Assert.False(tcs.Task.Wait(TimeSpan.FromSeconds(5))); } } }
protected HubConnection CreateHubConnection(ITestHost host) { var query = new Dictionary<string, string>(); query["test"] = GetTestName(); return new HubConnection(host.Url, query); }
protected void SetHostData(ITestHost host, Dictionary<string, string> query) { foreach (var item in host.ExtraData) { query[item.Key] = item.Value; } }
protected Client.Connection CreateAuthConnection(ITestHost host, string path, string user, string password) { var query = new Dictionary<string, string>(); query["test"] = GetTestName() + "." + Interlocked.Increment(ref _id); SetHostData(host, query); var handler = new HttpClientHandler(); handler.CookieContainer = new CookieContainer(); using (var httpClient = new HttpClient(handler)) { var content = string.Format("UserName={0}&Password={1}", user, password); var response = httpClient.PostAsync(host.Url + "/cookieauth/Account/Login", new StringContent(content, Encoding.UTF8, "application/x-www-form-urlencoded")).Result; } var connection = new Client.Connection(host.Url + "/cookieauth" + path, query); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; connection.CookieContainer = handler.CookieContainer; return connection; }
protected HubConnection CreateHubConnection(ITestHost host, string path = null, bool useDefaultUrl = true) { var query = new Dictionary<string, string>(); query["test"] = GetTestName() + "." + Interlocked.Increment(ref _id); SetHostData(host, query); var connection = new HubConnection(host.Url + path, query, useDefaultUrl); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; return connection; }
protected HubConnection CreateHubConnection(ITestHost host, string url = null, bool useDefaultUrl = true) { var query = new Dictionary<string, string>(); query["test"] = GetTestName(); SetHostData(host, query); var connection = new HubConnection(url ?? host.Url, query, useDefaultUrl); connection.TraceWriter = host.ClientTraceOutput ?? connection.TraceWriter; return connection; }