Beispiel #1
0
        public void TimeoutIsEvaluatedInSeconds()
        {
            var attrib = new TimeoutAttribute(120);

            Assert.AreEqual(120, attrib.TimeoutSeconds);
            Assert.AreEqual(TimeSpan.FromSeconds(120), attrib.Timeout);
        }
        public FunctionIndexProvider(ITypeLocator typeLocator,
                                     ITriggerBindingProvider triggerBindingProvider,
                                     CompositeBindingProvider bindingProviderFactory,
                                     IJobActivator activator,
                                     IFunctionExecutor executor,
                                     IExtensionRegistry extensions,
                                     SingletonManager singletonManager,
                                     ILoggerFactory loggerFactory,
                                     SharedQueueHandler sharedQueue,
                                     IOptions <JobHostFunctionTimeoutOptions> timeoutOptions,
                                     IOptions <JobHostOptions> hostOptions)
        {
            _typeLocator            = typeLocator ?? throw new ArgumentNullException(nameof(typeLocator));
            _triggerBindingProvider = triggerBindingProvider ?? throw new ArgumentNullException(nameof(triggerBindingProvider));
            _bindingProviderFactory = bindingProviderFactory ?? throw new ArgumentNullException(nameof(bindingProviderFactory));
            _activator        = activator ?? throw new ArgumentNullException(nameof(activator));
            _executor         = executor ?? throw new ArgumentNullException(nameof(executor));
            _extensions       = extensions ?? throw new ArgumentNullException(nameof(extensions));
            _singletonManager = singletonManager ?? throw new ArgumentNullException(nameof(singletonManager));
            _sharedQueue      = sharedQueue ?? throw new ArgumentNullException(nameof(sharedQueue));

            _loggerFactory           = loggerFactory;
            _defaultTimeout          = timeoutOptions.Value.ToAttribute();
            _allowPartialHostStartup = hostOptions.Value.AllowPartialHostStartup;
        }
Beispiel #3
0
        private void RunOnFunctionTimeoutTest(bool isDebugging, string expectedMessage)
        {
            System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromMinutes(1).TotalMilliseconds);
            timer.Start();

            Assert.True(timer.Enabled);
            Assert.False(_cancellationTokenSource.IsCancellationRequested);

            MethodInfo       method    = typeof(Functions).GetMethod("MethodLevel", BindingFlags.Static | BindingFlags.Public);
            TimeoutAttribute attribute = method.GetCustomAttribute <TimeoutAttribute>();

            _descriptor = FunctionIndexer.FromMethod(method);
            Guid instanceId            = Guid.Parse("B2D1DD72-80E2-412B-A22E-3B4558F378B4");
            bool timeoutWhileDebugging = false;

            TestLogger logger = new TestLogger("Tests.FunctionExecutor");

            FunctionExecutor.OnFunctionTimeout(timer, _descriptor, instanceId, attribute.Timeout, timeoutWhileDebugging, logger, _cancellationTokenSource, () => isDebugging);

            Assert.False(timer.Enabled);
            Assert.NotEqual(isDebugging, _cancellationTokenSource.IsCancellationRequested);

            string message = string.Format("Timeout value of 00:01:00 exceeded by function 'Functions.MethodLevel' (Id: 'b2d1dd72-80e2-412b-a22e-3b4558f378b4'). {0}", expectedMessage);

            // verify ILogger
            LogMessage log = logger.LogMessages.Single();

            Assert.Equal(LogLevel.Error, log.Level);
            Assert.Equal(message, log.FormattedMessage);
        }
Beispiel #4
0
        public async Task OnRequestAsync_Parameter_Timespan_Test()
        {
            var apiAction = new ApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync"));
            var context   = new TestRequestContext(apiAction, 5);

            var attr = new TimeoutAttribute();

            var parameterContext = new ApiParameterContext(context, 0);
            await attr.OnRequestAsync(parameterContext, () => Task.CompletedTask);

            await Task.Delay(20);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);

            context.Arguments[0] = Guid.NewGuid();

            await Assert.ThrowsAsync <HttpApiInvalidOperationException>(()
                                                                        => attr.OnRequestAsync(parameterContext, () => Task.CompletedTask));

            context.Arguments[0] = null;

            await attr.OnRequestAsync(parameterContext, () => Task.CompletedTask);

            Assert.True(context.CancellationTokens.Count == 1);
        }
        private void RunOnFunctionTimeoutTest(bool isDebugging, string expectedMessage)
        {
            System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromMinutes(1).TotalMilliseconds);
            timer.Start();

            Assert.True(timer.Enabled);
            Assert.False(_cancellationTokenSource.IsCancellationRequested);

            MethodInfo       method                = typeof(Functions).GetMethod("MethodLevel", BindingFlags.Static | BindingFlags.Public);
            TimeoutAttribute attribute             = method.GetCustomAttribute <TimeoutAttribute>();
            Guid             instanceId            = Guid.Parse("B2D1DD72-80E2-412B-A22E-3B4558F378B4");
            bool             timeoutWhileDebugging = false;

            FunctionExecutor.OnFunctionTimeout(timer, method, instanceId, attribute.Timeout, timeoutWhileDebugging, _traceWriter, _cancellationTokenSource, () => isDebugging);

            Assert.False(timer.Enabled);
            Assert.NotEqual(isDebugging, _cancellationTokenSource.IsCancellationRequested);

            TraceEvent trace = _traceWriter.Traces[0];

            Assert.Equal(TraceLevel.Error, trace.Level);
            Assert.Equal(TraceSource.Execution, trace.Source);
            string message = string.Format("Timeout value of 00:01:00 exceeded by function 'Functions.MethodLevel' (Id: 'b2d1dd72-80e2-412b-a22e-3b4558f378b4'). {0}", expectedMessage);

            Assert.Equal(message, trace.Message);
        }
Beispiel #6
0
        public FunctionIndexProvider(ITypeLocator typeLocator,
                                     ITriggerBindingProvider triggerBindingProvider,
                                     IBindingProvider bindingProvider,
                                     IJobActivator activator,
                                     IFunctionExecutor executor,
                                     IExtensionRegistry extensions,
                                     SingletonManager singletonManager,
                                     ILoggerFactory loggerFactory,
                                     SharedQueueHandler sharedQueue,
                                     TimeoutAttribute defaultTimeout,
                                     bool allowPartialHostStartup = false)
        {
            _typeLocator            = typeLocator ?? throw new ArgumentNullException(nameof(typeLocator));
            _triggerBindingProvider = triggerBindingProvider ?? throw new ArgumentNullException(nameof(triggerBindingProvider));
            _bindingProvider        = bindingProvider ?? throw new ArgumentNullException(nameof(bindingProvider));
            _activator        = activator ?? throw new ArgumentNullException(nameof(activator));
            _executor         = executor ?? throw new ArgumentNullException(nameof(executor));
            _extensions       = extensions ?? throw new ArgumentNullException(nameof(extensions));
            _singletonManager = singletonManager ?? throw new ArgumentNullException(nameof(singletonManager));
            _sharedQueue      = sharedQueue ?? throw new ArgumentNullException(nameof(sharedQueue));

            _loggerFactory           = loggerFactory;
            _defaultTimeout          = defaultTimeout;
            _allowPartialHostStartup = allowPartialHostStartup;
        }
Beispiel #7
0
        public async Task BeforeRequestAsync_Parameter_Timespan_Test()
        {
            var context = new TestActionContext(
                httpApi: null,
                httpApiConfig: new HttpApiConfig(),
                apiActionDescriptor: new ApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync")));

            IApiParameterAttribute attr = new TimeoutAttribute();


            var parameter = context.ApiActionDescriptor.Parameters[0].Clone(TimeSpan.FromMilliseconds(5));
            await attr.BeforeRequestAsync(context, parameter);

            await Task.Delay(10);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);


            parameter = context.ApiActionDescriptor.Parameters[0].Clone(Guid.NewGuid());
            await Assert.ThrowsAsync <HttpApiConfigException>(()
                                                              => attr.BeforeRequestAsync(context, parameter));


            parameter = context.ApiActionDescriptor.Parameters[0].Clone(null);
            await attr.BeforeRequestAsync(context, parameter);

            Assert.True(context.CancellationTokens.Count == 1);
        }
Beispiel #8
0
        public void ZeroTimeoutMeansInfinite()
        {
            var attrib = new TimeoutAttribute(0);

            Assert.AreEqual(0, attrib.TimeoutSeconds);
            Assert.IsNull(attrib.Timeout);
        }
Beispiel #9
0
        public void TimeoutAttribute()
        {
            var attr = new TimeoutAttribute(50) as IApplyToContext;

            attr.ApplyToContext(_context);
            Assert.That(_context.TestCaseTimeout, Is.EqualTo(50));
        }
        public void StartFunctionTimeout_NoTimeout_ReturnsNull()
        {
            TimeoutAttribute timeoutAttribute = null;

            System.Timers.Timer timer = FunctionExecutor.StartFunctionTimeout(null, timeoutAttribute, _cancellationTokenSource, _traceWriter);

            Assert.Null(timer);
        }
Beispiel #11
0
        public FunctionIndexer(
            ITriggerBindingProvider triggerBindingProvider,
            IBindingProvider bindingProvider,
            IJobActivator activator,
            IFunctionExecutor executor,
            IExtensionRegistry extensions,
            SingletonManager singletonManager,
            ILoggerFactory loggerFactory,
            INameResolver nameResolver      = null,
            SharedQueueHandler sharedQueue  = null,
            TimeoutAttribute defaultTimeout = null,
            bool allowPartialHostStartup    = false)
        {
            if (triggerBindingProvider == null)
            {
                throw new ArgumentNullException("triggerBindingProvider");
            }

            if (bindingProvider == null)
            {
                throw new ArgumentNullException("bindingProvider");
            }

            if (activator == null)
            {
                throw new ArgumentNullException("activator");
            }

            if (executor == null)
            {
                throw new ArgumentNullException("executor");
            }

            if (extensions == null)
            {
                throw new ArgumentNullException("extensions");
            }

            if (singletonManager == null)
            {
                throw new ArgumentNullException("singletonManager");
            }

            _triggerBindingProvider = triggerBindingProvider;
            _bindingProvider        = bindingProvider;
            _activator              = activator;
            _executor               = executor;
            _singletonManager       = singletonManager;
            _jobAttributeAssemblies = GetJobAttributeAssemblies(extensions);
            _nameResolver           = nameResolver;
            _logger                  = loggerFactory?.CreateLogger(LogCategories.Startup);
            _sharedQueue             = sharedQueue;
            _defaultTimeout          = defaultTimeout;
            _allowPartialHostStartup = allowPartialHostStartup;
        }
Beispiel #12
0
        public async Task OnRequestAsync()
        {
            var apiAction = new ApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync"));
            var context   = new TestRequestContext(apiAction, 10);

            var attr = new TimeoutAttribute(50);
            await attr.OnRequestAsync(context);

            await Task.Delay(100);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);
        }
        public void StartFunctionTimeout_GlobalTimeout_CreatesExpectedTimer()
        {
            MethodInfo method = GetType().GetMethod("GlobalLevel", BindingFlags.Static | BindingFlags.Public);

            _descriptor.Method = method;
            TimeoutAttribute attribute = method.GetCustomAttribute <TimeoutAttribute>();

            System.Timers.Timer timer = FunctionExecutor.StartFunctionTimeout(_mockFunctionInstance.Object, _globalFunctionTimeout, _cancellationTokenSource, _traceWriter);

            Assert.True(timer.Enabled);
            Assert.Equal(_globalFunctionTimeout.TotalMilliseconds, timer.Interval);

            _mockFunctionInstance.VerifyAll();
        }
        public async Task BeforeRequestAsyncTest()
        {
            var context = new ApiActionContext
            {
                HttpApiConfig       = new HttpApiConfig(),
                RequestMessage      = new HttpApiRequestMessage(),
                ApiActionDescriptor = ApiDescriptorCache.GetApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync"))
            };

            var attr = new TimeoutAttribute(5000);
            await attr.BeforeRequestAsync(context);

            Assert.True(context.RequestMessage.Timeout == TimeSpan.FromSeconds(5));
        }
Beispiel #15
0
        public async Task OnRequestAsync_Parameter_Double_Test()
        {
            var apiAction = new ApiActionDescriptor(typeof(ITestApi).GetMethod("PostAsync"));
            var context   = new TestRequestContext(apiAction, 1);

            var attr             = new TimeoutAttribute();
            var parameterContext = new ApiParameterContext(context, 0);
            await attr.OnRequestAsync(parameterContext, () => Task.CompletedTask);

            await Task.Delay(20);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);
        }
        public void Constructor_DefaultsProperties()
        {
            var timeout = new TimeoutAttribute("00:00:25");

            Assert.Equal(TimeSpan.FromSeconds(25), timeout.Timeout);
            Assert.Equal(TimeSpan.FromSeconds(2), timeout.GracePeriod);
            Assert.False(timeout.TimeoutWhileDebugging);
            Assert.False(timeout.ThrowOnTimeout);

            timeout = new TimeoutAttribute("00:05:00", "00:00:30");
            Assert.Equal(TimeSpan.FromMinutes(5), timeout.Timeout);
            Assert.Equal(TimeSpan.FromSeconds(30), timeout.GracePeriod);
            Assert.False(timeout.TimeoutWhileDebugging);
            Assert.False(timeout.ThrowOnTimeout);
        }
Beispiel #17
0
        public async Task BeforeRequestAsyncTest()
        {
            var context = new TestActionContext(
                httpApi: null,
                httpApiConfig: new HttpApiConfig(),
                apiActionDescriptor: new ApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync")));

            var attr = new TimeoutAttribute(50);
            await attr.BeforeRequestAsync(context);

            await Task.Delay(100);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);
        }
        public void StartFunctionTimeout_NoCancellationTokenParameter_ThrowOnTimeoutFalse_ReturnsNull()
        {
            MethodInfo method = typeof(Functions).GetMethod("NoCancellationTokenParameter", BindingFlags.Static | BindingFlags.Public);

            _descriptor.Method = method;

            TimeoutAttribute attribute = typeof(Functions).GetCustomAttribute <TimeoutAttribute>();

            attribute.ThrowOnTimeout = false;

            System.Timers.Timer timer = FunctionExecutor.StartFunctionTimeout(_mockFunctionInstance.Object, attribute, _cancellationTokenSource, _traceWriter);

            Assert.Null(timer);

            _mockFunctionInstance.VerifyAll();
        }
        internal static async Task HandleExceptionAsync(TimeoutAttribute timeout, ExceptionDispatchInfo exceptionInfo, IWebJobsExceptionHandler exceptionHandler)
        {
            if (exceptionInfo.SourceException == null)
            {
                return;
            }

            Exception exception = exceptionInfo.SourceException;

            if (exception.IsTimeout())
            {
                await exceptionHandler.OnTimeoutExceptionAsync(exceptionInfo, timeout.GracePeriod);
            }
            else if (exception.IsFatal())
            {
                await exceptionHandler.OnUnhandledExceptionAsync(exceptionInfo);
            }
        }
Beispiel #20
0
        public async Task BeforeRequestAsync_Parameter_Double_Test()
        {
            var context = new TestActionContext(
                httpApi: null,
                httpApiConfig: new HttpApiConfig(),
                apiActionDescriptor: new ApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync")));

            IApiParameterAttribute attr = new TimeoutAttribute();

            var parameter = context.ApiActionDescriptor.Parameters[0].Clone(10);
            await attr.BeforeRequestAsync(context, parameter);

            await Task.Delay(20);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);
        }
Beispiel #21
0
        public async Task BeforeRequestAsyncTest()
        {
            var context = new ApiActionContext
            {
                HttpApiConfig       = new HttpApiConfig(),
                RequestMessage      = new HttpApiRequestMessage(),
                ApiActionDescriptor = ApiDescriptorCache.GetApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync"))
            };

            var attr = new TimeoutAttribute(50);
            await attr.BeforeRequestAsync(context);

            await Task.Delay(100);

            var canceled = context.CancellationTokens[0].IsCancellationRequested;

            Assert.True(canceled);
        }
        internal static async Task HandleExceptionAsync(MethodInfo method, ExceptionDispatchInfo exceptionInfo, IWebJobsExceptionHandler exceptionHandler)
        {
            if (exceptionInfo.SourceException == null)
            {
                return;
            }

            Exception exception = exceptionInfo.SourceException;

            if (exception.IsTimeout())
            {
                TimeoutAttribute timeoutAttribute = TypeUtility.GetHierarchicalAttributeOrNull <TimeoutAttribute>(method);
                await exceptionHandler.OnTimeoutExceptionAsync(exceptionInfo, timeoutAttribute.GracePeriod);
            }
            else if (exception.IsFatal())
            {
                await exceptionHandler.OnUnhandledExceptionAsync(exceptionInfo);
            }
        }
        public void StartFunctionTimeout_ClassLevelTimeout_CreatesExpectedTimer()
        {
            MethodInfo method = typeof(Functions).GetMethod("ClassLevel", BindingFlags.Static | BindingFlags.Public);

            _descriptor.Method = method;

            // we need to set up the Id so that when the timer fires it doesn't throw, but since this is Strict, we need to access it first.
            _mockFunctionInstance.SetupGet(p => p.Id).Returns(Guid.Empty);
            Assert.NotNull(_mockFunctionInstance.Object.Id);

            TimeoutAttribute attribute = typeof(Functions).GetCustomAttribute <TimeoutAttribute>();

            System.Timers.Timer timer = FunctionExecutor.StartFunctionTimeout(_mockFunctionInstance.Object, attribute, _cancellationTokenSource, _traceWriter);

            Assert.True(timer.Enabled);
            Assert.Equal(attribute.Timeout.TotalMilliseconds, timer.Interval);

            _mockFunctionInstance.VerifyAll();
        }
        internal static System.Timers.Timer StartFunctionTimeout(IFunctionInstance instance, TimeSpan?globalTimeout, CancellationTokenSource cancellationTokenSource, TraceWriter trace)
        {
            MethodInfo method = instance.FunctionDescriptor.Method;

            if (!method.GetParameters().Any(p => p.ParameterType == typeof(CancellationToken)))
            {
                // function doesn't bind to the CancellationToken, so no point in setting
                // up the cancellation timer
                return(null);
            }

            // first see if there is a Timeout applied to the method or class
            TimeSpan?        timeout          = globalTimeout;
            TimeoutAttribute timeoutAttribute = TypeUtility.GetHierarchicalAttributeOrNull <TimeoutAttribute>(method);

            if (timeoutAttribute != null)
            {
                timeout = timeoutAttribute.Timeout;
            }

            if (timeout != null)
            {
                // Create a Timer that will cancel the token source when it fires. We're using our
                // own Timer (rather than CancellationToken.CancelAfter) so we can write a log entry
                // before cancellation occurs.
                var timer = new System.Timers.Timer(timeout.Value.TotalMilliseconds)
                {
                    AutoReset = false
                };
                timer.Elapsed += (o, e) =>
                {
                    OnFunctionTimeout(timer, method, instance.Id, timeout.Value, trace, cancellationTokenSource);
                };
                timer.Start();

                return(timer);
            }

            return(null);
        }
Beispiel #25
0
        private void HasValidTimeoutAttribute()
        {
            StringBuilder sb = new StringBuilder();

            foreach (MethodInfo methodInfo in this.TestMethods)
            {
                TimeoutAttribute timeout = methodInfo.GetCustomAttributes(typeof(TimeoutAttribute), false).Cast <TimeoutAttribute>().FirstOrDefault();
                if (timeout == null)
                {
                    sb.AppendLine(string.Format("    {0}: should have [Timeout].", methodInfo.Name));
                }
                else if (timeout.Timeout <= 0 || timeout.Timeout > (TimeoutConstant.ExtendedTimeout))
                {
                    sb.AppendLine(string.Format("    {0}: [Timeout({1})] must be > 0 and < {2} milliseconds.", methodInfo.Name, timeout.Timeout, TimeoutConstant.ExtendedTimeout));
                }
            }

            if (sb.Length != 0)
            {
                Assert.Fail(string.Format("{0}these test methods have incorrect [Timeout] attributes:\r\n{1}.", testErrorPrefix, sb.ToString()));
            }
        }
        private TestMethodUnit(MethodInfo testCase)
        {
            m_testCase = testCase;
            name       = testCase.Name;
            m_tagAttrs = new List <string>();

            foreach (Attribute attr in testCase.GetCustomAttributes(true))
            {
                if (null != (attr as TestMethodAttribute))
                {
                    m_attr = (TestMethodAttribute)attr;
                }

                if (null != (attr as TimeoutAttribute))
                {
                    m_timeoutAttr = (TimeoutAttribute)attr;
                }

                if (null != (attr as TestCategoryAttribute))
                {
                    m_tagAttrs.Add(((TestCategoryAttribute)attr).TestCategories[0]);
                }

                if (null != (attr as IgnoreAttribute))
                {
                    m_ignoreAttr = (IgnoreAttribute)attr;
                }
            }

            //default is all enabled if not ignored
            if (Ignore)
            {
                enable = false;
            }
            else
            {
                enable = true;
            }
        }
        // Expose internally for testing purposes
        internal static FunctionDescriptor FromMethod(
            MethodInfo method,
            IJobActivator jobActivator      = null,
            INameResolver nameResolver      = null,
            TimeoutAttribute defaultTimeout = null)
        {
            var disabled = HostListenerFactory.IsDisabled(method, nameResolver, jobActivator);

            bool hasCancellationToken = method.GetParameters().Any(p => p.ParameterType == typeof(CancellationToken));

            string logName   = method.Name;
            string shortName = method.GetShortName();
            FunctionNameAttribute nameAttribute = method.GetCustomAttribute <FunctionNameAttribute>();

            if (nameAttribute != null)
            {
                logName   = nameAttribute.Name;
                shortName = logName;
                if (!FunctionNameAttribute.FunctionNameValidationRegex.IsMatch(logName))
                {
                    throw new InvalidOperationException(string.Format("'{0}' is not a valid function name.", logName));
                }
            }

            return(new FunctionDescriptor
            {
                Id = method.GetFullName(),
                LogName = logName,
                FullName = method.GetFullName(),
                ShortName = shortName,
                IsDisabled = disabled,
                HasCancellationToken = hasCancellationToken,
                TimeoutAttribute = TypeUtility.GetHierarchicalAttributeOrNull <TimeoutAttribute>(method) ?? defaultTimeout,
                SingletonAttributes = method.GetCustomAttributes <SingletonAttribute>(),
                MethodLevelFilters = method.GetCustomAttributes().OfType <IFunctionFilter>(),
                ClassLevelFilters = method.DeclaringType.GetCustomAttributes().OfType <IFunctionFilter>()
            });
        }
 public FunctionIndexer(
     ITriggerBindingProvider triggerBindingProvider,
     IBindingProvider bindingProvider,
     IJobActivator activator,
     IFunctionExecutor executor,
     SingletonManager singletonManager,
     ILoggerFactory loggerFactory,
     INameResolver nameResolver      = null,
     SharedQueueHandler sharedQueue  = null,
     TimeoutAttribute defaultTimeout = null,
     bool allowPartialHostStartup    = false)
 {
     _triggerBindingProvider = triggerBindingProvider ?? throw new ArgumentNullException(nameof(triggerBindingProvider));
     _bindingProvider        = bindingProvider ?? throw new ArgumentNullException(nameof(bindingProvider));
     _activator               = activator ?? throw new ArgumentNullException(nameof(activator));
     _executor                = executor ?? throw new ArgumentNullException(nameof(executor));
     _singletonManager        = singletonManager ?? throw new ArgumentNullException(nameof(singletonManager));
     _nameResolver            = nameResolver;
     _logger                  = loggerFactory?.CreateLogger(LogCategories.Startup);
     _sharedQueue             = sharedQueue;
     _defaultTimeout          = defaultTimeout;
     _allowPartialHostStartup = allowPartialHostStartup;
 }
        public void OnFunctionTimeout_PerformsExpectedOperations()
        {
            System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromMinutes(1).TotalMilliseconds);
            timer.Start();

            Assert.True(timer.Enabled);
            Assert.False(_cancellationTokenSource.IsCancellationRequested);

            MethodInfo       method     = typeof(Functions).GetMethod("MethodLevel", BindingFlags.Static | BindingFlags.Public);
            TimeoutAttribute attribute  = method.GetCustomAttribute <TimeoutAttribute>();
            Guid             instanceId = Guid.Parse("B2D1DD72-80E2-412B-A22E-3B4558F378B4");

            FunctionExecutor.OnFunctionTimeout(timer, method, instanceId, attribute.Timeout, _traceWriter, _cancellationTokenSource);

            Assert.False(timer.Enabled);
            Assert.True(_cancellationTokenSource.IsCancellationRequested);

            TraceEvent trace = _traceWriter.Traces[0];

            Assert.Equal(TraceLevel.Error, trace.Level);
            Assert.Equal(TraceSource.Execution, trace.Source);
            Assert.Equal("Timeout value of 00:01:00 exceeded by function 'Functions.MethodLevel' (Id: 'b2d1dd72-80e2-412b-a22e-3b4558f378b4'). Initiating cancellation.", trace.Message);
        }
        internal static async Task ExecuteWithWatchersAsync(IFunctionInstance instance,
                                                            IReadOnlyDictionary <string, IValueProvider> parameters,
                                                            TraceWriter traceWriter,
                                                            CancellationTokenSource functionCancellationTokenSource)
        {
            IFunctionInvoker       invoker        = instance.Invoker;
            IReadOnlyList <string> parameterNames = invoker.ParameterNames;
            IDelayedException      delayedBindingException;

            object[] invokeParameters = PrepareParameters(parameterNames, parameters, out delayedBindingException);

            if (delayedBindingException != null)
            {
                // This is done inside a watcher context so that each binding error is publish next to the binding in
                // the parameter status log.
                delayedBindingException.Throw();
            }

            // if the function is a Singleton, aquire the lock
            SingletonLock singleton = null;

            if (TryGetSingletonLock(parameters, out singleton))
            {
                await singleton.AcquireAsync(functionCancellationTokenSource.Token);
            }

            // Create a source specifically for timeouts
            using (CancellationTokenSource timeoutTokenSource = new CancellationTokenSource())
            {
                MethodInfo       method           = instance.FunctionDescriptor.Method;
                TimeoutAttribute timeoutAttribute = TypeUtility.GetHierarchicalAttributeOrNull <TimeoutAttribute>(method);
                bool             throwOnTimeout   = timeoutAttribute == null ? false : timeoutAttribute.ThrowOnTimeout;
                var      timer         = StartFunctionTimeout(instance, timeoutAttribute, timeoutTokenSource, traceWriter);
                TimeSpan timerInterval = timer == null ? TimeSpan.MinValue : TimeSpan.FromMilliseconds(timer.Interval);
                try
                {
                    await InvokeAsync(invoker, invokeParameters, timeoutTokenSource, functionCancellationTokenSource,
                                      throwOnTimeout, timerInterval, instance);
                }
                finally
                {
                    if (timer != null)
                    {
                        timer.Stop();
                        timer.Dispose();
                    }
                }
            }

            // Process any out parameters and persist any pending values.
            // Ensure IValueBinder.SetValue is called in BindStepOrder. This ordering is particularly important for
            // ensuring queue outputs occur last. That way, all other function side-effects are guaranteed to have
            // occurred by the time messages are enqueued.
            string[] parameterNamesInBindOrder = SortParameterNamesInStepOrder(parameters);
            foreach (string name in parameterNamesInBindOrder)
            {
                IValueProvider provider = parameters[name];
                IValueBinder   binder   = provider as IValueBinder;

                if (binder != null)
                {
                    object argument = invokeParameters[GetParameterIndex(parameterNames, name)];

                    try
                    {
                        // This could do complex things that may fail. Catch the exception.
                        await binder.SetValueAsync(argument, functionCancellationTokenSource.Token);
                    }
                    catch (OperationCanceledException)
                    {
                        throw;
                    }
                    catch (Exception exception)
                    {
                        string message = String.Format(CultureInfo.InvariantCulture,
                                                       "Error while handling parameter {0} after function returned:", name);
                        throw new InvalidOperationException(message, exception);
                    }
                }
            }

            if (singleton != null)
            {
                await singleton.ReleaseAsync(functionCancellationTokenSource.Token);
            }
        }
Beispiel #31
0
 public void TimeoutAttribute()
 {
     var attr = new TimeoutAttribute(50) as IApplyToContext;
     attr.ApplyToContext(_context);
     Assert.That(_context.TestCaseTimeout, Is.EqualTo(50));
 }