public void SkipEvaluationForFirstNodeSingleNeighborTest(bool skip)
        {
            var engine = new SearchEngine()
            {
                SkipEvaluationForFirstNodeSingleNeighbor = skip
            };
            var tree = new UnaryDeterministicTree();

            tree.State2.SetEvaluationTo(2);
            tree.EndState.SetEvaluationTo(3);

            var result = engine.Search(tree.RootState, 10);

            if (skip)
            {
                Assert.AreEqual(2, result.Evaluation);
                Assert.AreEqual(1, result.StateSequence.Count);
                A.CallTo(() => tree.State2.GetNeighbors()).MustNotHaveHappened();
            }
            else
            {
                Assert.AreEqual(3, result.Evaluation);
                Assert.AreEqual(3, result.StateSequence.Count);
            }
        }
        public void Search_IsSearchCompletedTrue(int degreeOfParallelism, ParallelismMode parallelismMode)
        {
            var tree = new UnaryDeterministicTree();

            var engine = TestUtils.GetBasicSearchEngine(parallelismMode, degreeOfParallelism);
            var result = engine.Search(tree.State3, 5);

            Assert.IsTrue(result.IsSearchCompleted, "Search should have been completed");
        }
        public void FillCache_CacheModeNotSetToResueCache_ThrowsException(CacheMode cacheMode)
        {
            var tree   = new UnaryDeterministicTree();
            var engine = new SearchEngine(cacheMode, CacheKeyType.StateOnly)
            {
                SkipEvaluationForFirstNodeSingleNeighbor = false
            };

            engine.FillCache(tree.RootState, CancellationToken.None);
        }
        public void Search_CacheKeyStateAndDepth_EngineDoesntUseCachedStatesWithDiffrentDepth()
        {
            var tree   = new UnaryDeterministicTree();
            var engine = new SearchEngine(CacheMode.ReuseCache, CacheKeyType.StateAndDepth)
            {
                SkipEvaluationForFirstNodeSingleNeighbor = false
            };

            engine.Search(tree.State2, 10);
            var result = engine.Search(tree.RootState, 10);

            Assert.AreEqual(3, result.StateSequence.Count);  // The tree shouldn't end at state2 - since it's cached with depth 1, and in the second search it will have depth 2
            Assert.AreEqual(tree.EndState, result.StateSequence.Last());
        }
        public void Search_EngineRemebersCachedStates(CacheKeyType cacheKeyType)
        {
            var tree   = new UnaryDeterministicTree();
            var engine = new SearchEngine(CacheMode.ReuseCache, cacheKeyType)
            {
                SkipEvaluationForFirstNodeSingleNeighbor = false
            };

            engine.Search(tree.RootState, 10); // This should put all the states in the cache
            var result = engine.Search(tree.RootState, 10);

            Assert.AreEqual(1, result.StateSequence.Count);
            Assert.IsTrue(result.FullTreeSearchedOrPruned);
        }
        public void ClearCache_CacheCleared()
        {
            var tree   = new UnaryDeterministicTree();
            var engine = new SearchEngine(CacheMode.ReuseCache, CacheKeyType.StateOnly)
            {
                SkipEvaluationForFirstNodeSingleNeighbor = false
            };

            engine.Search(tree.RootState, 10); // This should put all the states in the cache
            engine.CacheManager.Clear();
            var result = engine.Search(tree.RootState, 10);

            Assert.AreNotEqual(result.StateSequence.Count, 1);
        }
        public void FillCache_EngineRemembersCachedStates()
        {
            var tree   = new UnaryDeterministicTree();
            var engine = new SearchEngine(CacheMode.ReuseCache, CacheKeyType.StateOnly)
            {
                SkipEvaluationForFirstNodeSingleNeighbor = false
            };

            engine.FillCache(tree.RootState, CancellationToken.None);
            var result = engine.Search(tree.RootState, 10);

            Assert.AreEqual(1, result.StateSequence.Count);
            Assert.IsTrue(result.FullTreeSearchedOrPruned);
        }
        public void Search_CacheKeyStateOnly_EngineRemebersCachedStates()
        {
            var tree   = new UnaryDeterministicTree();
            var engine = new SearchEngine(CacheMode.ReuseCache, CacheKeyType.StateOnly)
            {
                SkipEvaluationForFirstNodeSingleNeighbor = false
            };

            engine.Search(tree.State2, 10); // This should put state's 2 and 3 in the cache
            var result = engine.Search(tree.RootState, 10);

            Assert.AreEqual(1, result.StateSequence.Count); // The tree should end at state2 - which is cached
            Assert.AreEqual(tree.State2, result.StateSequence.Last());
            Assert.IsTrue(result.FullTreeSearchedOrPruned);
        }
        public void SetCustomCache_UseCustomCache(CacheMode cacheMode)
        {
            var tree        = new UnaryDeterministicTree();
            var customCache = A.Fake <ICacheManager>();

            A.CallTo(() => customCache.GetStateEvaluation(A <IState> ._, A <int> ._, A <IList <IState> > ._)).Returns(new EvaluationRange(1));

            var engine = new SearchEngine(cacheMode, () => customCache)
            {
                SkipEvaluationForFirstNodeSingleNeighbor = false
            };

            engine.Search(tree.RootState, 10);
            A.CallTo(() => tree.EndState.GetNeighbors()).MustNotHaveHappened();
        }
        public void Search_TaskCanceld_DontContinueSearching(int degreeOfParallelism, ParallelismMode parallelismMode)
        {
            var tree = new UnaryDeterministicTree();
            var cancellationSource = new CancellationTokenSource();

            A.CallTo(() => tree.RootState.GetNeighbors()).ReturnsLazily(() =>
            {
                cancellationSource.Cancel();
                return(new List <IDeterministicState> {
                    tree.State2
                });
            });

            tree.RootState.SetEvaluationTo(1);
            tree.State2.SetEvaluationTo(2);
            tree.EndState.SetEvaluationTo(2);

            var searchEngine = TestUtils.GetBasicSearchEngine(parallelismMode, degreeOfParallelism);
            var result       = searchEngine.Search(tree.RootState, 5, cancellationSource.Token);

            Assert.AreEqual(1, result.Evaluation);
            Assert.AreEqual(0, result.StateSequence.Count, "We shouldn't have gotten to past " + nameof(tree.RootState));
            Assert.IsFalse(result.IsSearchCompleted, "The search shouldn't have been completed");
        }