public void FunctionMetadataManager_Verify_FunctionErrors(string scriptFile)
        {
            Collection <FunctionMetadata> functionMetadataCollection = new Collection <FunctionMetadata>();

            functionMetadataCollection.Add(GetTestFunctionMetadata(scriptFile));

            ImmutableDictionary <string, ImmutableArray <string> > mockFunctionErrors = new Dictionary <string, ICollection <string> >().ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray());
            Mock <IFunctionMetadataProvider> mockFunctionMetadataProvider             = new Mock <IFunctionMetadataProvider>();

            mockFunctionMetadataProvider.Setup(m => m.GetFunctionMetadataAsync(It.IsAny <IEnumerable <RpcWorkerConfig> >(), SystemEnvironment.Instance, false)).Returns(Task.FromResult(functionMetadataCollection.ToImmutableArray()));
            mockFunctionMetadataProvider.Setup(m => m.FunctionErrors).Returns(mockFunctionErrors);

            var managerMock = new Mock <IScriptHostManager>();
            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), managerMock,
                                                                                                                         mockFunctionMetadataProvider.Object, new List <IFunctionProvider>(), new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory(), new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            managerMock.Raise(m => m.HostInitializing += null, new EventArgs());
            Assert.Empty(testFunctionMetadataManager.LoadFunctionMetadata());

            Assert.True(testFunctionMetadataManager.Errors.Count == 1);
            ImmutableArray <string> functionErrors = testFunctionMetadataManager.Errors["testFunction"];

            Assert.True(functionErrors.Length == 1);
            Assert.Equal(_expectedErrorMessage, functionErrors[0]);
        }
        public void FunctionMetadataManager_ThrowsError_DuplicateFunctions_FromFunctionProviders()
        {
            var functionMetadataCollection    = new Collection <FunctionMetadata>();
            var mockFunctionErrors            = new Dictionary <string, ImmutableArray <string> >();
            var mockFunctionMetadataProvider  = new Mock <IFunctionMetadataProvider>();
            var mockFunctionProvider          = new Mock <IFunctionProvider>();
            var mockFunctionProviderDuplicate = new Mock <IFunctionProvider>();
            var workerConfigs = TestHelpers.GetTestWorkerConfigs();

            mockFunctionMetadataProvider.Setup(m => m.GetFunctionMetadataAsync(workerConfigs, SystemEnvironment.Instance, false)).Returns(Task.FromResult(new Collection <FunctionMetadata>().ToImmutableArray()));
            mockFunctionMetadataProvider.Setup(m => m.FunctionErrors).Returns(new Dictionary <string, ICollection <string> >().ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray()));

            functionMetadataCollection.Add(GetTestFunctionMetadata("somefile.dll", name: "duplicateFunction"));

            mockFunctionProvider.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection.ToImmutableArray());
            mockFunctionProvider.Setup(m => m.FunctionErrors).Returns(mockFunctionErrors.ToImmutableDictionary());

            mockFunctionProviderDuplicate.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection.ToImmutableArray());
            mockFunctionProviderDuplicate.Setup(m => m.FunctionErrors).Returns(mockFunctionErrors.ToImmutableDictionary());

            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions),
                                                                                                                         mockFunctionMetadataProvider.Object, new List <IFunctionProvider>()
            {
                mockFunctionProvider.Object, mockFunctionProviderDuplicate.Object
            },
                                                                                                                         new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory(),
                                                                                                                         new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            var ex = Assert.Throws <InvalidOperationException>(() => testFunctionMetadataManager.LoadFunctionMetadata());

            Assert.Equal("Found duplicate FunctionMetadata with the name duplicateFunction", ex.Message);
        }
        public void FunctionMetadataManager_IgnoresMetadata_FromFunctionProviders()
        {
            var functionMetadataCollection = new Collection <FunctionMetadata>();
            var mockFunctionErrors         = new Dictionary <string, ImmutableArray <string> >();

            var mockFunctionMetadataProvider = new Mock <IFunctionMetadataProvider>();
            var mockFunctionProvider         = new Mock <IFunctionProvider>();
            var workerConfigs = TestHelpers.GetTestWorkerConfigs();

            mockFunctionMetadataProvider.Setup(m => m.GetFunctionMetadataAsync(workerConfigs, SystemEnvironment.Instance, false)).Returns(Task.FromResult(new Collection <FunctionMetadata>().ToImmutableArray()));
            mockFunctionMetadataProvider.Setup(m => m.FunctionErrors).Returns(new Dictionary <string, ICollection <string> >().ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray()));

            functionMetadataCollection.Add(GetTestFunctionMetadata("somefile.dll", name: "anotherFunction"));

            mockFunctionProvider.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection.ToImmutableArray());
            mockFunctionProvider.Setup(m => m.FunctionErrors).Returns(mockFunctionErrors.ToImmutableDictionary());

            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions),
                                                                                                                         mockFunctionMetadataProvider.Object, new List <IFunctionProvider>()
            {
                mockFunctionProvider.Object
            }, new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory(), new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            Assert.Equal(0, testFunctionMetadataManager.GetFunctionMetadata(true, includeCustomProviders: false).Length);
            Assert.Equal(0, testFunctionMetadataManager.Errors.Count);
        }
        public void IsScriptFileDetermined_ScriptFile_Emtpy_HttpWorker_Returns_True(string scriptFile)
        {
            FunctionMetadata functionMetadata = GetTestFunctionMetadata(scriptFile);

            var managerMock = new Mock <IScriptHostManager>();

            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), managerMock,
                                                                                                                         _mockFunctionMetadataProvider.Object, new List <IFunctionProvider>(), new OptionsWrapper <HttpWorkerOptions>(GetTestHttpWorkerOptions()), MockNullLoggerFactory.CreateLoggerFactory(), new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            managerMock.Raise(m => m.HostInitializing += null, new EventArgs());

            Assert.True(testFunctionMetadataManager.IsScriptFileDetermined(functionMetadata));
        }
        public void FunctionMetadataManager_ResetProviders_OnRefresh()
        {
            var functionMetadataCollection   = new Collection <FunctionMetadata>();
            var mockFunctionErrors           = new Dictionary <string, ImmutableArray <string> >();
            var mockFunctionMetadataProvider = new Mock <IFunctionMetadataProvider>();
            var mockFunctionProvider         = new Mock <IFunctionProvider>();
            var workerConfigs = TestHelpers.GetTestWorkerConfigs();

            mockFunctionMetadataProvider.Setup(m => m.GetFunctionMetadataAsync(workerConfigs, SystemEnvironment.Instance, false)).Returns(Task.FromResult(new Collection <FunctionMetadata>().ToImmutableArray()));
            mockFunctionMetadataProvider.Setup(m => m.FunctionErrors).Returns(new Dictionary <string, ICollection <string> >().ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray()));

            functionMetadataCollection.Add(GetTestFunctionMetadata("somefile.dll", name: "myFunction"));

            mockFunctionProvider.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection.ToImmutableArray());
            mockFunctionProvider.Setup(m => m.FunctionErrors).Returns(mockFunctionErrors.ToImmutableDictionary());

            var managerMock = new Mock <IScriptHostManager>();

            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), managerMock,
                                                                                                                         mockFunctionMetadataProvider.Object, new List <IFunctionProvider>()
            {
                mockFunctionProvider.Object
            }, new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory(), new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            testFunctionMetadataManager.LoadFunctionMetadata();

            Assert.Equal(0, testFunctionMetadataManager.Errors.Count);
            Assert.Equal(1, testFunctionMetadataManager.GetFunctionMetadata(true).Length);
            Assert.Equal("myFunction", testFunctionMetadataManager.GetFunctionMetadata(true).FirstOrDefault()?.Name);

            functionMetadataCollection = new Collection <FunctionMetadata>
            {
                GetTestFunctionMetadata("somefile.dll", name: "newFunction")
            };

            mockFunctionProvider = new Mock <IFunctionProvider>();
            mockFunctionProvider.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection.ToImmutableArray());

            managerMock.As <IServiceProvider>().Setup(m => m.GetService(typeof(IEnumerable <IFunctionProvider>))).Returns(new List <IFunctionProvider>()
            {
                mockFunctionProvider.Object
            });
            testFunctionMetadataManager.LoadFunctionMetadata();

            Assert.Equal(0, testFunctionMetadataManager.Errors.Count);
            Assert.Equal(1, testFunctionMetadataManager.GetFunctionMetadata(true).Length);
            Assert.Equal("newFunction", testFunctionMetadataManager.GetFunctionMetadata(true).FirstOrDefault()?.Name);
        }
        private void AddProxyProvider(IServiceCollection services, string rootPath)
        {
            var jobHostOptions = new ScriptJobHostOptions
            {
                RootLogPath    = rootPath,
                RootScriptPath = rootPath
            };
            var jobHostOptionsWrapped   = new OptionsWrapper <ScriptJobHostOptions>(jobHostOptions);
            var nullLogger              = new NullLoggerFactory();
            var proxyMetadataProvider   = new ProxyFunctionProvider(jobHostOptionsWrapped, new Mock <IEnvironment>().Object, new Mock <IScriptEventManager>().Object, nullLogger);
            var functionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(jobHostOptionsWrapped, new Mock <IFunctionMetadataProvider>().Object,
                                                                                                 new List <IFunctionProvider>()
            {
                proxyMetadataProvider
            }, new OptionsWrapper <HttpWorkerOptions>(new HttpWorkerOptions()), nullLogger, new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            services.AddSingleton <IFunctionMetadataManager>(functionMetadataManager);
        }
        public FunctionMetadataManagerTests()
        {
            _mockFunctionMetadataProvider = new Mock <IFunctionMetadataProvider>();
            string functionsPath = Path.Combine(Environment.CurrentDirectory, @"..", "..", "..", "..", "..", "sample", "node");

            _defaultHttpWorkerOptions            = new HttpWorkerOptions();
            _scriptJobHostOptions.RootScriptPath = functionsPath;

            _mockScriptHostManager       = new Mock <IScriptHostManager>();
            _testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(
                new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions),
                _mockScriptHostManager,
                _mockFunctionMetadataProvider.Object,
                new List <IFunctionProvider>(),
                new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions),
                MockNullLoggerFactory.CreateLoggerFactory(),
                new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));
        }
        public void FunctionMetadataManager_DoesNotError_MissingScriptFile_InWebHostMode()
        {
            var mockFunctionMetadataProvider = new Mock <IFunctionMetadataProvider>();
            var mockFunctionProvider         = new Mock <IFunctionProvider>();

            var testMetadata = GetTestFunctionMetadata(null);

            var managerMock = new Mock <IScriptHostManager>();
            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), managerMock,
                                                                                                                         mockFunctionMetadataProvider.Object, new List <IFunctionProvider>()
            {
                mockFunctionProvider.Object
            }, new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory(), new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            Assert.True(testFunctionMetadataManager.IsScriptFileDetermined(testMetadata));

            managerMock.Raise(m => m.HostInitializing += null, new EventArgs());

            Assert.False(testFunctionMetadataManager.IsScriptFileDetermined(testMetadata));
        }
        public void FunctionMetadataManager_Verify_FunctionErrors_FromFunctionProviders(string scriptFile)
        {
            var functionMetadataCollection   = new Collection <FunctionMetadata>();
            var mockFunctionErrors           = new Dictionary <string, ImmutableArray <string> >();
            var mockFunctionMetadataProvider = new Mock <IFunctionMetadataProvider>();
            var mockFunctionProvider         = new Mock <IFunctionProvider>();
            var workerConfigs = TestHelpers.GetTestWorkerConfigs();

            mockFunctionMetadataProvider.Setup(m => m.GetFunctionMetadataAsync(workerConfigs, SystemEnvironment.Instance, false)).Returns(Task.FromResult(new Collection <FunctionMetadata>().ToImmutableArray()));
            mockFunctionMetadataProvider.Setup(m => m.FunctionErrors).Returns(new Dictionary <string, ICollection <string> >().ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray()));

            functionMetadataCollection.Add(GetTestFunctionMetadata(scriptFile));
            functionMetadataCollection.Add(GetTestFunctionMetadata(scriptFile, name: "anotherFunction"));
            mockFunctionErrors["anotherFunction"] = new List <string>()
            {
                "error"
            }.ToImmutableArray();

            mockFunctionProvider.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection.ToImmutableArray());
            mockFunctionProvider.Setup(m => m.FunctionErrors).Returns(mockFunctionErrors.ToImmutableDictionary());

            var managerMock = new Mock <IScriptHostManager>();
            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), managerMock,
                                                                                                                         mockFunctionMetadataProvider.Object, new List <IFunctionProvider>()
            {
                mockFunctionProvider.Object
            }, new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory(), new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));

            managerMock.Raise(m => m.HostInitializing += null, new EventArgs());

            testFunctionMetadataManager.LoadFunctionMetadata();

            Assert.Equal(2, testFunctionMetadataManager.Errors.Count);
            ImmutableArray <string> functionErrors = testFunctionMetadataManager.Errors["anotherFunction"];

            Assert.Equal(2, functionErrors.Length);
            Assert.True(functionErrors.Contains("error"));
        }
        public void FunctionMetadataManager_SortsMetadata_FromFunctionProviders()
        {
            var functionMetadataCollection   = new Collection <FunctionMetadata>();
            var mockFunctionMetadataProvider = new Mock <IFunctionMetadataProvider>();
            var mockFunctionProvider         = new Mock <IFunctionProvider>();

            var workerConfigs = TestHelpers.GetTestWorkerConfigs();

            mockFunctionMetadataProvider.Setup(m => m.GetFunctionMetadataAsync(workerConfigs, SystemEnvironment.Instance, false)).Returns(Task.FromResult(new Collection <FunctionMetadata>().ToImmutableArray()));
            mockFunctionMetadataProvider.Setup(m => m.FunctionErrors).Returns(new Dictionary <string, ICollection <string> >().ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray()));

            const string aFunction = "aFunction";
            const string bFunction = "bFunction";
            const string cFunction = "cFunction";

            // Add in unsorted order
            functionMetadataCollection.Add(GetTestFunctionMetadata("b.dll", name: bFunction));
            functionMetadataCollection.Add(GetTestFunctionMetadata("a.dll", name: aFunction));
            functionMetadataCollection.Add(GetTestFunctionMetadata("c.dll", name: cFunction));
            functionMetadataCollection.Add(GetTestFunctionMetadata("null.dll", name: null));

            mockFunctionProvider.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection.ToImmutableArray());

            FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions),
                                                                                                                         mockFunctionMetadataProvider.Object, new List <IFunctionProvider>()
            {
                mockFunctionProvider.Object
            }, new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory(), new OptionsWrapper <LanguageWorkerOptions>(TestHelpers.GetTestLanguageWorkerOptions()));
            var functionMetadata = testFunctionMetadataManager.LoadFunctionMetadata();

            Assert.Equal(4, functionMetadata.Length);

            Assert.Null(functionMetadata[0].Name);
            Assert.True(string.Equals(aFunction, functionMetadata[1].Name));
            Assert.True(string.Equals(bFunction, functionMetadata[2].Name));
            Assert.True(string.Equals(cFunction, functionMetadata[3].Name));
        }