public void AnotherObtainingOfSameObject_CreationTimestampIsNotModified()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSameObjectPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            _pool.TryObtain(_key, out _outPoolObject, null);
            var previous = _pool.ObjectToLifetimeData[_outPoolObject].CreationTimeStamp;

            Thread.Sleep(5);
            _pool.TryObtain(_key, out _outPoolObject, null);

            var current = _pool.ObjectToLifetimeData[_outPoolObject].CreationTimeStamp;
            Assert.That(previous, Is.EqualTo(current).Within(_timeToleranceInMills).Milliseconds);
        }
        public void ReleaseWasCalled_LastUsageTimestampIsUpdated()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var resource = AddObject("asd");
            var previous = _pool.ObjectToLifetimeData[resource].LastUsageTimeStamp;

            Thread.Sleep(5);
            _pool.Release(_key, resource);

            var current = _pool.ObjectToLifetimeData[resource].LastUsageTimeStamp;
            Assert.That(current - previous >= TimeSpan.FromMilliseconds(5));
            Assert.That(previous, Is.EqualTo(current).Within(_timeToleranceInMills).Milliseconds);
        }
        public void ReleaseWasCalled_CreationTimestampIsNotModified()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var resource = AddObject("asd");
            var previous = _pool.ObjectToLifetimeData[resource].CreationTimeStamp;

            Thread.Sleep(5);
            _pool.Release(_key, resource);

            var current = _pool.ObjectToLifetimeData[resource].CreationTimeStamp;
            Assert.That(current, Is.EqualTo(previous));
        }
        public void OnlyRevivalTimespanIsSpecified_TimestampsAreNotRememberedOnRelease()
        {
            _settings.MaxObjectIdleTimeSpanInSeconds = null;
            _settings.MaxObjectLifetimeInSeconds = null;
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var unknownResource = new TestResource("asd");

            _pool.Release(_key, unknownResource);

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(0));
        }
        public void BasePoolReturnedFalse_PoolIsNotBrokenAndJustReturnsFalse()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseNoObjectPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);

            var getStatus = _pool.TryObtain(_key, out _outPoolObject, null);

            Assert.That(getStatus, Is.False);
            Assert.That(_outPoolObject, Is.Null);
        }
        public void AnotherObtainingOfSameObject_RememberedObjectKeyIsPreserved()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSameObjectPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            _pool.TryObtain(_key, out _outPoolObject, null);
            var previous = _pool.ObjectToLifetimeData[_outPoolObject].Key;

            _pool.TryObtain(_key, out _outPoolObject, null);

            var current = _pool.ObjectToLifetimeData[_outPoolObject].Key;
            Assert.That(previous, Is.EqualTo(current));
        }
        public void UtilizerRaisedObjectIsGoneEvent_RelatedLifetimeDataIsRemoved()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            _pool.ObjectToLifetimeData[_goneObjectArgs.PoolObject] = new ObjectLifetimeData<TestKey>(_key);

            _objectUtilizerMock.Raise(x => x.ObjectIsGone += null, _goneObjectArgs);

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(0));
        }
        public void ReleasingOfUnknownObject_NotThrowsAndAddsTimestampData()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var unknownResource = new TestResource("asd");

            Assert.DoesNotThrow(() => _pool.Release(_key, unknownResource));

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(1));
            var lifetimeData = _pool.ObjectToLifetimeData[unknownResource];
            Assert.That(lifetimeData.CreationTimeStamp, Is.EqualTo(DateTime.Now).Within(_timeToleranceInMills).Milliseconds);
            Assert.That(lifetimeData.LastUsageTimeStamp, Is.EqualTo(DateTime.Now).Within(_timeToleranceInMills).Milliseconds);
        }
        public void CleaningIsCalledPeriodically()
        {
            _settings.TimeSpanBetweenRevivalsInSeconds = 1;
            _settings.MaxObjectLifetimeInSeconds = 1;
            _settings.MaxObjectIdleTimeSpanInSeconds = null;
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);

            _pool.ObjectToLifetimeData[new TestResource("too old")] = new ObjectLifetimeData<TestKey>(_key)
            {
                CreationTimeStamp = DateTime.Now - TimeSpan.FromSeconds(10),
            };
            _pool.ObjectToLifetimeData[new TestResource("becoming old")] = new ObjectLifetimeData<TestKey>(_key)
            {
                CreationTimeStamp = DateTime.Now + TimeSpan.FromSeconds(1),
            };
            _pool.ObjectToLifetimeData[new TestResource("forever young")] = new ObjectLifetimeData<TestKey>(_key)
            {
                CreationTimeStamp = DateTime.Now + TimeSpan.FromHours(1),
            };

            Thread.Sleep(TimeSpan.FromSeconds(3));

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(1));
            _objectUtilizerMock.Verify(x => x.Utilize(_key, It.IsAny<TestResource>(), _pool), Times.Exactly(2));
        }
        public void CleaningExecuted_UsefulObjectsArePinged()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var usefulResource = AddObject("useful");

            _pool.DropLifelessObjectsAndWakeupOthers();

            _successfulObjectActionsMock.Verify(x => x.Ping(usefulResource));
        }
        public void CleaningExecutedAndTimespansAreNotSpecified_InvalidObjectsAreUtilizedAndForgotten()
        {
            _settings.MaxObjectIdleTimeSpanInSeconds = null;
            _settings.MaxObjectLifetimeInSeconds = null;
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var invalidResource = AddObject(Mocks.ObjectActions.SubstringOfInvalidObject);

            _pool.DropLifelessObjectsAndWakeupOthers();

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(0));
            _objectUtilizerMock.Verify(x => x.Utilize(_key, invalidResource, _pool), Times.Once);
        }
        public void CleaningExecutedAndPingFailed_ObjectIsUtilizedAndForgottenAndCleaningProceeds()
        {
            _settings.TimeSpanBetweenRevivalsInSeconds = 100;
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseThrowingPoolMock.Object, _failingOnPingObjectActionsMock.Object, _objectUtilizerMock.Object);
            var object1 = AddObject("something1");
            var object2 = AddObject("something2");

            _pool.DropLifelessObjectsAndWakeupOthers();

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(0));
            _objectUtilizerMock.Verify(x => x.Utilize(_key,object1,_pool));
            _objectUtilizerMock.Verify(x => x.Utilize(_key,object2,_pool));
        }
        public void BasePoolThrewOnRelease_ItIsRethrownAsIs()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseThrowingPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);

            _outPoolObject = new TestResource(string.Empty);
            Assert.Throws<InvalidPoolOperationException<TestKey, TestResource>>(
                () => _pool.Release(_key, _outPoolObject));
        }
        public void BasePoolThrewOnObtain_ItIsRethrownAsIs()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseThrowingPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);

            Assert.Throws<ObjectCreationFailedException<TestKey,TestResource>>(
                () => _pool.TryObtain(_key, out _outPoolObject, null));
        }
        public void ReleaseWasCalled_RememberedKeyIsPreserved()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var resource = AddObject("asd");
            var previous = _pool.ObjectToLifetimeData[resource].Key;

            _pool.Release(_key, resource);

            var current = _pool.ObjectToLifetimeData[resource].Key;
            Assert.That(current, Is.EqualTo(previous));
        }
        public void ReleasingOfUnknownObject_BasePoolIsCalled()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var unknownResource = new TestResource("asd");

            _pool.Release(_key, unknownResource);

            _baseSuccessfulPoolMock.Verify(x => x.Release(_key,unknownResource), Times.Once);
        }
        public void MaxLifetimeIsSpecified_TooOldObjectsAreUtilizedAndForgotten()
        {
            _settings.MaxObjectLifetimeInSeconds = 5;
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            var tooOldResource = new TestResource("old");
            _pool.ObjectToLifetimeData[tooOldResource] = new ObjectLifetimeData<TestKey>(_key)
            {
                CreationTimeStamp = DateTime.Now - TimeSpan.FromSeconds(6),
            };

            _pool.DropLifelessObjectsAndWakeupOthers();

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(0));
            _objectUtilizerMock.Verify(x => x.Utilize(_key, tooOldResource, _pool), Times.Once);
        }
        public void UtilizerRaisedEventWithUnknownObject_PoolDoesNotThrow()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);

            Assert.DoesNotThrow(() => _objectUtilizerMock.Raise(x => x.ObjectIsGone += null, _goneObjectArgs));
        }
        public void ObtainWasCalled_BasePoolIsCalled()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            Func<TestKey, TestResource> createDelegate = key => new TestResource(string.Empty);

            _pool.TryObtain(_key, out _outPoolObject, createDelegate);

            _baseSuccessfulPoolMock.Verify(x => x.TryObtain(_key, out _outPoolObject, createDelegate), Times.Once);
        }
        public void ObtainWasCalled_ProvidedObjectIsReturned()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);

            var getStatus = _pool.TryObtain(_key, out _outPoolObject, null);

            Assert.That(getStatus, Is.True);
            Assert.That(_outPoolObject.Value, Is.EqualTo(_key.Identifier + " 1"));
        }
        public void OnlyMaxLifetimeIsSpecified_ValidYoungObjectsAreKept()
        {
            _settings.MaxObjectLifetimeInSeconds = 5;
            _settings.MaxObjectIdleTimeSpanInSeconds = null;
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);
            AddObject("young");

            _pool.DropLifelessObjectsAndWakeupOthers();

            Assert.That(_pool.ObjectToLifetimeData.Count, Is.EqualTo(1));
        }
        private PoolController<int, ThreadWorker> CreateThreadPoolControllerInstance()
        {
            var workerActions = new ObjectActionsBasedOnDelegateOrInterface<ThreadWorker>(new ExplicitlyDefinedObjectActions<ThreadWorker>());
            var objectUtilizer = new ObjectUtilizer<int, ThreadWorker>();

            var basicPoolSettings = new PoolItemsStorageSettings
            {
                AllowOnlyOneUserPerObject = true,
                BalancingStrategy = _settings.BalancingStrategy,
                MaxObjectsCountPerKey = _settings.MaxWorkersCount,
                ThrowIfCantCreateObjectBecauseOfReachedLimit = false,
            };
            var basicPool = new PoolItemsStorage<int, ThreadWorker>(basicPoolSettings, workerActions, objectUtilizer);

            var stateMonitoringSettings = new PWObjectStateMonitoringSettings
            {
                MaxObjectIdleTimeSpanInSeconds = _settings.MaxObjectIdleTimeSpanInSeconds,
                MaxObjectLifetimeInSeconds = _settings.MaxObjectIdleTimeSpanInSeconds,
                TimeSpanBetweenRevivalsInSeconds = _settings.MonitorTimeSpanInSeconds,
            };
            var stateMonitoringPool = new PWObjectStateMonitoringWrapper<int, ThreadWorker>(stateMonitoringSettings,
                                                                                            basicPool,
                                                                                            workerActions,
                                                                                            objectUtilizer);

            var singleUsePool = new PWSingleUseEnforcingWrapper<int, ThreadWorker>(stateMonitoringPool);

            var autoReleasingPool = new PWAutoReleasingWrapper<int, ThreadWorker>(singleUsePool);

            var poolControllerSettings = new PoolControllerSettings
            {
                CallingReleaseOperationWillHappen = true,
            };
            var controller = new PoolController<int, ThreadWorker>(poolControllerSettings, autoReleasingPool);
            autoReleasingPool.SetPoolController(controller);
            return controller;
        }
        public void BasePoolProvidesObject_ObjectLifetimeDataAppears()
        {
            _pool = new PWObjectStateMonitoringWrapper<TestKey, TestResource>(_settings, _baseSuccessfulPoolMock.Object, _successfulObjectActionsMock.Object, _objectUtilizerMock.Object);

            _pool.TryObtain(_key, out _outPoolObject, null);

            var lifetimeData = _pool.ObjectToLifetimeData[_outPoolObject];
            Assert.That(lifetimeData.Key, Is.EqualTo(_key));
            Assert.That(lifetimeData.CreationTimeStamp, Is.EqualTo(DateTime.Now).Within(_timeToleranceInMills).Milliseconds);
            Assert.That(lifetimeData.LastUsageTimeStamp, Is.EqualTo(DateTime.Now).Within(_timeToleranceInMills).Milliseconds);
        }