Esempio n. 1
0
        public Task ExecuteAsync(HttpRequest request, CancellationToken cancellationToken)
        {
            if (!CanExecute)
            {
                throw new InvalidOperationException("Unable to execute function without a target.");
            }

            Dictionary <string, object> arguments = GetFunctionArguments(_descriptor, request);

            return(_host.CallAsync(_descriptor.Name, arguments, cancellationToken));
        }
        public async Task Validate_Manual()
        {
            string functionName    = "Scenarios";
            int    invocationCount = 5;

            List <string> functionTraces = new List <string>();
            ScriptHost    host           = _fixture.GetScriptHost();

            // We want to invoke this multiple times specifically to make sure Node invocationIds
            // are correctly being set. Invoke them all first, then come back and validate all.
            for (int i = 0; i < invocationCount; i++)
            {
                string functionTrace = $"Function trace: {Guid.NewGuid().ToString()}";
                functionTraces.Add(functionTrace);

                Dictionary <string, object> input = new Dictionary <string, object>
                {
                    ["input"] = new JObject()
                    {
                        { "scenario", "appInsights" },
                        { "container", "not-used" },
                        { "value", functionTrace }
                    }.ToString()
                };

                await host.CallAsync(functionName, input);
            }

            // Now validate each function invocation.
            foreach (string functionTrace in functionTraces)
            {
                await WaitForFunctionTrace(functionName, functionTrace);

                string invocationId = ValidateEndToEndTest(functionName, functionTrace, true);

                // TODO: Remove this check when metrics are supported in Node:
                // https://github.com/Azure/azure-functions-host/issues/2189
                if (this is ApplicationInsightsCSharpEndToEndTests)
                {
                    // Do some additional metric validation
                    MetricTelemetry metric = _fixture.Channel.Telemetries
                                             .OfType <MetricTelemetry>()
                                             .Where(t => t.Context.Operation.Id == invocationId)
                                             .Single();
                    ValidateMetric(metric, invocationId, functionName);
                }
            }
        }
        public async Task ExecuteAsync(HttpRequest request, CancellationToken cancellationToken)
        {
            if (!CanExecute)
            {
                throw new InvalidOperationException("Unable to execute function without a target.");
            }

            JObject coldStartData = null;

            if (request.IsColdStart())
            {
                coldStartData = new JObject
                {
                    { "requestId", request.GetRequestId() },
                    { "language", Descriptor.Metadata.ScriptType.ToString() },
                    { "sku", _settingsManager.WebsiteSku }
                };

                var dispatchStopwatch = request.GetItemOrDefault <Stopwatch>(ScriptConstants.AzureFunctionsColdStartKey);
                if (dispatchStopwatch != null)
                {
                    dispatchStopwatch.Stop();
                    coldStartData.Add("dispatchDuration", dispatchStopwatch.ElapsedMilliseconds);
                }
            }

            var functionStopwatch = new Stopwatch();

            functionStopwatch.Start();
            var arguments = GetFunctionArguments(_descriptor, request);
            await _host.CallAsync(_descriptor.Name, arguments, cancellationToken);

            functionStopwatch.Stop();

            if (coldStartData != null)
            {
                coldStartData.Add("functionDuration", functionStopwatch.ElapsedMilliseconds);

                var logData = new Dictionary <string, object>
                {
                    [ScriptConstants.LogPropertyEventNameKey]  = ScriptConstants.ColdStartEventName,
                    [ScriptConstants.LogPropertyActivityIdKey] = request.GetRequestId()
                };
                _logger.Log(LogLevel.Information, 0, logData, null, (s, e) => coldStartData.ToString(Formatting.None));
            }
        }
        public static void WarmUp(WebHostSettings settings)
        {
            var        traceWriter = new FileTraceWriter(Path.Combine(settings.LogPath, "Host"), TraceLevel.Info);
            ScriptHost host        = null;

            try
            {
                traceWriter.Info("Warm up started");

                string rootPath = settings.ScriptPath;
                if (Directory.Exists(rootPath))
                {
                    Directory.Delete(rootPath, true);
                }
                Directory.CreateDirectory(rootPath);

                string content = ReadResourceString("Functions.host.json");
                File.WriteAllText(Path.Combine(rootPath, "host.json"), content);

                // read in the C# function
                string functionPath = Path.Combine(rootPath, "Test-CSharp");
                Directory.CreateDirectory(functionPath);
                content = ReadResourceString("Functions.Test_CSharp.function.json");
                File.WriteAllText(Path.Combine(functionPath, "function.json"), content);
                content = ReadResourceString("Functions.Test_CSharp.run.csx");
                File.WriteAllText(Path.Combine(functionPath, "run.csx"), content);

                // read in the F# function
                functionPath = Path.Combine(rootPath, "Test-FSharp");
                Directory.CreateDirectory(functionPath);
                content = ReadResourceString("Functions.Test_FSharp.function.json");
                File.WriteAllText(Path.Combine(functionPath, "function.json"), content);
                content = ReadResourceString("Functions.Test_FSharp.run.fsx");
                File.WriteAllText(Path.Combine(functionPath, "run.fsx"), content);

                traceWriter.Info("Warm up functions deployed");

                ScriptHostConfiguration config = new ScriptHostConfiguration
                {
                    RootScriptPath      = rootPath,
                    FileLoggingMode     = FileLoggingMode.Never,
                    RootLogPath         = settings.LogPath,
                    TraceWriter         = traceWriter,
                    FileWatchingEnabled = false
                };
                config.HostConfig.StorageConnectionString   = null;
                config.HostConfig.DashboardConnectionString = null;

                host = ScriptHost.Create(config);
                traceWriter.Info(string.Format("Starting Host (Id={0})", host.ScriptConfig.HostConfig.HostId));

                host.Start();

                var arguments = new Dictionary <string, object>
                {
                    { "input", "{}" }
                };
                host.CallAsync("Test-CSharp", arguments).Wait();
                host.CallAsync("Test-FSharp", arguments).Wait();
                host.Stop();

                traceWriter.Info("Warm up succeeded");
            }
            catch (Exception ex)
            {
                traceWriter.Error(string.Format("Warm up failed: {0}", ex));
            }
            finally
            {
                host?.Dispose();
                traceWriter.Dispose();
            }
        }
Esempio n. 5
0
        private async Task RunTimeoutTest(string scriptLang, string functionName)
        {
            TestHelpers.ClearFunctionLogs(functionName);
            TimeSpan     testTimeout = TimeSpan.FromSeconds(3);
            IHostBuilder builder     = CreateTimeoutHostBuilder($@"TestScripts\{scriptLang}", TimeSpan.FromSeconds(3), functionName);

            using (var host = builder.Build())
            {
                await host.StartAsync();

                ScriptHost scriptHost = host.GetScriptHost();
                string     testData   = Guid.NewGuid().ToString();

                Dictionary <string, object> arguments = new Dictionary <string, object>
                {
                    { "inputData", testData },
                };

                FunctionTimeoutException ex = await Assert.ThrowsAsync <FunctionTimeoutException>(() => scriptHost.CallAsync(functionName, arguments));

                await TestHelpers.Await(() =>
                {
                    // make sure logging from within the function worked
                    // TODO: This doesn't appear to work for Powershell in AppVeyor. Need to investigate.
                    // bool hasTestData = inProgressLogs.Any(l => l.Contains(testData));
                    var expectedMessage = $"Timeout value of {testTimeout} exceeded by function 'Functions.{functionName}'";
                    var traces          = string.Join(Environment.NewLine, _loggerProvider.GetAllLogMessages().Where(t => t.FormattedMessage != null).Select(p => p.FormattedMessage));
                    return(traces.Contains(expectedMessage));
                });

                var exception = GetExceptionHandler(host).TimeoutExceptionInfos.Single().SourceException;
                Assert.IsType <FunctionTimeoutException>(exception);
            }
        }