public async Task IsFunction_ReturnsExpectedResult() { var host = TestHelpers.GetDefaultHost(o => { o.ScriptPath = TestHelpers.FunctionsTestDirectory; o.LogPath = TestHelpers.GetHostLogFileDirectory().FullName; }); await host.StartAsync(); var scriptHost = host.GetScriptHost(); var parameters = new Collection <ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); var metadata = new FunctionMetadata(); var invoker = new TestInvoker(); var function = new FunctionDescriptor("TestFunction", invoker, metadata, parameters, null, null, null); scriptHost.Functions.Add(function); var errors = new Collection <string>(); errors.Add("A really really bad error!"); scriptHost.FunctionErrors.Add("ErrorFunction", errors); Assert.True(scriptHost.IsFunction("TestFunction")); Assert.True(scriptHost.IsFunction("ErrorFunction")); Assert.False(scriptHost.IsFunction("DoesNotExist")); Assert.False(scriptHost.IsFunction(string.Empty)); Assert.False(scriptHost.IsFunction(null)); }
public void IsFunction_ReturnsExpectedResult() { Mock <IScriptHostEnvironment> mockEnvironment = new Mock <IScriptHostEnvironment>(MockBehavior.Strict); var config = new ScriptHostConfiguration(); var mockHost = new Mock <ScriptHost>(MockBehavior.Strict, new object[] { mockEnvironment.Object, config, null }); var functions = new Collection <FunctionDescriptor>(); var functionErrors = new Dictionary <string, Collection <string> >(); mockHost.Setup(p => p.Functions).Returns(functions); mockHost.Setup(p => p.FunctionErrors).Returns(functionErrors); var parameters = new Collection <ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); var metadata = new FunctionMetadata(); var invoker = new TestInvoker(); var function = new FunctionDescriptor("TestFunction", invoker, metadata, parameters); functions.Add(function); var errors = new Collection <string>(); errors.Add("A really really bad error!"); functionErrors.Add("ErrorFunction", errors); var host = mockHost.Object; Assert.True(host.IsFunction("TestFunction")); Assert.True(host.IsFunction("ErrorFunction")); Assert.False(host.IsFunction("DoesNotExist")); Assert.False(host.IsFunction(string.Empty)); Assert.False(host.IsFunction(null)); }
public async Task Generate_EndToEnd() { // construct our TimerTrigger attribute ([TimerTrigger("00:00:02", RunOnStartup = true)]) Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); ParameterDescriptor parameter = new ParameterDescriptor("timerInfo", typeof(TimerInfo)); ConstructorInfo ctorInfo = typeof(TimerTriggerAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo runOnStartupProperty = typeof(TimerTriggerAttribute).GetProperty("RunOnStartup"); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder( ctorInfo, new object[] { "00:00:02" }, new PropertyInfo[] { runOnStartupProperty }, new object[] { true }); parameter.CustomAttributes.Add(attributeBuilder); parameters.Add(parameter); // create the FunctionDefinition FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor("TimerFunction", invoker, metadata, parameters, null, null, null); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // Get the Type Attributes (in this case, a TimeoutAttribute) ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = TimeSpan.FromMinutes(5); Collection <CustomAttributeBuilder> typeAttributes = new Collection <CustomAttributeBuilder>(); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod("TimerFunction"); ParameterInfo triggerParameter = method.GetParameters()[0]; TimerTriggerAttribute triggerAttribute = triggerParameter.GetCustomAttribute <TimerTriggerAttribute>(); Assert.NotNull(triggerAttribute); // start the JobHost which will start running the timer function JobHostConfiguration config = new JobHostConfiguration() { TypeLocator = new TypeLocator(functionType), LoggerFactory = new LoggerFactory() }; config.UseTimers(); JobHost host = new JobHost(config); await host.StartAsync(); await Task.Delay(3000); await host.StopAsync(); // verify our custom invoker was called Assert.True(invoker.InvokeCount >= 2); }
public async Task Generate_EndToEnd() { // construct our TimerTrigger attribute ([TimerTrigger("00:00:02", RunOnStartup = true)]) Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); ParameterDescriptor parameter = new ParameterDescriptor("timerInfo", typeof(TimerInfo)); ConstructorInfo ctorInfo = typeof(TimerTriggerAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo runOnStartupProperty = typeof(TimerTriggerAttribute).GetProperty("RunOnStartup"); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder( ctorInfo, new object[] { "00:00:02" }, new PropertyInfo[] { runOnStartupProperty }, new object[] { true }); parameter.CustomAttributes.Add(attributeBuilder); parameters.Add(parameter); // create the FunctionDefinition FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor("TimerFunction", invoker, metadata, parameters); Collection<FunctionDescriptor> functions = new Collection<FunctionDescriptor>(); functions.Add(function); // Get the Type Attributes (in this case, a TimeoutAttribute) ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = TimeSpan.FromMinutes(5); Collection<CustomAttributeBuilder> typeAttributes = ScriptHost.CreateTypeAttributes(scriptConfig); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod("TimerFunction"); TimeoutAttribute timeoutAttribute = (TimeoutAttribute)functionType.GetCustomAttributes().Single(); Assert.Equal(TimeSpan.FromMinutes(5), timeoutAttribute.Timeout); Assert.True(timeoutAttribute.ThrowOnTimeout); Assert.True(timeoutAttribute.TimeoutWhileDebugging); ParameterInfo triggerParameter = method.GetParameters()[0]; TimerTriggerAttribute triggerAttribute = triggerParameter.GetCustomAttribute<TimerTriggerAttribute>(); Assert.NotNull(triggerAttribute); // start the JobHost which will start running the timer function JobHostConfiguration config = new JobHostConfiguration() { TypeLocator = new TypeLocator(functionType) }; config.UseTimers(); JobHost host = new JobHost(config); await host.StartAsync(); await Task.Delay(3000); await host.StopAsync(); // verify our custom invoker was called Assert.True(invoker.InvokeCount >= 2); }
public void Generate_WithMultipleOutParameters() { string functionName = "FunctionWithOuts"; Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); parameters.Add(new ParameterDescriptor("param2", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); parameters.Add(new ParameterDescriptor("param3", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // Make sure we don't generate a TimeoutAttribute if FunctionTimeout is null. ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = null; Collection <CustomAttributeBuilder> typeAttributes = ScriptHost.CreateTypeAttributes(scriptConfig); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); IEnumerable <Attribute> attributes = functionType.GetCustomAttributes(); Assert.Empty(attributes); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that out parameters were correctly generated Assert.True(functionParams[1].IsOut); Assert.True(functionParams[2].IsOut); // Verify that the method is invocable method.Invoke(null, new object[] { "test", null, null }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); }
public void Generate_WithOutParams_CorrectlyUpdatesOutput() { string functionName = "FunctionWithOutValue"; Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); FunctionMetadata metadata = new FunctionMetadata(); object[] invocationArguments = null; TestInvoker invoker = new TestInvoker(args => { invocationArguments = args; invocationArguments[0] = "newvalue"; }); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", null, functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that the method is invocable DateTimeOffset input = DateTimeOffset.Now; method.Invoke(null, new object[] { null }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); Assert.NotNull(invocationArguments); Assert.Equal("newvalue", (string)invocationArguments[0]); }
public void Generate_WithMultipleOutParameters() { string functionName = "FunctionWithOuts"; Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); parameters.Add(new ParameterDescriptor("param2", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); parameters.Add(new ParameterDescriptor("param3", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection<FunctionDescriptor> functions = new Collection<FunctionDescriptor>(); functions.Add(function); // Make sure we don't generate a TimeoutAttribute if FunctionTimeout is null. ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = null; Collection<CustomAttributeBuilder> typeAttributes = ScriptHost.CreateTypeAttributes(scriptConfig); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); IEnumerable<Attribute> attributes = functionType.GetCustomAttributes(); Assert.Empty(attributes); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that out parameters were correctly generated Assert.True(functionParams[1].IsOut); Assert.True(functionParams[2].IsOut); // Verify that the method is invocable method.Invoke(null, new object[] { "test", null, null }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); }
public void Generate_WithValueTypes_Succeeds() { string functionName = "FunctionWithValueTypes"; Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); parameters.Add(new ParameterDescriptor("param2", typeof(DateTimeOffset))); parameters.Add(new ParameterDescriptor("param3", typeof(int))); FunctionMetadata metadata = new FunctionMetadata(); object[] invocationArguments = null; TestInvoker invoker = new TestInvoker(args => { invocationArguments = args; }); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", null, functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that the method is invocable DateTimeOffset input = DateTimeOffset.Now; method.Invoke(null, new object[] { "test", input, 44 }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); Assert.NotNull(invocationArguments); Assert.Equal(input, (DateTimeOffset)invocationArguments[1]); Assert.Equal(44, (int)invocationArguments[2]); }
public void Generate_WithOutParams_CorrectlyUpdatesOutput() { string functionName = "FunctionWithOutValue"; Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string).MakeByRefType()) { Attributes = ParameterAttributes.Out }); FunctionMetadata metadata = new FunctionMetadata(); object[] invocationArguments = null; TestInvoker invoker = new TestInvoker(args => { invocationArguments = args; invocationArguments[0] = "newvalue"; }); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection<FunctionDescriptor> functions = new Collection<FunctionDescriptor>(); functions.Add(function); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that the method is invocable DateTimeOffset input = DateTimeOffset.Now; method.Invoke(null, new object[] { null }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); Assert.NotNull(invocationArguments); Assert.Equal("newvalue", (string)invocationArguments[0]); }
public void Generate_WithValueTypes_Succeeds() { string functionName = "FunctionWithValueTypes"; Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); parameters.Add(new ParameterDescriptor("param1", typeof(string))); parameters.Add(new ParameterDescriptor("param2", typeof(DateTimeOffset))); parameters.Add(new ParameterDescriptor("param3", typeof(int))); FunctionMetadata metadata = new FunctionMetadata(); object[] invocationArguments = null; TestInvoker invoker = new TestInvoker(args => { invocationArguments = args; }); FunctionDescriptor function = new FunctionDescriptor(functionName, invoker, metadata, parameters); Collection<FunctionDescriptor> functions = new Collection<FunctionDescriptor>(); functions.Add(function); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", functions); // verify the generated function MethodInfo method = functionType.GetMethod(functionName); ParameterInfo[] functionParams = method.GetParameters(); // Verify that we have the correct number of parameters Assert.Equal(parameters.Count, functionParams.Length); // Verify that the method is invocable DateTimeOffset input = DateTimeOffset.Now; method.Invoke(null, new object[] { "test", input, 44 }); // verify our custom invoker was called Assert.Equal(1, invoker.InvokeCount); Assert.NotNull(invocationArguments); Assert.Equal(input, (DateTimeOffset)invocationArguments[1]); Assert.Equal(44, (int)invocationArguments[2]); }
public async Task Generate_EndToEnd() { // construct our TimerTrigger attribute ([TimerTrigger("00:00:02", RunOnStartup = true)]) Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); ParameterDescriptor parameter = new ParameterDescriptor("timerInfo", typeof(TimerInfo)); ConstructorInfo ctorInfo = typeof(TimerTriggerAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo runOnStartupProperty = typeof(TimerTriggerAttribute).GetProperty("RunOnStartup"); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder( ctorInfo, new object[] { "00:00:02" }, new PropertyInfo[] { runOnStartupProperty }, new object[] { true }); parameter.CustomAttributes.Add(attributeBuilder); parameters.Add(parameter); // create the FunctionDefinition FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor("TimerFunction", invoker, metadata, parameters, null, null, null); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // Get the Type Attributes (in this case, a TimeoutAttribute) ScriptJobHostOptions scriptConfig = new ScriptJobHostOptions(); scriptConfig.FunctionTimeout = TimeSpan.FromMinutes(5); Collection <CustomAttributeBuilder> typeAttributes = new Collection <CustomAttributeBuilder>(); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod("TimerFunction"); ParameterInfo triggerParameter = method.GetParameters()[0]; TimerTriggerAttribute triggerAttribute = triggerParameter.GetCustomAttribute <TimerTriggerAttribute>(); Assert.NotNull(triggerAttribute); // start the JobHost which will start running the timer function var builder = new HostBuilder() .ConfigureWebJobs(b => { b.AddTimers() .AddAzureStorageCoreServices(); }) .ConfigureServices(s => { s.AddSingleton <ITypeLocator>(new TestTypeLocator(functionType)); s.AddSingleton <ILoggerFactory>(new LoggerFactory()); TestHelpers.AddTestAzureBlobStorageProvider(s, TestHelpers.GetTestConfiguration()); TestHostBuilderExtensions.AddMockedSingleton <IScriptHostManager>(s); }); using (var host = builder.Build()) { await host.StartAsync(); await Task.Delay(3000); await host.StopAsync(); } // verify our custom invoker was called Assert.True(invoker.InvokeCount >= 2); }