Await() публичный статический Метод

public static Await ( Func condition, int timeout = 60*1000, int pollingInterval = 2*1000 ) : System.Threading.Tasks.Task
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);
        }
Пример #10
0
        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"));
        }
Пример #12
0
        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);
        }
Пример #15
0
        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));
        }
Пример #19
0
        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();
            }
        }
Пример #20
0
        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());
            });
        }
Пример #21
0
        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);
        }
Пример #22
0
        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));
        }
Пример #23
0
        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);
        }