public void BasicHttpFunction() { var generator = new FunctionMetadataGenerator(); var typeDef = TestUtility.GetTypeDefinition(typeof(BasicHttp)); var functions = generator.GenerateFunctionMetadata(typeDef); ValidateFunction(functions.Single(), BasicHttp.FunctionName, GetEntryPoint(nameof(BasicHttp), nameof(BasicHttp.Http)), b => ValidateTrigger(b), b => ValidateReturn(b)); void ValidateTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "myReq" }, { "Type", "HttpTrigger" }, { "Direction", "In" }, { "authLevel", "Admin" }, { "methods", new[] { "get", "Post" } }, { "Route", "/api2" } }); } void ValidateReturn(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "$return" }, { "Type", "http" }, { "Direction", "Out" } }); } FunctionMetadataJsonWriter.WriteMetadata(functions, "."); }
public void MultiOutput_OnReturnType() { var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); var typeDef = TestUtility.GetTypeDefinition(typeof(MultiOutput_ReturnType)); var functions = generator.GenerateFunctionMetadata(typeDef); var extensions = generator.Extensions; Assert.Single(functions); var queueToBlob = functions.Single(p => p.Name == "QueueToBlobFunction"); ValidateFunction(queueToBlob, "QueueToBlobFunction", GetEntryPoint(nameof(MultiOutput_ReturnType), nameof(MultiOutput_ReturnType.QueueToBlob)), b => ValidateQueueTrigger(b), b => ValidateBlobOutput(b), b => ValidateQueueOutput(b)); AssertDictionary(extensions, new Dictionary <string, string> { { "Microsoft.Azure.WebJobs.Extensions.Storage", "4.0.4" } }); void ValidateQueueTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "queuePayload" }, { "Type", "QueueTrigger" }, { "Direction", "In" }, { "Connection", "MyConnection" }, { "queueName", "queueName" }, { "DataType", "String" } }); } void ValidateBlobOutput(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "blobOutput" }, { "Type", "Blob" }, { "Direction", "Out" }, { "blobPath", "container1/hello.txt" }, { "Connection", "MyOtherConnection" }, { "DataType", "String" } }); } void ValidateQueueOutput(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "queueOutput" }, { "Type", "Queue" }, { "Direction", "Out" }, { "queueName", "queue2" }, { "DataType", "String" } }); } }
public void BasicHttpFunctionWithNoResponse() { var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); var typeDef = TestUtility.GetTypeDefinition(typeof(BasicHttpWithNoResponse)); var functions = generator.GenerateFunctionMetadata(typeDef); var extensions = generator.Extensions; AssertDictionary(extensions, new Dictionary <string, string> { }); ValidateFunction(functions.Single(), BasicHttpWithNoResponse.FunctionName, GetEntryPoint(nameof(BasicHttpWithNoResponse), nameof(BasicHttpWithNoResponse.Http)), b => ValidateTrigger(b)); void ValidateTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "myReq" }, { "Type", "HttpTrigger" }, { "Direction", "In" }, { "authLevel", "Admin" }, { "methods", new[] { "get", "Post" } }, { "Route", "/api2" } }); } FunctionMetadataJsonWriter.WriteMetadata(functions, "."); }
public void TimerFunction() { var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); var typeDef = TestUtility.GetTypeDefinition(typeof(Timer)); var functions = generator.GenerateFunctionMetadata(typeDef); var extensions = generator.Extensions; ValidateFunction(functions.Single(), "TimerFunction", GetEntryPoint(nameof(Timer), nameof(Timer.RunTimer)), b => ValidateTrigger(b)); AssertDictionary(extensions, new Dictionary <string, string>()); void ValidateTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "timer" }, { "Type", "TimerTrigger" }, { "Direction", "In" }, { "schedule", "0 0 0 * * *" }, { "RunOnStartup", false } }); } }
public void CardinalityMany_WithNotIterableTypeThrows() { var generator = new FunctionMetadataGenerator(); var typeDef = TestUtility.GetTypeDefinition(typeof(EventHubNotBatched)); var exception = Assert.Throws <FunctionsMetadataGenerationException>(() => generator.GenerateFunctionMetadata(typeDef)); Assert.Contains("Function is configured to process events in batches but parameter type is not iterable", exception.Message); }
public void EnableImplicitRegistration_NotSet() { // This test assembly explicitly has an ExtensionInformationAttribute, without setting EnableImplicitRegistration var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); generator.GenerateFunctionMetadata(module); Assert.Empty(generator.Extensions); }
public void MultiOutput_OnReturnType_WithHttp() { var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); var typeDef = TestUtility.GetTypeDefinition(typeof(MultiOutput_ReturnType_Http)); var functions = generator.GenerateFunctionMetadata(typeDef); var extensions = generator.Extensions; Assert.Single(functions); var HttpAndQueue = functions.Single(p => p.Name == "HttpAndQueue"); ValidateFunction(HttpAndQueue, "HttpAndQueue", GetEntryPoint(nameof(MultiOutput_ReturnType_Http), nameof(MultiOutput_ReturnType_Http.HttpAndQueue)), b => ValidateHttpTrigger(b), b => ValidateQueueOutput(b), b => ValidateHttpOutput(b)); AssertDictionary(extensions, new Dictionary <string, string> { { "Microsoft.Azure.WebJobs.Extensions.Storage", "4.0.4" } }); void ValidateHttpTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "req" }, { "Type", "HttpTrigger" }, { "Direction", "In" }, { "methods", new[] { "get" } }, { "DataType", "String" } }); } void ValidateHttpOutput(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "httpResponseProp" }, { "Type", "http" }, { "Direction", "Out" } }); } void ValidateQueueOutput(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "queueOutput" }, { "Type", "Queue" }, { "Direction", "Out" }, { "queueName", "queue2" }, { "DataType", "String" } }); } }
public void MultiOutput_OnMethod_Throws() { var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); var typeDef = TestUtility.GetTypeDefinition(typeof(MultiOutput_Method)); var exception = Assert.Throws <FunctionsMetadataGenerationException>(() => generator.GenerateFunctionMetadata(typeDef)); Assert.Contains($"Found multiple Output bindings on method", exception.Message); }
public void EnableImplicitRegistration_False() { var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); // Inject enableImplicitRegistration = false into the constructor var enableImplicitRegistrationParam = new CustomAttributeArgument(TestUtility.GetTypeDefinition(typeof(bool)), false); var extInfo = module.Assembly.CustomAttributes.Single(p => p.AttributeType.FullName == Constants.ExtensionsInformationType); extInfo.ConstructorArguments.Add(enableImplicitRegistrationParam); generator.GenerateFunctionMetadata(module); Assert.Empty(generator.Extensions); }
public void CardinalityManyFunctions(string functionName, string entryPoint, bool cardinalityMany, string dataType) { var generator = new FunctionMetadataGenerator(); var typeDef = TestUtility.GetTypeDefinition(typeof(CardinalityMany)); var functions = generator.GenerateFunctionMetadata(typeDef); var extensions = generator.Extensions; SdkFunctionMetadata metadata = functions.Where(a => string.Equals(a.Name, functionName, StringComparison.Ordinal)).Single(); ValidateFunction(metadata, functionName, GetEntryPoint(nameof(CardinalityMany), entryPoint), b => ValidateTrigger(b, cardinalityMany)); AssertDictionary(extensions, new Dictionary <string, string>() { { "Microsoft.Azure.WebJobs.Extensions.EventHubs", "4.2.0" } }); void ValidateTrigger(ExpandoObject b, bool many) { var expected = new Dictionary <string, object>() { { "Name", "input" }, { "Type", "EventHubTrigger" }, { "Direction", "In" }, { "eventHubName", "test" }, { "Connection", "EventHubConnectionAppSetting" } }; if (many) { expected.Add("Cardinality", "Many"); } else { expected.Add("Cardinality", "One"); } if (!string.IsNullOrEmpty(dataType)) { expected.Add("DataType", dataType); } AssertExpandoObject(b, expected); } }
public void JustHttp_OnReturnTypeProperty() { var generator = new FunctionMetadataGenerator(); var module = ModuleDefinition.ReadModule(_thisAssembly.Location); var typeDef = TestUtility.GetTypeDefinition(typeof(ReturnType_JustHttp)); var functions = generator.GenerateFunctionMetadata(typeDef); var extensions = generator.Extensions; Assert.Single(functions); var HttpAndQueue = functions.Single(p => p.Name == "JustHtt"); ValidateFunction(HttpAndQueue, "JustHtt", GetEntryPoint(nameof(ReturnType_JustHttp), nameof(ReturnType_JustHttp.Justhtt)), b => ValidateHttpTrigger(b), b => ValidateHttpOutput(b)); AssertDictionary(extensions, new Dictionary <string, string>()); void ValidateHttpTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "req" }, { "Type", "HttpTrigger" }, { "Direction", "In" }, { "methods", new[] { "get" } }, { "DataType", "String" } }); } void ValidateHttpOutput(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "httpResponseProp" }, { "Type", "http" }, { "Direction", "Out" } }); } }
public override bool Execute() { try { var functionGenerator = new FunctionMetadataGenerator(MSBuildLogger); var functions = functionGenerator.GenerateFunctionMetadata(AssemblyPath !, ReferencePaths.Select(p => p.ItemSpec)); var extensions = functionGenerator.Extensions; var extensionsCsProjGenerator = new ExtensionsCsprojGenerator(extensions, ExtensionsCsProjFilePath !, AzureFunctionsVersion !); extensionsCsProjGenerator.Generate(); FunctionMetadataJsonWriter.WriteMetadata(functions, OutputPath !); } catch (FunctionsMetadataGenerationException) { Log.LogError($"Unable to build Azure Functions metadata for {AssemblyPath}"); return(false); } return(true); }
public void StorageFunctions() { var generator = new FunctionMetadataGenerator(); var typeDef = TestUtility.GetTypeDefinition(typeof(Storage)); var functions = generator.GenerateFunctionMetadata(typeDef); Assert.Equal(2, functions.Count()); var queueToBlob = functions.Single(p => p.Name == "QueueToBlobFunction"); var blobToQueue = functions.Single(p => p.Name == "BlobToQueueFunction"); ValidateFunction(queueToBlob, "QueueToBlobFunction", GetEntryPoint(nameof(Storage), nameof(Storage.QueueToBlob)), b => ValidateQueueTrigger(b), b => ValidateBlobOutput(b)); void ValidateQueueTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "queuePayload" }, { "Type", "QueueTrigger" }, { "Direction", "In" }, { "Connection", "MyConnection" }, { "queueName", "queueName" } }); } void ValidateBlobOutput(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "blobOutput" }, { "Type", "Blob" }, { "Direction", "Out" }, { "blobPath", "container1/hello.txt" }, { "Connection", "MyOtherConnection" }, { "access", "ReadWrite" } }); } ValidateFunction(blobToQueue, "BlobToQueueFunction", GetEntryPoint(nameof(Storage), nameof(Storage.BlobToQueue)), b => ValidateBlobTrigger(b), b => ValidateQueueOutput(b)); void ValidateBlobTrigger(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "blob" }, { "Type", "BlobTrigger" }, { "Direction", "In" }, { "blobPath", "container2/%file%" } }); } void ValidateQueueOutput(ExpandoObject b) { AssertExpandoObject(b, new Dictionary <string, object> { { "Name", "queueOutput" }, { "Type", "Queue" }, { "Direction", "Out" }, { "queueName", "queue2" }, }); } }