public void Create_ConstantSchedule_CreatesExpectedSchedule() { TimerTriggerAttribute attribute = new TimerTriggerAttribute("00:00:15"); INameResolver nameResolver = new TestNameResolver(); ConstantSchedule schedule = (ConstantSchedule)TimerSchedule.Create(attribute, nameResolver, _logger); Assert.False(attribute.UseMonitor); var log = _loggerProvider.GetAllLogMessages().Single(); Assert.Equal("UseMonitor changed to false based on schedule frequency.", log.FormattedMessage); Assert.Equal(LogLevel.Debug, log.Level); DateTime now = new DateTime(2015, 5, 22, 9, 45, 00); DateTime nextOccurrence = schedule.GetNextOccurrence(now); Assert.Equal(new TimeSpan(0, 0, 15), nextOccurrence - now); // For schedules occuring on an interval greater than a minute, we expect // UseMonitor to be defaulted to true _loggerProvider.ClearAllLogMessages(); attribute = new TimerTriggerAttribute("01:00:00"); schedule = (ConstantSchedule)TimerSchedule.Create(attribute, nameResolver, _logger); Assert.True(attribute.UseMonitor); Assert.Empty(_loggerProvider.GetAllLogMessages()); // verify that if UseMonitor is set explicitly, it is not overridden attribute = new TimerTriggerAttribute("01:00:00"); attribute.UseMonitor = false; schedule = (ConstantSchedule)TimerSchedule.Create(attribute, nameResolver, _logger); Assert.False(attribute.UseMonitor); Assert.Empty(_loggerProvider.GetAllLogMessages()); }
public void Create_ConstantSchedule_CreatesExpectedSchedule() { TimerTriggerAttribute attribute = new TimerTriggerAttribute("00:00:15"); INameResolver nameResolver = new TestNameResolver(); ConstantSchedule schedule = (ConstantSchedule)TimerSchedule.Create(attribute, nameResolver); Assert.False(attribute.UseMonitor); DateTime now = new DateTime(2015, 5, 22, 9, 45, 00); DateTime nextOccurrence = schedule.GetNextOccurrence(now); Assert.Equal(new TimeSpan(0, 0, 15), nextOccurrence - now); // For schedules occuring on an interval greater than a minute, we expect // UseMonitor to be defaulted to true attribute = new TimerTriggerAttribute("01:00:00"); schedule = (ConstantSchedule)TimerSchedule.Create(attribute, nameResolver); Assert.True(attribute.UseMonitor); // verify that if UseMonitor is set explicitly, it is not overridden attribute = new TimerTriggerAttribute("01:00:00"); attribute.UseMonitor = false; schedule = (ConstantSchedule)TimerSchedule.Create(attribute, nameResolver); Assert.False(attribute.UseMonitor); }
public void Create_InvalidSchedule() { TimerTriggerAttribute attribute = new TimerTriggerAttribute("invalid"); ArgumentException ex = Assert.Throws <ArgumentException>(() => { TimerSchedule.Create(attribute, new TestNameResolver()); }); Assert.Equal("The schedule expression 'invalid' was not recognized as a valid cron expression or timespan string.", ex.Message); }
public void Create_CustomSchedule_CreatesExpectedSchedule() { TimerTriggerAttribute attribute = new TimerTriggerAttribute(typeof(CustomSchedule)); INameResolver nameResolver = new TestNameResolver(); CustomSchedule schedule = (CustomSchedule)TimerSchedule.Create(attribute, nameResolver); Assert.NotNull(schedule); Assert.True(attribute.UseMonitor); // verify that if UseMonitor is set explicitly, it is not overridden attribute = new TimerTriggerAttribute(typeof(CustomSchedule)); attribute.UseMonitor = false; schedule = (CustomSchedule)TimerSchedule.Create(attribute, nameResolver); Assert.False(attribute.UseMonitor); }
public void Create_UsesNameResolver() { TimerTriggerAttribute attribute = new TimerTriggerAttribute("%test_schedule%"); TestNameResolver nameResolver = new TestNameResolver(); nameResolver.Values.Add("test_schedule", "*/15 * * * * *"); CronSchedule schedule = (CronSchedule)TimerSchedule.Create(attribute, nameResolver); Assert.False(attribute.UseMonitor); DateTime now = new DateTime(2015, 5, 22, 9, 45, 00); DateTime nextOccurrence = schedule.GetNextOccurrence(now); Assert.Equal(new TimeSpan(0, 0, 15), nextOccurrence - now); }
private void VerifyConstantSchedule(string expression, TimeSpan expectedInterval) { Assert.True(TimeSpan.TryParse(expression, out TimeSpan timeSpan)); Assert.Equal(timeSpan, expectedInterval); TimerTriggerAttribute attribute = new TimerTriggerAttribute(expression); INameResolver nameResolver = new TestNameResolver(); ConstantSchedule schedule = (ConstantSchedule)TimerSchedule.Create(attribute, nameResolver, _logger); DateTime now = new DateTime(2015, 5, 22, 9, 45, 00); var occurrences = schedule.GetNextOccurrences(5, now); for (int i = 0; i < 4; i++) { var delta = occurrences.ElementAt(i + 1) - occurrences.ElementAt(i); Assert.Equal(expectedInterval, delta); } }
private void CreateTestListener(string expression, bool useMonitor = true, Action functionAction = null) { _attribute = new TimerTriggerAttribute(expression); _schedule = TimerSchedule.Create(_attribute, new TestNameResolver()); _attribute.UseMonitor = useMonitor; _options = new TimersOptions(); _mockScheduleMonitor = new Mock <ScheduleMonitor>(MockBehavior.Strict); _mockTriggerExecutor = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict); FunctionResult result = new FunctionResult(true); _mockTriggerExecutor.Setup(p => p.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>())) .Callback <TriggeredFunctionData, CancellationToken>((mockFunctionData, mockToken) => { _triggeredFunctionData = mockFunctionData; functionAction?.Invoke(); }) .Returns(Task.FromResult(result)); _logger = new TestLogger(null); _listener = new TimerListener(_attribute, _schedule, _testTimerName, _options, _mockTriggerExecutor.Object, _logger, _mockScheduleMonitor.Object); }
public async Task BindAsync_ReturnsExpectedTriggerData() { ParameterInfo parameter = GetType().GetMethod("TestTimerJob").GetParameters()[0]; MethodInfo methodInfo = (MethodInfo)parameter.Member; string timerName = string.Format("{0}.{1}", methodInfo.DeclaringType.FullName, methodInfo.Name); Mock <ScheduleMonitor> mockScheduleMonitor = new Mock <ScheduleMonitor>(MockBehavior.Strict); ScheduleStatus status = new ScheduleStatus(); mockScheduleMonitor.Setup(p => p.GetStatusAsync(timerName)).ReturnsAsync(status); TimerTriggerAttribute attribute = parameter.GetCustomAttribute <TimerTriggerAttribute>(); INameResolver nameResolver = new TestNameResolver(); TimerSchedule schedule = TimerSchedule.Create(attribute, nameResolver); TimersConfiguration config = new TimersConfiguration(); config.ScheduleMonitor = mockScheduleMonitor.Object; ILoggerFactory loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(new TestLoggerProvider()); TimerTriggerBinding binding = new TimerTriggerBinding(parameter, attribute, schedule, config, loggerFactory.CreateLogger("Test")); // when we bind to a non-TimerInfo (e.g. in a Dashboard invocation) a new // TimerInfo is created, with the ScheduleStatus populated FunctionBindingContext functionContext = new FunctionBindingContext(Guid.NewGuid(), CancellationToken.None); ValueBindingContext context = new ValueBindingContext(functionContext, CancellationToken.None); TriggerData triggerData = (TriggerData)(await binding.BindAsync(string.Empty, context)); TimerInfo timerInfo = (TimerInfo)(await triggerData.ValueProvider.GetValueAsync()); Assert.Same(status, timerInfo.ScheduleStatus); // when we pass in a TimerInfo that is used TimerInfo expected = new TimerInfo(schedule, status); triggerData = (TriggerData)(await binding.BindAsync(expected, context)); timerInfo = (TimerInfo)(await triggerData.ValueProvider.GetValueAsync()); Assert.Same(expected, timerInfo); }
private void CreateTestListener(string expression, bool useMonitor = true) { _attribute = new TimerTriggerAttribute(expression); _schedule = TimerSchedule.Create(_attribute, new TestNameResolver()); _attribute.UseMonitor = useMonitor; _config = new TimersConfiguration(); _mockScheduleMonitor = new Mock <ScheduleMonitor>(MockBehavior.Strict); _config.ScheduleMonitor = _mockScheduleMonitor.Object; _mockTriggerExecutor = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict); FunctionResult result = new FunctionResult(true); _mockTriggerExecutor.Setup(p => p.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>())) .Callback <TriggeredFunctionData, CancellationToken>((mockFunctionData, mockToken) => { _triggeredFunctionData = mockFunctionData; }) .Returns(Task.FromResult(result)); JobHostConfiguration hostConfig = new JobHostConfiguration(); hostConfig.HostId = "testhostid"; _listener = new TimerListener(_attribute, _schedule, _testTimerName, _config, _mockTriggerExecutor.Object, new TestTraceWriter()); }
public Task <ITriggerBinding> TryCreateAsync(TriggerBindingProviderContext context) { if (context == null) { throw new ArgumentNullException("context"); } ParameterInfo parameter = context.Parameter; TimerTriggerAttribute timerTriggerAttribute = parameter.GetCustomAttribute <TimerTriggerAttribute>(inherit: false); if (timerTriggerAttribute == null) { return(Task.FromResult <ITriggerBinding>(null)); } if (parameter.ParameterType != typeof(TimerInfo)) { throw new InvalidOperationException(string.Format("Can't bind TimerTriggerAttribute to type '{0}'.", parameter.ParameterType)); } TimerSchedule schedule = TimerSchedule.Create(timerTriggerAttribute, _nameResolver, _logger); return(Task.FromResult <ITriggerBinding>(new TimerTriggerBinding(parameter, timerTriggerAttribute, schedule, _options, _logger, _scheduleMonitor))); }