public static Await ( Func |
||
condition | Func |
|
timeout | int | |
pollingInterval | int | |
리턴 | System.Threading.Tasks.Task |
protected async Task <Document> WaitForDocumentAsync(string itemId, string textToMatch = null) { var docUri = UriFactory.CreateDocumentUri("ItemDb", "ItemCollection", itemId); // We know the tests are using the default connection string. var connectionString = _configuration.GetConnectionString("CosmosDB"); var builder = new DbConnectionStringBuilder { ConnectionString = connectionString }; var serviceUri = new Uri(builder["AccountEndpoint"].ToString()); var client = new DocumentClient(serviceUri, builder["AccountKey"].ToString()); Document doc = null; await TestHelpers.Await(async() => { bool result = false; try { var response = await client.ReadDocumentAsync(docUri); doc = response.Resource; } catch (DocumentClientException ex) when(ex.Error.Code == "NotFound") { return(false); } if (textToMatch != null) { result = doc.GetPropertyValue <string>("text") == textToMatch; } else { result = true; } return(result); }, userMessageCallback : () => { // AppVeyor only shows 4096 chars var s = string.Join(Environment.NewLine, Fixture.Host.GetLogMessages()); return(s.Length < 4096 ? s : s.Substring(s.Length - 4096)); }); return(doc); }
public async Task StandbyModeE2E_Dotnet() { _settings.Add(EnvironmentSettingNames.AzureWebsiteInstanceId, Guid.NewGuid().ToString()); var environment = new TestEnvironment(_settings); await InitializeTestHostAsync("Windows", environment); await VerifyWarmupSucceeds(); await VerifyWarmupSucceeds(restart : true); // now specialize the host environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0"); environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteContainerReady, "1"); environment.SetEnvironmentVariable(LanguageWorkerConstants.FunctionWorkerRuntimeSettingName, "dotnet"); Assert.False(environment.IsPlaceholderModeEnabled()); Assert.True(environment.IsContainerReady()); // give time for the specialization to happen string[] logLines = null; await TestHelpers.Await(() => { // wait for the trace indicating that the host has been specialized logLines = _loggerProvider.GetAllLogMessages().Where(p => p.FormattedMessage != null).Select(p => p.FormattedMessage).ToArray(); return(logLines.Contains("Generating 0 job function(s)") && logLines.Contains("Stopping JobHost")); }, userMessageCallback : () => string.Join(Environment.NewLine, _loggerProvider.GetAllLogMessages().Select(p => $"[{p.Timestamp.ToString("HH:mm:ss.fff")}] {p.FormattedMessage}"))); // verify the rest of the expected logs logLines = _loggerProvider.GetAllLogMessages().Where(p => p.FormattedMessage != null).Select(p => p.FormattedMessage).ToArray(); Assert.True(logLines.Count(p => p.Contains("Stopping JobHost")) >= 1); Assert.Equal(1, logLines.Count(p => p.Contains("Creating StandbyMode placeholder function directory"))); Assert.Equal(1, logLines.Count(p => p.Contains("StandbyMode placeholder function directory created"))); Assert.Equal(2, logLines.Count(p => p.Contains("Host is in standby mode"))); Assert.Equal(2, logLines.Count(p => p.Contains("Executed 'Functions.WarmUp' (Succeeded"))); Assert.Equal(1, logLines.Count(p => p.Contains("Starting host specialization"))); Assert.Equal(1, logLines.Count(p => p.Contains("Starting language worker channel specialization"))); Assert.Equal(3, logLines.Count(p => p.Contains($"Starting Host (HostId={_expectedHostId}"))); Assert.Equal(3, logLines.Count(p => p.Contains($"Loading functions metadata"))); Assert.Equal(2, logLines.Count(p => p.Contains($"1 functions loaded"))); Assert.Equal(1, logLines.Count(p => p.Contains($"0 functions loaded"))); Assert.Equal(1, logLines.Count(p => p.Contains($"Loading proxies metadata"))); Assert.Equal(1, logLines.Count(p => p.Contains("Initializing Azure Function proxies"))); Assert.Equal(1, logLines.Count(p => p.Contains($"0 proxies loaded"))); Assert.Contains("Generating 0 job function(s)", logLines); // Verify that the internal cache has reset Assert.NotSame(GetCachedTimeZoneInfo(), _originalTimeZoneInfoCache); }
public async Task MultipleHostRestarts() { string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString()); Directory.CreateDirectory(functionTestDir); string logDir = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString()); string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString()); ScriptHostConfiguration config = new ScriptHostConfiguration { RootLogPath = logDir, RootScriptPath = functionTestDir, FileLoggingMode = FileLoggingMode.Always, }; ISecretsRepository repository = new FileSystemSecretsRepository(_secretsDirectory.Path); SecretManager secretManager = new SecretManager(_settingsManager, repository, NullTraceWriter.Instance, null); WebHostSettings webHostSettings = new WebHostSettings(); webHostSettings.SecretsPath = _secretsDirectory.Path; var mockEventManager = new Mock <IScriptEventManager>(); var factoryMock = new Mock <IScriptHostFactory>(); int count = 0; factoryMock.Setup(p => p.Create(It.IsAny <IScriptHostEnvironment>(), It.IsAny <IScriptEventManager>(), _settingsManager, config)).Callback(() => { count++; }).Throws(new Exception("Kaboom!")); ScriptHostManager hostManager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), mockEventManager.Object, _settingsManager, webHostSettings, factoryMock.Object); Task runTask = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => { return(count > 3); }); hostManager.Stop(); Assert.Equal(ScriptHostState.Default, hostManager.State); // regression test: previously on multiple restarts we were recomposing // the writer on each restart, resulting in a nested chain of writers // increasing on each restart Assert.Equal(typeof(SystemTraceWriter), config.TraceWriter.GetType()); }
public async Task HasLease_WhenLeaseIsAcquired_ReturnsTrue() { string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); string hostId = Guid.NewGuid().ToString(); string instanceId = Guid.NewGuid().ToString(); var traceWriter = new TestTraceWriter(System.Diagnostics.TraceLevel.Verbose); using (var manager = await BlobLeaseManager.CreateAsync(connectionString, TimeSpan.FromSeconds(15), hostId, instanceId, traceWriter)) { await TestHelpers.Await(() => manager.HasLease); Assert.Equal(instanceId, manager.LeaseId); } await ClearLeaseBlob(hostId); }
public async Task RunAndBlock_ParseError_LogsError() { TestLoggerProvider loggerProvider = new TestLoggerProvider(); TestLoggerProviderFactory factory = new TestLoggerProviderFactory(loggerProvider, includeDefaultLoggerProviders: false); string rootPath = Path.Combine(Environment.CurrentDirectory, "ScriptHostTests"); if (!Directory.Exists(rootPath)) { Directory.CreateDirectory(rootPath); } var configPath = Path.Combine(rootPath, "host.json"); File.WriteAllText(configPath, @"{<unparseable>}"); var config = new ScriptHostConfiguration() { RootScriptPath = rootPath }; config.HostConfig.HostId = ID; var scriptHostFactory = new TestScriptHostFactory(); var eventManagerMock = new Mock <IScriptEventManager>(); var hostManager = new ScriptHostManager(config, _settingsManager, scriptHostFactory, eventManagerMock.Object, loggerProviderFactory: factory); Task taskIgnore = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => hostManager.State == ScriptHostState.Error, 3000, 50); Assert.Equal(ScriptHostState.Error, hostManager.State); hostManager.Stop(); var ex = hostManager.LastError; Assert.True(ex is FormatException); var expectedMessage = $"Unable to parse host configuration file '{configPath}'."; Assert.Equal(expectedMessage, ex.Message); var logger = loggerProvider.CreatedLoggers.Last(); var logMessage = logger.GetLogMessages()[0]; Assert.StartsWith("A ScriptHost error has occurred", logMessage.FormattedMessage); Assert.Equal(expectedMessage, logMessage.Exception.Message); }
public async Task Invoke_CallsFunction() { string testFunctionName = "TestFunction"; string triggerParameterName = "testTrigger"; string testInput = Guid.NewGuid().ToString(); bool functionInvoked = false; hostMock.Setup(p => p.CallAsync(It.IsAny <string>(), It.IsAny <Dictionary <string, object> >(), CancellationToken.None)) .Callback <string, Dictionary <string, object>, CancellationToken>((name, args, token) => { // verify the correct arguments were passed to the invoke Assert.Equal(testFunctionName, name); Assert.Equal(1, args.Count); Assert.Equal(testInput, (string)args[triggerParameterName]); functionInvoked = true; }) .Returns(Task.CompletedTask); // Add a few parameters, with the trigger parameter last // to verify parameter order handling Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor> { new ParameterDescriptor("context", typeof(ExecutionContext)), new ParameterDescriptor("log", typeof(TraceWriter)), new ParameterDescriptor(triggerParameterName, typeof(string)) { IsTrigger = true } }; testFunctions.Add(new FunctionDescriptor(testFunctionName, null, null, parameters, null, null, null)); FunctionInvocation invocation = new FunctionInvocation { Input = testInput }; IActionResult response = testController.Invoke(testFunctionName, invocation); Assert.IsType <AcceptedResult>(response); // The call is fire-and-forget, so watch for functionInvoked to be set. await TestHelpers.Await(() => functionInvoked, timeout : 3000, pollingInterval : 100); Assert.True(functionInvoked); }
public async Task TimerTrigger() { // job is running every second, so give it a few seconds to // generate some output await TestHelpers.Await(() => { if (File.Exists(JobLogTestFileName)) { string[] lines = File.ReadAllLines(JobLogTestFileName); return(lines.Length > 2); } else { return(false); } }, timeout : 10 * 1000); }
public async Task HasLeaseChanged_WhenLeaseIsLostAndStateChanges_IsFired() { string hostId = Guid.NewGuid().ToString(); string instanceId = Guid.NewGuid().ToString(); string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); ICloudBlob blob = await GetLockBlobAsync(connectionString, hostId); var traceWriter = new TestTraceWriter(TraceLevel.Verbose); var resetEvent = new ManualResetEventSlim(); PrimaryHostCoordinator manager = null; string tempLeaseId = null; var lockManager = CreateLockManager(); var renewalInterval = TimeSpan.FromSeconds(3); using (manager = PrimaryHostCoordinator.Create(lockManager, TimeSpan.FromSeconds(15), hostId, instanceId, traceWriter, null, renewalInterval)) { try { await TestHelpers.Await(() => manager.HasLease); manager.HasLeaseChanged += (s, a) => resetEvent.Set(); // Release the manager's lease and acquire one with a different id await lockManager.ReleaseLockAsync(manager.LockHandle, CancellationToken.None); tempLeaseId = await blob.AcquireLeaseAsync(TimeSpan.FromSeconds(30), Guid.NewGuid().ToString()); } finally { if (tempLeaseId != null) { await blob.ReleaseLeaseAsync(new AccessCondition { LeaseId = tempLeaseId }); } } resetEvent.Wait(TimeSpan.FromSeconds(15)); } Assert.True(resetEvent.IsSet); Assert.False(manager.HasLease, $"{nameof(PrimaryHostCoordinator.HasLease)} was not correctly set to 'false' when lease lost."); await ClearLeaseBlob(hostId); }
public async Task EmptyHost_StartsSuccessfully() { string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString()); Directory.CreateDirectory(functionTestDir); // important for the repro that these directories no not exist string logDir = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString()); string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString()); JObject hostConfig = new JObject { { "id", "123456" } }; File.WriteAllText(Path.Combine(functionTestDir, ScriptConstants.HostMetadataFileName), hostConfig.ToString()); ScriptHostConfiguration config = new ScriptHostConfiguration { RootScriptPath = functionTestDir, RootLogPath = logDir, FileLoggingMode = FileLoggingMode.Always }; ISecretManager secretManager = new SecretManager(_settingsManager, secretsDir, NullTraceWriter.Instance); WebHostSettings webHostSettings = new WebHostSettings(); ScriptHostManager hostManager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), _settingsManager, webHostSettings); Task runTask = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => hostManager.State == ScriptHostState.Running, timeout : 10000); hostManager.Stop(); Assert.Equal(ScriptHostState.Default, hostManager.State); // give some time for the logs to be flushed fullly await Task.Delay(FileTraceWriter.LogFlushIntervalMs * 3); string hostLogFilePath = Directory.EnumerateFiles(Path.Combine(logDir, "Host")).Single(); string hostLogs = File.ReadAllText(hostLogFilePath); Assert.Contains("Generating 0 job function(s)", hostLogs); Assert.Contains("No job functions found.", hostLogs); Assert.Contains("Job host started", hostLogs); Assert.Contains("Job host stopped", hostLogs); }
public async Task InitializeAsync_WithSpecializedSite_SkipsWarmupFunctionsAndLogs() { _settings.Add(EnvironmentSettingNames.AzureWebsiteInstanceId, Guid.NewGuid().ToString()); var environment = new TestEnvironment(_settings); // We cannot create and run a full test host as there's no way to issue // requests to the TestServer before initialization has occurred. var webHostBuilder = await CreateWebHostBuilderAsync("Windows", environment); IWebHost host = webHostBuilder.Build(); // Pull the service out of the built host. If it were easier to construct, we'd do that instead. var standbyManager = host.Services.GetService <IStandbyManager>(); var scriptHostManager = host.Services.GetService <IScriptHostManager>() as WebJobsScriptHostService; // Simulate the race condition by flipping the specialization env vars and calling // Specialize before the call to Initialize was made. environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0"); environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteContainerReady, "1"); bool changeTokenFired = false; using (StandbyManager.ChangeToken.RegisterChangeCallback(_ => changeTokenFired = true, null)) { Task specializeTask = standbyManager.SpecializeHostAsync(); await TestHelpers.Await(() => changeTokenFired); await standbyManager.InitializeAsync(); await TestHelpers.Await(() => _loggerProvider.GetLog().Contains(" called with a specialized site configuration. Skipping warmup function creation.")); // Note: we also need to start the ScriptHostManager or else specialization will never complete await scriptHostManager.StartAsync(CancellationToken.None); await specializeTask; Assert.True(changeTokenFired); bool warmupCreationLogPresent = _loggerProvider.GetAllLogMessages() .Any(p => p.FormattedMessage != null && p.FormattedMessage.StartsWith("Creating StandbyMode placeholder function directory")); Assert.False(warmupCreationLogPresent); } }
public async Task EventHubTrigger() { TestHelpers.ClearFunctionLogs("EventHubTrigger"); // write 3 events List <EventData> events = new List <EventData>(); string[] ids = new string[3]; for (int i = 0; i < 3; i++) { ids[i] = Guid.NewGuid().ToString(); JObject jo = new JObject { { "value", ids[i] } }; events.Add(new EventData(Encoding.UTF8.GetBytes(jo.ToString(Formatting.None)))); } string connectionString = Environment.GetEnvironmentVariable("AzureWebJobsEventHubSender"); ServiceBusConnectionStringBuilder builder = new ServiceBusConnectionStringBuilder(connectionString); EventHubClient eventHubClient; if (!string.IsNullOrWhiteSpace(builder.EntityPath)) { eventHubClient = EventHubClient.CreateFromConnectionString(connectionString); } else { string eventHubPath = _settingsManager.GetSetting("AzureWebJobsEventHubPath"); eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubPath); } await eventHubClient.SendBatchAsync(events); string logs = null; await TestHelpers.Await(() => { // wait for all 3 of the unique IDs send // above have been processed logs = string.Join("\r\n", TestHelpers.GetFunctionLogsAsync("EventHubTrigger", throwOnNoLogs: false).Result); return(ids.All(p => logs.Contains(p))); }); Assert.True(logs.Contains("IsArray true")); }
protected async Task TableOutputTest() { CloudTable table = Fixture.TableClient.GetTableReference("testoutput"); await table.CreateIfNotExistsAsync(); await Fixture.DeleteEntities(table); JObject item = new JObject { { "partitionKey", "TestOutput" }, { "rowKey", 1 }, { "stringProp", "Mathew" }, { "intProp", 123 }, { "boolProp", true }, { "guidProp", Guid.NewGuid() }, { "floatProp", 68756.898 } }; await Fixture.Host.BeginFunctionAsync("TableOut", item); // read the entities and verify schema TableQuery tableQuery = new TableQuery(); DynamicTableEntity[] entities = null; await TestHelpers.Await(async() => { var results = await table.ExecuteQuerySegmentedAsync(tableQuery, null); entities = results.ToArray(); return(entities.Length == 3); }); foreach (var entity in entities) { Assert.Equal(EdmType.String, entity.Properties["stringProp"].PropertyType); Assert.Equal(EdmType.Int32, entity.Properties["intProp"].PropertyType); Assert.Equal(EdmType.Boolean, entity.Properties["boolProp"].PropertyType); // Guids end up roundtripping as strings Assert.Equal(EdmType.String, entity.Properties["guidProp"].PropertyType); Assert.Equal(EdmType.Double, entity.Properties["floatProp"].PropertyType); } }
public async Task TraceOutputsMessagesWhenLeaseRenewalFails() { var renewResetEvent = new ManualResetEventSlim(); var blobMock = new Mock <IDistributedLockManager>(); blobMock.Setup(b => b.TryLockAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>())) .Returns(() => Task.FromResult <IDistributedLock>(new FakeLock())); blobMock.Setup(b => b.RenewAsync(It.IsAny <IDistributedLock>(), It.IsAny <CancellationToken>())) .Returns(() => Task.FromException <bool>(new StorageException(new RequestResult { HttpStatusCode = 409 }, "test", null))) .Callback(() => renewResetEvent.Set()); var host = CreateHost(s => { s.AddSingleton <IDistributedLockManager>(_ => blobMock.Object); }); string hostId = host.GetHostId(); string instanceId = host.Services.GetService <ScriptSettingsManager>().AzureWebsiteInstanceId; using (host) { await host.StartAsync(); renewResetEvent.Wait(TimeSpan.FromSeconds(10)); await TestHelpers.Await(() => _loggerProvider.GetAllLogMessages().Any(m => m.FormattedMessage.StartsWith("Failed to renew host lock lease: ")), 10000, 500); await host.StopAsync(); } LogMessage acquisitionEvent = _loggerProvider.GetAllLogMessages().Single(m => m.FormattedMessage.Contains($"Host lock lease acquired by instance ID '{instanceId}'.")); Assert.Equal(Microsoft.Extensions.Logging.LogLevel.Information, acquisitionEvent.Level); LogMessage renewalEvent = _loggerProvider.GetAllLogMessages().Single(m => m.FormattedMessage.Contains(@"Failed to renew host lock lease: Another host has acquired the lease.")); string pattern = @"Failed to renew host lock lease: Another host has acquired the lease. The last successful renewal completed at (.+) \([0-9]+ milliseconds ago\) with a duration of [0-9]+ milliseconds."; Assert.True(Regex.IsMatch(renewalEvent.FormattedMessage, pattern), $"Expected trace event {pattern} not found."); Assert.Equal(Microsoft.Extensions.Logging.LogLevel.Information, renewalEvent.Level); }
public async Task HasLeaseChanged_WhenLeaseIsLost() { var host = CreateHost(); string connectionString = host.GetStorageConnectionString(); string hostId = host.GetHostId(); using (host) { ICloudBlob blob = await GetLockBlobAsync(connectionString, hostId); var primaryState = host.Services.GetService <IPrimaryHostStateProvider>(); var manager = host.Services.GetServices <IHostedService>().OfType <PrimaryHostCoordinator>().Single(); var lockManager = host.Services.GetService <IDistributedLockManager>(); string tempLeaseId = null; await host.StartAsync(); try { await TestHelpers.Await(() => primaryState.IsPrimary); // Release the manager's lease and acquire one with a different id await lockManager.ReleaseLockAsync(manager.LockHandle, CancellationToken.None); tempLeaseId = await blob.AcquireLeaseAsync(TimeSpan.FromSeconds(30), Guid.NewGuid().ToString()); await TestHelpers.Await(() => !primaryState.IsPrimary, userMessageCallback : () => $"{nameof(IPrimaryHostStateProvider.IsPrimary)} was not correctly set to 'false' when lease lost."); } finally { if (tempLeaseId != null) { await blob.ReleaseLeaseAsync(new AccessCondition { LeaseId = tempLeaseId }); } } await host.StopAsync(); } await ClearLeaseBlob(connectionString, hostId); }
public async Task EmptyHost_StartsSuccessfully() { string functionDir = Path.Combine(TestHelpers.FunctionsTestDirectory, "Functions", Guid.NewGuid().ToString()); Directory.CreateDirectory(functionDir); // important for the repro that this directory does not exist string logDir = Path.Combine(TestHelpers.FunctionsTestDirectory, "Logs", Guid.NewGuid().ToString()); JObject hostConfig = new JObject { { "id", "123456" } }; File.WriteAllText(Path.Combine(functionDir, ScriptConstants.HostMetadataFileName), hostConfig.ToString()); ScriptHostConfiguration config = new ScriptHostConfiguration { RootScriptPath = functionDir, RootLogPath = logDir, FileLoggingMode = FileLoggingMode.Always }; var eventManagerMock = new Mock <IScriptEventManager>(); ScriptHostManager hostManager = new ScriptHostManager(config, eventManagerMock.Object); Task runTask = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => hostManager.State == ScriptHostState.Running, timeout : 10000); hostManager.Stop(); Assert.Equal(ScriptHostState.Default, hostManager.State); await Task.Delay(FileTraceWriter.LogFlushIntervalMs); string hostLogFilePath = Directory.EnumerateFiles(Path.Combine(logDir, "Host")).Single(); string hostLogs = File.ReadAllText(hostLogFilePath); Assert.Contains("Generating 0 job function(s)", hostLogs); Assert.Contains("No job functions found.", hostLogs); Assert.Contains("Job host started", hostLogs); Assert.Contains("Job host stopped", hostLogs); }
public async Task StandbyModeE2E_Java() { _settings.Add(EnvironmentSettingNames.AzureWebsiteInstanceId, Guid.NewGuid().ToString()); var environment = new TestEnvironment(_settings); await InitializeTestHostAsync("Windows_Java", environment); await VerifyWarmupSucceeds(); await VerifyWarmupSucceeds(restart : true); // Get java process Id before specialization IEnumerable <int> javaProcessesBefore = Process.GetProcessesByName("java").Select(p => p.Id); // now specialize the host environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0"); environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteContainerReady, "1"); environment.SetEnvironmentVariable(LanguageWorkerConstants.FunctionWorkerRuntimeSettingName, "java"); Assert.False(environment.IsPlaceholderModeEnabled()); Assert.True(environment.IsContainerReady()); // give time for the specialization to happen string[] logLines = null; await TestHelpers.Await(() => { // wait for the trace indicating that the host has been specialized logLines = _loggerProvider.GetAllLogMessages().Where(p => p.FormattedMessage != null).Select(p => p.FormattedMessage).ToArray(); return(logLines.Contains("Generating 0 job function(s)") && logLines.Contains("Stopping JobHost")); }, userMessageCallback : () => string.Join(Environment.NewLine, _loggerProvider.GetAllLogMessages().Select(p => $"[{p.Timestamp.ToString("HH:mm:ss.fff")}] {p.FormattedMessage}"))); IEnumerable <int> javaProcessesAfter = Process.GetProcessesByName("java").Select(p => p.Id); // Verify number of java processes before and after specialization are the same. Assert.Equal(javaProcessesBefore.Count(), javaProcessesAfter.Count()); //Verify atleast one java process is running Assert.True(javaProcessesAfter.Count() >= 1); // Verify Java same java process is used after host restart var result = javaProcessesBefore.Where(pId1 => !javaProcessesAfter.Any(pId2 => pId2 == pId1)); Assert.Equal(0, result.Count()); }
public async Task HasLease_WhenLeaseIsAcquired_ReturnsTrue() { var host = CreateHost(); string connectionString = host.GetStorageConnectionString(); string hostId = host.GetHostId(); using (host) { await host.StartAsync(); var primaryState = host.Services.GetService <IPrimaryHostStateProvider>(); await TestHelpers.Await(() => primaryState.IsPrimary); await host.StopAsync(); } await ClearLeaseBlob(connectionString, hostId); }
public async Task DifferentHosts_UsingSameStorageAccount_CanObtainLease() { string hostId1 = Guid.NewGuid().ToString(); string hostId2 = Guid.NewGuid().ToString(); string instanceId = Guid.NewGuid().ToString(); string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); var traceWriter = new TestTraceWriter(TraceLevel.Verbose); using (var manager1 = await BlobLeaseManager.CreateAsync(connectionString, TimeSpan.FromSeconds(15), hostId1, instanceId, traceWriter)) using (var manager2 = await BlobLeaseManager.CreateAsync(connectionString, TimeSpan.FromSeconds(15), hostId2, instanceId, traceWriter)) { Task manager1Check = TestHelpers.Await(() => manager1.HasLease); Task manager2Check = TestHelpers.Await(() => manager2.HasLease); await Task.WhenAll(manager1Check, manager2Check); } await Task.WhenAll(ClearLeaseBlob(hostId1), ClearLeaseBlob(hostId2)); }
public async Task UpdateFileAndRestart() { Random r = new Random(); CancellationTokenSource cts = new CancellationTokenSource(); var fixture = new NodeEndToEndTests.TestFixture(); var blob1 = UpdateOutputName("testblob", "first", fixture); await fixture.Host.StopAsync(); var config = fixture.Host.ScriptConfig; using (var manager = new ScriptHostManager(config)) { // Background task to run while the main thread is pumping events at RunAndBlock(). Thread t = new Thread(_ => { // Wait for initial execution. TestHelpers.Await(() => { return(blob1.Exists()); }, timeout: 10 * 1000).Wait(); // This changes the bindings so that we now write to blob2 var blob2 = UpdateOutputName("first", "second", fixture); // wait for newly executed TestHelpers.Await(() => { return(blob2.Exists()); }, timeout: 10 * 1000).Wait(); manager.Stop(); }); t.Start(); manager.RunAndBlock(cts.Token); t.Join(); } }
public static async Task WaitForBlobAsync(CloudBlockBlob blob, Func <string> userMessageCallback = null) { StringBuilder sb = new StringBuilder(); await TestHelpers.Await(async() => { bool exists = await blob.ExistsAsync(); sb.AppendLine($"{blob.Name} exists: {exists}."); return(exists); }, pollingInterval : 500, userMessageCallback : () => { if (userMessageCallback != null) { sb.AppendLine().Append(userMessageCallback()); } return(sb.ToString()); }); }
public async Task OnDebugModeFileChanged_TriggeredWhenDebugFileUpdated() { ScriptHost host = _fixture.Host; string debugSentinelFilePath = Path.Combine(host.ScriptConfig.RootLogPath, "Host", ScriptConstants.DebugSentinelFileName); host.LastDebugNotify = DateTime.MinValue; Assert.False(host.InDebugMode); // verify that our file watcher for the debug sentinel file is configured // properly by touching the file and ensuring that our host goes into // debug mode File.SetLastWriteTimeUtc(debugSentinelFilePath, DateTime.UtcNow); await TestHelpers.Await(() => { return(host.InDebugMode); }); Assert.True(host.InDebugMode); }
public async Task DifferentHosts_UsingSameStorageAccount_CanObtainLease() { string hostId1 = Guid.NewGuid().ToString(); string hostId2 = Guid.NewGuid().ToString(); string instanceId = Guid.NewGuid().ToString(); string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); var lockManager = CreateLockManager(); using (var manager1 = PrimaryHostCoordinator.Create(lockManager, TimeSpan.FromSeconds(15), hostId1, instanceId, NullLoggerFactory.Instance)) using (var manager2 = PrimaryHostCoordinator.Create(lockManager, TimeSpan.FromSeconds(15), hostId2, instanceId, NullLoggerFactory.Instance)) { Task manager1Check = TestHelpers.Await(() => manager1.HasLease); Task manager2Check = TestHelpers.Await(() => manager2.HasLease); await Task.WhenAll(manager1Check, manager2Check); } await Task.WhenAll(ClearLeaseBlob(hostId1), ClearLeaseBlob(hostId2)); }
public async Task RunAndBlock_SetsLastError_WhenExceptionIsThrown() { ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = Environment.CurrentDirectory, TraceWriter = NullTraceWriter.Instance }; var exception = new Exception("Kaboom!"); var hostMock = new Mock <TestScriptHost>(config); var factoryMock = new Mock <IScriptHostFactory>(); factoryMock.Setup(f => f.Create(It.IsAny <ScriptHostConfiguration>())) .Returns(() => { if (exception != null) { throw exception; } return(hostMock.Object); }); var target = new Mock <ScriptHostManager>(config, factoryMock.Object); Task taskIgnore = Task.Run(() => target.Object.RunAndBlock()); // we expect a host exception immediately await Task.Delay(2000); Assert.False(target.Object.IsRunning); Assert.Same(exception, target.Object.LastError); // now verify that if no error is thrown on the next iteration // the cached error is cleared exception = null; await TestHelpers.Await(() => { return(target.Object.IsRunning); }); Assert.Null(target.Object.LastError); }
protected async Task <JObject> GetFunctionTestResult(string functionName) { string logEntry = null; await TestHelpers.Await(() => { // search the logs for token "TestResult:" and parse the following JSON var logs = Fixture.Host.GetLogMessages(LogCategories.CreateFunctionUserCategory(functionName)); if (logs != null) { logEntry = logs.Select(p => p.FormattedMessage).SingleOrDefault(p => p != null && p.Contains("TestResult:")); } return(logEntry != null); }); int idx = logEntry.IndexOf("{"); logEntry = logEntry.Substring(idx); return(JObject.Parse(logEntry)); }
protected async Task <JObject> GetFunctionTestResult(string functionName) { string logEntry = null; await TestHelpers.Await(() => { // search the logs for token "TestResult:" and parse the following JSON var logs = TestHelpers.GetFunctionLogsAsync(functionName, throwOnNoLogs: false).Result; if (logs != null) { logEntry = logs.SingleOrDefault(p => p.Contains("TestResult:")); } return(logEntry != null); }); int idx = logEntry.IndexOf("{"); logEntry = logEntry.Substring(idx); return(JObject.Parse(logEntry)); }
public async Task GetHostSecretsOrNull_ReturnsExpectedSecrets() { var path = WriteStartupContext(); var secrets = _startupContextProvider.GetHostSecretsOrNull(); Assert.Equal(_secrets.Host.Master, secrets.MasterKey); Assert.Equal(_secrets.Host.Function, secrets.FunctionKeys); Assert.Equal(_secrets.Host.System, secrets.SystemKeys); var logs = _loggerProvider.GetAllLogMessages().Select(p => p.FormattedMessage).ToArray(); Assert.True(logs.Contains($"Loading startup context from {path}")); Assert.True(logs.Contains("Loaded host keys from startup context")); // verify the context file is deleted after it's consumed await TestHelpers.Await(() => { return(!File.Exists(path)); }, timeout : 1000); }
private async Task <WebScriptHostManager> CreateAndStartWebScriptHostManager(TraceWriter traceWriter) { var functions = new Collection <string> { "TimeoutToken" }; ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = $@"TestScripts\CSharp", TraceWriter = traceWriter, FileLoggingMode = FileLoggingMode.Always, Functions = functions, FunctionTimeout = TimeSpan.FromSeconds(3) }; var manager = new WebScriptHostManager(config, new TestSecretManagerFactory(), _settingsManager, new WebHostSettings()); Task task = Task.Run(() => { manager.RunAndBlock(); }); await TestHelpers.Await(() => manager.State == ScriptHostState.Running); return(manager); }
public async Task DifferentHosts_UsingSameStorageAccount_CanObtainLease() { string hostId1 = Guid.NewGuid().ToString(); string hostId2 = Guid.NewGuid().ToString(); var host1 = CreateHost(s => { s.AddSingleton <IHostIdProvider>(_ => new FixedHostIdProvider(hostId1)); }); var host2 = CreateHost(s => { s.AddSingleton <IHostIdProvider>(_ => new FixedHostIdProvider(hostId2)); }); string host1ConnectionString = host1.GetStorageConnectionString(); string host2ConnectionString = host2.GetStorageConnectionString(); using (host1) using (host2) { await host1.StartAsync(); await host2.StartAsync(); var primaryState1 = host1.Services.GetService <IPrimaryHostStateProvider>(); var primaryState2 = host2.Services.GetService <IPrimaryHostStateProvider>(); Task manager1Check = TestHelpers.Await(() => primaryState1.IsPrimary); Task manager2Check = TestHelpers.Await(() => primaryState2.IsPrimary); await Task.WhenAll(manager1Check, manager2Check); await host1.StopAsync(); await host2.StopAsync(); } await Task.WhenAll(ClearLeaseBlob(host1ConnectionString, hostId1), ClearLeaseBlob(host2ConnectionString, hostId2)); }
public async Task Renew_WhenBlobIsDeleted_RecreatesBlob() { string hostId = Guid.NewGuid().ToString(); string instanceId = Guid.NewGuid().ToString(); var traceWriter = new TestTraceWriter(TraceLevel.Verbose); var renewResetEvent = new ManualResetEventSlim(); string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); ICloudBlob blob = await GetLockBlobAsync(connectionString, hostId); var blobMock = new Mock <ICloudBlob>(); blobMock.Setup(b => b.AcquireLeaseAsync(It.IsAny <TimeSpan>(), It.IsAny <string>())) .Returns(() => Task.FromResult(hostId)); blobMock.Setup(b => b.RenewLeaseAsync(It.IsAny <AccessCondition>())) .Returns(() => Task.FromException <string>(new StorageException(new RequestResult { HttpStatusCode = 404 }, "test", null))) .Callback(() => Task.Delay(1000).ContinueWith(t => renewResetEvent.Set())); blobMock.SetupGet(b => b.ServiceClient).Returns(blob.ServiceClient); // Delete the blob await blob.DeleteIfExistsAsync(); using (var manager = new BlobLeaseManager(blobMock.Object, TimeSpan.FromSeconds(15), hostId, instanceId, traceWriter, TimeSpan.FromSeconds(3))) { renewResetEvent.Wait(TimeSpan.FromSeconds(10)); await TestHelpers.Await(() => manager.HasLease); } bool blobExists = await blob.ExistsAsync(); Assert.True(renewResetEvent.IsSet); Assert.True(blobExists); await ClearLeaseBlob(hostId); }
protected async Task <Document> WaitForDocumentAsync(string itemId, string textToMatch = null) { var docUri = UriFactory.CreateDocumentUri("ItemDb", "ItemCollection", itemId); // We know the tests are using the default INameResolver and the default setting. var connectionString = _nameResolver.Resolve("AzureWebJobsCosmosDBConnectionString"); var builder = new DbConnectionStringBuilder(); builder.ConnectionString = connectionString; var serviceUri = new Uri(builder["AccountEndpoint"].ToString()); var client = new DocumentClient(serviceUri, builder["AccountKey"].ToString()); Document doc = null; await TestHelpers.Await(() => { bool result = false; try { var response = Task.Run(() => client.ReadDocumentAsync(docUri)).Result; doc = response.Resource; if (textToMatch != null) { result = doc.GetPropertyValue <string>("text") == textToMatch; } else { result = true; } } catch (Exception) { string logs = string.Join(Environment.NewLine, Fixture.Host.GetLogMessages()); } return(result); }); return(doc); }