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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 9
0
        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" },
                });
            }
        }