Esempio n. 1
0
        public void GetEngineCreatesNewEngineIfNotAtMaximum()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 1,
                MaxEngines    = 2,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            factory.Verify(x => x.EngineFactory(), Times.Exactly(2));
            pool.GetEngine();             // First engine created on init
            factory.Verify(x => x.EngineFactory(), Times.Exactly(2));
            Assert.AreEqual(1, pool.EngineCount);
            Assert.AreEqual(0, pool.AvailableEngineCount);

            pool.GetEngine();             // Second engine created JIT
            factory.Verify(x => x.EngineFactory(), Times.Exactly(3));
            Assert.AreEqual(2, pool.EngineCount);
            Assert.AreEqual(0, pool.AvailableEngineCount);
        }
Esempio n. 2
0
        public void GetEngineReturnsAllAvailableEngines()
        {
            var engines = new[]
            {
                new Mock <IJsEngine>().Object,
                new Mock <IJsEngine>().Object,
                new Mock <IJsEngine>().Object,
            };
            var factory = new Mock <IEngineFactoryForMock>();

            factory.SetupSequence(x => x.EngineFactory())
            // Initial call to factory is to determine engine type, we don't care
            // about that here.
            .Returns(new Mock <IJsEngine>().Object)
            .Returns(engines[0])
            .Returns(engines[1])
            .Returns(engines[2]);
            var config = new JsPoolConfig
            {
                StartEngines  = 3,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool          = new JsPool(config);
            var resultEngines = new[]
            {
                pool.GetEngine(),
                pool.GetEngine(),
                pool.GetEngine(),
            };

            CollectionAssert.AreEquivalent(engines, resultEngines);
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a new JavaScript engine pool.
        /// </summary>
        protected virtual IJsPool CreatePool()
        {
            var allFiles = _config.Scripts
                           .Concat(_config.ScriptsWithoutTransform)
                           .Select(_fileSystem.MapPath);

            var poolConfig = new JsPoolConfig
            {
                EngineFactory = _factory,
                Initializer   = InitialiseEngine,
                WatchPath     = _fileSystem.MapPath("~/"),
                WatchFiles    = allFiles
            };

            if (_config.MaxEngines != null)
            {
                poolConfig.MaxEngines = _config.MaxEngines.Value;
            }
            if (_config.StartEngines != null)
            {
                poolConfig.StartEngines = _config.StartEngines.Value;
            }
            if (_config.MaxUsagesPerEngine != null)
            {
                poolConfig.MaxUsagesPerEngine = _config.MaxUsagesPerEngine.Value;
            }

            var pool = new JsPool(poolConfig);

            // Reset the recycle exception on recycle. If there *are* errors loading the scripts
            // during recycle, the errors will be caught in the initializer.
            pool.Recycled += (sender, args) => _scriptLoadException = null;
            return(pool);
        }
        /// <summary>
        /// Creates a new JavaScript engine pool.
        /// </summary>
        protected virtual IJsPool CreatePool()
        {
            var allFiles = _config.Scripts
                           .Concat(_config.ScriptsWithoutTransform)
                           .Select(_fileSystem.MapPath);

            var poolConfig = new JsPoolConfig
            {
                EngineFactory = _factory,
                Initializer   = InitialiseEngine,
                WatchPath     = _fileSystem.MapPath("~/"),
                WatchFiles    = allFiles
            };

            if (_config.MaxEngines != null)
            {
                poolConfig.MaxEngines = _config.MaxEngines.Value;
            }
            if (_config.StartEngines != null)
            {
                poolConfig.StartEngines = _config.StartEngines.Value;
            }

            return(new JsPool(poolConfig));
        }
Esempio n. 5
0
        public void GetEngineReturnsAllAvailableEngines()
        {
            var engines = new[]
            {
                new Mock <IJsEngine>().Object,
                new Mock <IJsEngine>().Object,
                new Mock <IJsEngine>().Object,
            };
            var factory = new Mock <IEngineFactoryForMock>();

            factory.SetupSequence(x => x.EngineFactory())
            .Returns(engines[0])
            .Returns(engines[1])
            .Returns(engines[2]);
            var config = new JsPoolConfig
            {
                StartEngines  = 3,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool          = new JsPool(config);
            var resultEngines = new[]
            {
                pool.GetEngine().InnerEngine,
                pool.GetEngine().InnerEngine,
                pool.GetEngine().InnerEngine,
            };

            Assert.Equal(engines, resultEngines);
        }
Esempio n. 6
0
        public void DisposeDisposesAllEngines()
        {
            var engines = new[]
            {
                new Mock<IJsEngine>(),
                new Mock<IJsEngine>(),
                new Mock<IJsEngine>(),
                new Mock<IJsEngine>(),
            };
            var factory = new Mock<IEngineFactoryForMock>();
            factory.SetupSequence(x => x.EngineFactory())
                .Returns(engines[0].Object)
                .Returns(engines[1].Object)
                .Returns(engines[2].Object)
                .Returns(engines[3].Object);
            var config = new JsPoolConfig
            {
                StartEngines = 3,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);
            pool.Dispose();

            foreach (var engine in engines)
            {
                engine.Verify(x => x.Dispose());
            }
        }
Esempio n. 7
0
        protected override IJsPool CreatePool()
        {
            var allFiles = _config.Scripts
                           .Concat(_config.ScriptsWithoutTransform)
                           .Select(_fileSystem.MapPath);

            var poolConfig = new JsPoolConfig
            {
                EngineFactory             = _factory,
                Initializer               = InitialiseEngine,
                WatchPath                 = _fileSystem.MapPath("~/"),
                WatchFiles                = allFiles,
                GetEngineTimeout          = TimeSpan.FromSeconds(10.0),
                MaxUsagesPerEngine        = 0,
                StartEngines              = 10,
                MaxEngines                = 10,
                GarbageCollectionInterval = 60
            };

            var pool = new AfishaJsPool(poolConfig);

            // Reset the recycle exception on recycle. If there *are* errors loading the scripts
            // during recycle, the errors will be caught in the initializer.
            pool.Recycled += (sender, args) => _scriptLoadException = null;
            return(pool);
        }
Esempio n. 8
0
        public void DisposeDisposesAllEngines()
        {
            var engines = new[]
            {
                new Mock <IJsEngine>(),
                new Mock <IJsEngine>(),
                new Mock <IJsEngine>(),
                new Mock <IJsEngine>(),
            };
            var factory = new Mock <IEngineFactoryForMock>();

            factory.SetupSequence(x => x.EngineFactory())
            .Returns(engines[0].Object)
            .Returns(engines[1].Object)
            .Returns(engines[2].Object)
            .Returns(engines[3].Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 3,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            pool.Dispose();

            foreach (var engine in engines)
            {
                engine.Verify(x => x.Dispose());
            }
        }
Esempio n. 9
0
		public void GetEngineReturnsAllAvailableEngines()
		{
			var engines = new[]
			{
				new Mock<IJsEngine>().Object,
				new Mock<IJsEngine>().Object,
				new Mock<IJsEngine>().Object,
			};
			var factory = new Mock<IEngineFactoryForMock>();
			factory.SetupSequence(x => x.EngineFactory())
				// Initial call to factory is to determine engine type, we don't care
				// about that here.
				.Returns(new Mock<IJsEngine>().Object)
				.Returns(engines[0])
				.Returns(engines[1])
				.Returns(engines[2]);
			var config = new JsPoolConfig
			{
				StartEngines = 3,
				EngineFactory = factory.Object.EngineFactory
			};

			var pool = new JsPool(config);
			var resultEngines = new[]
			{
				pool.GetEngine(),
				pool.GetEngine(),
				pool.GetEngine(),
			};

			CollectionAssert.AreEquivalent(engines, resultEngines);
		}
Esempio n. 10
0
        public AfishaJsPool(JsPoolConfig <IJsEngine> config) : base(config)
        {
#if DEBUG
            new Thread(
                () =>
            {
                while (!_cancellationTokenSource.IsCancellationRequested)
                {
                    Debug.WriteLine($"AvailableEngines: {_availableEngines.Count}");
                    Debug.WriteLine($"EnginesToGC: {_enginesToGc.Count}");
                    Thread.Sleep(1000);
                }
            }).Start();
#endif

            new Thread(
                () =>
            {
                while (!_cancellationTokenSource.IsCancellationRequested)
                {
                    WaitHandle.WaitAny(new WaitHandle[] { _enginePopulateEvent }, TimeSpan.FromSeconds(5));

                    while (EngineCount < _config.MaxEngines)
                    {
                        var engine = CreateEngine();
                        _availableEngines.Add(engine);
                    }
                }
            }).Start();

            new Thread(
                () =>
            {
                while (!_cancellationTokenSource.IsCancellationRequested)
                {
                    _engineEnqueuedEvent.WaitOne();

                    while (!_cancellationTokenSource.IsCancellationRequested && _enginesToGc.TryDequeue(out var engine))
                    {
                        if (!_metadata.TryGetValue(engine, out _))
                        {
                            // This engine was from another pool. This could happen if a pool is recycled
                            // and replaced with a different one (like what ReactJS.NET does when any
                            // loaded files change). Let's just pretend we never saw it.
                            engine.Dispose();

                            continue;
                        }

                        engine.CollectGarbage();
                        _availableEngines.Add(engine);
                        _engineGcTime[engine] = DateTime.UtcNow;
                    }
                }
            }).Start();
        }
Esempio n. 11
0
        public JsPool GetEnginePool()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 100,
                EngineFactory = factory.Object.EngineFactory,
            };

            return(new JsPool(config));
        }
Esempio n. 12
0
        public void ConstructorCreatesEngines()
        {
            var factory = new Mock<IEngineFactoryForMock>();
            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock<IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines = 5,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);
            Assert.AreEqual(5, pool.AvailableEngineCount);
            // 6 times because one is at the very beginning to check the engine type
            factory.Verify(x => x.EngineFactory(), Times.Exactly(6));
        }
Esempio n. 13
0
        public void WatchPathWithoutWatchFilesDoesNotThrow()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 2,
                EngineFactory = factory.Object.EngineFactory,
                WatchPath     = Directory.GetCurrentDirectory(),
            };

            // Should not throw
            // ReSharper disable once UnusedVariable
            var pool = new JsPool(config);
        }
        /// <summary>
        /// Create a new js Pool
        /// </summary>
        /// <returns></returns>
        private JsPool CreatePool()
        {
            var config = new JsPoolConfig
            {
                EngineFactory = _factory,
                Initializer   = LoadScripts
            };

            var pool = new JsPool(config);

            // Reset the recycle exception on recycle. If there *are* errors loading the scripts
            // during recycle, the errors will be caught in the initializer.
            pool.Recycled += null;

            return(pool);
        }
Esempio n. 15
0
        public void ConstructorCreatesEngines()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 5,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            Assert.Equal(5, pool.AvailableEngineCount);
            factory.Verify(x => x.EngineFactory(), Times.Exactly(5));
        }
Esempio n. 16
0
        public void ConstructorCreatesEngines()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 5,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            Assert.AreEqual(5, pool.AvailableEngineCount);
            // 6 times because one is at the very beginning to check the engine type
            factory.Verify(x => x.EngineFactory(), Times.Exactly(6));
        }
Esempio n. 17
0
        public void ReturnEngineDisposesIfAtMaxUsages()
        {
            var mockEngine1 = new Mock <IJsEngine>();
            var mockEngine2 = new Mock <IJsEngine>();
            var factory     = new Mock <IEngineFactoryForMock>();

            factory.SetupSequence(x => x.EngineFactory())
            .Returns(mockEngine1.Object)
            .Returns(mockEngine2.Object);
            var config = new JsPoolConfig
            {
                StartEngines       = 1,
                MaxUsagesPerEngine = 3,
                EngineFactory      = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            // First two usages should not recycle it
            using (var engine = pool.GetEngine())
            {
                Assert.Equal(mockEngine1.Object, engine.InnerEngine);
            }
            mockEngine1.Verify(x => x.Dispose(), Times.Never);

            using (var engine = pool.GetEngine())
            {
                Assert.Equal(mockEngine1.Object, engine.InnerEngine);
            }
            mockEngine1.Verify(x => x.Dispose(), Times.Never);

            // Third usage should recycle it, since the max usages is 3
            using (var engine = pool.GetEngine())
            {
                Assert.Equal(mockEngine1.Object, engine.InnerEngine);
            }
            mockEngine1.Verify(x => x.Dispose());

            // Next usage should get a new engine
            using (var engine = pool.GetEngine())
            {
                Assert.Equal(mockEngine2.Object, engine.InnerEngine);
            }
        }
        public JsEngineManager(IJsEngineManagerConfiguration config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            this._modules = ResolvePaths(config.Modules ?? new List <string>()).ToList();

            // replace with custom object & mapping
            this._poolConfig = new JsPoolConfig
            {
                EngineFactory = new ChakraCoreJsEngineFactory().CreateEngine,
                Initializer   = this.Initializer()
            };

            if (this._modules.Count > 0)
            {
                // Get common root path for all files and configure watching.
                this._poolConfig.WatchPath  = this.GetCommonRoot(this._modules);
                this._poolConfig.WatchFiles = this._modules;
            }

            if (config.StartEngines.HasValue)
            {
                this._poolConfig.StartEngines = config.StartEngines.Value;
            }

            if (config.MaxEngines.HasValue)
            {
                this._poolConfig.MaxEngines = config.MaxEngines.Value;
            }

            if (config.MaxUsagesPerEngine.HasValue)
            {
                this._poolConfig.MaxUsagesPerEngine = config.MaxUsagesPerEngine.Value;
            }

            this._pool = new JsPool(this._poolConfig);

            // Clean combined scripts on any script file change
            this._pool.Recycled += (sender, args) => { this._scripts = null; };
        }
        /// <summary>
        /// Creates a new JavaScript engine pool.
        /// </summary>
        protected virtual IJsPool CreatePool()
        {
            var poolConfig = new JsPoolConfig
            {
                EngineFactory = _factory,
                Initializer   = InitialiseEngine,
            };

            if (_config.MaxEngines != null)
            {
                poolConfig.MaxEngines = _config.MaxEngines.Value;
            }
            if (_config.StartEngines != null)
            {
                poolConfig.StartEngines = _config.StartEngines.Value;
            }

            return(new JsPool(poolConfig));
        }
Esempio n. 20
0
        public void ConcurrentGetAndReleaseEnginesIsSafe()
        {
            const int ConcurrentThreadCount = 100;
            var       config = new JsPoolConfig
            {
                StartEngines  = 0,
                MaxEngines    = ConcurrentThreadCount,
                EngineFactory = () => new Mock <IJsEngine>().Object
            };

            var         pool             = new JsPool(config);
            ThreadStart getReleaseEngine = () =>
            {
                for (var i = 0; i < 10000; ++i)
                {
                    IJsEngine engine = pool.GetEngine();
                    pool.ReturnEngineToPool(engine);
                }
            };


            IList <Thread> threads = new List <Thread>();

            for (var i = 0; i < ConcurrentThreadCount; ++i)
            {
                threads.Add(new Thread(getReleaseEngine));
            }

            foreach (var thread in threads)
            {
                thread.Start();
            }

            threads[0].Join();
            for (var i = 1; i < threads.Count; ++i)
            {
                Thread thread = threads[i];
                thread.Join();
            }

            Assert.AreEqual(0, pool.EngineCount);
        }
Esempio n. 21
0
        public void ReturnEngineToPoolAddsToAvailableEngines()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 2,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            Assert.AreEqual(2, pool.AvailableEngineCount);
            var engine = pool.GetEngine();

            Assert.AreEqual(1, pool.AvailableEngineCount);
            pool.ReturnEngineToPool(engine);
            Assert.AreEqual(2, pool.AvailableEngineCount);
        }
Esempio n. 22
0
        public void ShouldIgnoreReturnToPoolIfUnknownEngine()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 1,
                EngineFactory = factory.Object.EngineFactory
            };
            var rogueEngine = new Mock <IJsEngine>();

            var pool = new JsPool(config);

            pool.ReturnEngineToPool(rogueEngine.Object);

            Assert.AreEqual(1, pool.AvailableEngineCount);
            Assert.AreEqual(1, pool.EngineCount);
            rogueEngine.Verify(x => x.Dispose());
        }
Esempio n. 23
0
        public void ReturnEngineDisposesIfAtMaxUsages()
        {
            var mockEngine1 = new Mock <IJsEngine>();
            var mockEngine2 = new Mock <IJsEngine>();
            var factory     = new Mock <IEngineFactoryForMock>();

            factory.SetupSequence(x => x.EngineFactory())
            // First engine is a dummy engine to check functionality
            .Returns(new Mock <IJsEngine>().Object)
            .Returns(mockEngine1.Object)
            .Returns(mockEngine2.Object);
            var config = new JsPoolConfig
            {
                StartEngines       = 1,
                MaxUsagesPerEngine = 3,
                EngineFactory      = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            // First two usages should not recycle it
            var engine = pool.GetEngine();

            Assert.AreEqual(mockEngine1.Object, engine);
            pool.ReturnEngineToPool(engine);
            mockEngine1.Verify(x => x.Dispose(), Times.Never);

            engine = pool.GetEngine();
            Assert.AreEqual(mockEngine1.Object, engine);
            pool.ReturnEngineToPool(engine);
            mockEngine1.Verify(x => x.Dispose(), Times.Never);

            // Third usage should recycle it, since the max usages is 3
            engine = pool.GetEngine();
            pool.ReturnEngineToPool(engine);
            mockEngine1.Verify(x => x.Dispose());

            // Next usage should get a new engine
            engine = pool.GetEngine();
            Assert.AreEqual(mockEngine2.Object, engine);
        }
Esempio n. 24
0
        public void GetEngineFailsIfAtMaximum()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 1,
                MaxEngines    = 1,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            factory.Verify(x => x.EngineFactory(), Times.Exactly(2));
            pool.GetEngine();             // First engine created on init

            Assert.Throws <JsPoolExhaustedException>(() =>
                                                     pool.GetEngine(TimeSpan.Zero)
                                                     );
        }
Esempio n. 25
0
        public void ConcurrentGetAndReleaseEnginesIsSafe()
        {
            const int ConcurrentThreadCount = 100;
            var config = new JsPoolConfig
            {
                StartEngines = 0,
                MaxEngines = ConcurrentThreadCount,
                EngineFactory = () => new Mock<IJsEngine>().Object
            };

            var pool = new JsPool(config);
            ThreadStart getReleaseEngine = () =>
            {
                for (var i = 0; i < 10000; ++i)
                {
                    IJsEngine engine = pool.GetEngine();
                    pool.ReturnEngineToPool(engine);
                }
            };

            IList<Thread> threads = new List<Thread>();
            for (var i = 0; i < ConcurrentThreadCount; ++i)
            {
                threads.Add(new Thread(getReleaseEngine));
            }

            foreach (var thread in threads)
            {
                thread.Start();
            }

            threads[0].Join(10000);
            for (var i = 1; i < threads.Count; ++i)
            {
                Thread thread = threads[i];
                thread.Join(100);
            }

            Assert.AreEqual(0, pool.EngineCount);
        }
Esempio n. 26
0
        public void RecycleCreatesNewEngines()
        {
            var factory = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 2,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            Assert.Equal(2, pool.AvailableEngineCount);
            factory.Verify(x => x.EngineFactory(), Times.Exactly(2));

            // Now recycle the pool
            pool.Recycle();
            Assert.Equal(2, pool.AvailableEngineCount);
            // Two more engines should have been created
            factory.Verify(x => x.EngineFactory(), Times.Exactly(4));
        }
Esempio n. 27
0
        public void RecycleFiresRecycledEvent()
        {
            var callCount = 0;
            var factory   = new Mock <IEngineFactoryForMock>();

            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock <IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines  = 2,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            pool.Recycled += (sender, args) => callCount++;
            Assert.AreEqual(0, callCount);

            pool.Recycle();
            Assert.AreEqual(1, callCount);

            pool.Recycle();
            Assert.AreEqual(2, callCount);
        }
Esempio n. 28
0
		public void GetEngineCreatesNewEngineIfNotAtMaximum()
		{
			var factory = new Mock<IEngineFactoryForMock>();
			factory.Setup(x => x.EngineFactory()).Returns(new Mock<IJsEngine>().Object);
			var config = new JsPoolConfig
			{
				StartEngines = 1,
				MaxEngines = 2,
				EngineFactory = factory.Object.EngineFactory
			};

			var pool = new JsPool(config);
			factory.Verify(x => x.EngineFactory(), Times.Exactly(2));
			pool.GetEngine(); // First engine created on init
			factory.Verify(x => x.EngineFactory(), Times.Exactly(2));
			Assert.AreEqual(1, pool.EngineCount);
			Assert.AreEqual(0, pool.AvailableEngineCount);

			pool.GetEngine(); // Second engine created JIT
			factory.Verify(x => x.EngineFactory(), Times.Exactly(3));
			Assert.AreEqual(2, pool.EngineCount);
			Assert.AreEqual(0, pool.AvailableEngineCount);
		}
Esempio n. 29
0
 public void WatchPathWithoutWatchFilesDoesNotThrow()
 {
     var factory = new Mock<IEngineFactoryForMock>();
     factory.Setup(x => x.EngineFactory()).Returns(() => new Mock<IJsEngine>().Object);
     var config = new JsPoolConfig
     {
         StartEngines = 2,
         EngineFactory = factory.Object.EngineFactory,
         WatchPath = Directory.GetCurrentDirectory(),
     };
     Assert.DoesNotThrow(() =>
     {
         // ReSharper disable once UnusedVariable
         var pool = new JsPool(config);
     });
 }
Esempio n. 30
0
        public void ReturnEngineToPoolAddsToAvailableEngines()
        {
            var factory = new Mock<IEngineFactoryForMock>();
            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock<IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines = 2,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);
            Assert.AreEqual(2, pool.AvailableEngineCount);
            var engine = pool.GetEngine();
            Assert.AreEqual(1, pool.AvailableEngineCount);
            pool.ReturnEngineToPool(engine);
            Assert.AreEqual(2, pool.AvailableEngineCount);
        }
Esempio n. 31
0
        public void ReturnEngineDisposesIfAtMaxUsages()
        {
            var mockEngine1 = new Mock<IJsEngine>();
            var mockEngine2 = new Mock<IJsEngine>();
            var factory = new Mock<IEngineFactoryForMock>();
            factory.SetupSequence(x => x.EngineFactory())
                // First engine is a dummy engine to check functionality
                .Returns(new Mock<IJsEngine>().Object)
                .Returns(mockEngine1.Object)
                .Returns(mockEngine2.Object);
            var config = new JsPoolConfig
            {
                StartEngines = 1,
                MaxUsagesPerEngine = 3,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);

            // First two usages should not recycle it
            var engine = pool.GetEngine();
            Assert.AreEqual(mockEngine1.Object, engine);
            pool.ReturnEngineToPool(engine);
            mockEngine1.Verify(x => x.Dispose(), Times.Never);

            engine = pool.GetEngine();
            Assert.AreEqual(mockEngine1.Object, engine);
            pool.ReturnEngineToPool(engine);
            mockEngine1.Verify(x => x.Dispose(), Times.Never);

            // Third usage should recycle it, since the max usages is 3
            engine = pool.GetEngine();
            pool.ReturnEngineToPool(engine);
            mockEngine1.Verify(x => x.Dispose());

            // Next usage should get a new engine
            engine = pool.GetEngine();
            Assert.AreEqual(mockEngine2.Object, engine);
        }
Esempio n. 32
0
        public void RecycleFiresRecycledEvent()
        {
            var callCount = 0;
            var factory = new Mock<IEngineFactoryForMock>();
            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock<IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines = 2,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);
            pool.Recycled += (sender, args) => callCount++;
            Assert.AreEqual(0, callCount);

            pool.Recycle();
            Assert.AreEqual(1, callCount);

            pool.Recycle();
            Assert.AreEqual(2, callCount);
        }
Esempio n. 33
0
        public void GetEngineFailsIfAtMaximum()
        {
            var factory = new Mock<IEngineFactoryForMock>();
            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock<IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines = 1,
                MaxEngines = 1,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);
            factory.Verify(x => x.EngineFactory(), Times.Exactly(2));
            pool.GetEngine(); // First engine created on init

            Assert.Throws<JsPoolExhaustedException>(() =>
                pool.GetEngine(TimeSpan.Zero)
            );
        }
Esempio n. 34
0
        public void RecycleCreatesNewEngines()
        {
            var factory = new Mock<IEngineFactoryForMock>();
            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock<IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines = 2,
                EngineFactory = factory.Object.EngineFactory
            };

            var pool = new JsPool(config);
            Assert.AreEqual(2, pool.AvailableEngineCount);
            // 3 times because one is at the very beginning to check the engine type
            factory.Verify(x => x.EngineFactory(), Times.Exactly(3));

            // Now recycle the pool
            pool.Recycle();
            Assert.AreEqual(2, pool.AvailableEngineCount);
            // Two more engines should have been created
            factory.Verify(x => x.EngineFactory(), Times.Exactly(5));
        }
Esempio n. 35
0
        public void ShouldIgnoreReturnToPoolIfUnknownEngine()
        {
            var factory = new Mock<IEngineFactoryForMock>();
            factory.Setup(x => x.EngineFactory()).Returns(() => new Mock<IJsEngine>().Object);
            var config = new JsPoolConfig
            {
                StartEngines = 1,
                EngineFactory = factory.Object.EngineFactory
            };
            var rogueEngine = new Mock<IJsEngine>();

            var pool = new JsPool(config);
            pool.ReturnEngineToPool(rogueEngine.Object);

            Assert.AreEqual(1, pool.AvailableEngineCount);
            Assert.AreEqual(1, pool.EngineCount);
            rogueEngine.Verify(x => x.Dispose());
        }