Ejemplo n.º 1
0
        public void ShouldDeleteCommitPointIfCouldNotRecoverFromIt()
        {
            var    dataDir = NewDataPath("ShouldDeleteCommitPointIfCouldNotRecoverFromIt");
            string indexFullPath;
            string indexStoragePath;
            int    indexId;
            string commitPointsDirectory;
            var    index = new MapRecoveryTestIndex();

            using (var server = GetNewServer(runInMemory: false, dataDirectory: dataDir))
            {
                CommitPointAfterEachCommit(server.SystemDatabase.Configuration);

                using (var store = new DocumentStore {
                    Url = "http://localhost:8079"
                }.Initialize())
                {
                    index.Execute(store);

                    using (var session = store.OpenSession())
                    {
                        session.Store(new Recovery
                        {
                            Name   = "One",
                            Number = 1
                        });

                        session.SaveChanges();                         // first commit point
                        WaitForIndexing(store);

                        server.SystemDatabase.IndexStorage.FlushMapIndexes();
                        server.SystemDatabase.IndexStorage.FlushReduceIndexes();

                        session.Store(new Recovery
                        {
                            Name   = "Two",
                            Number = 2
                        });

                        session.SaveChanges();                         // second commit point
                        WaitForIndexing(store);

                        server.SystemDatabase.IndexStorage.FlushMapIndexes();
                        server.SystemDatabase.IndexStorage.FlushReduceIndexes();

                        session.Store(new Recovery
                        {
                            Name   = "Three",
                            Number = 3
                        });

                        session.SaveChanges();                         // second commit point
                        WaitForIndexing(store, timeout: TimeSpan.FromSeconds(60));

                        server.SystemDatabase.IndexStorage.FlushMapIndexes();
                        server.SystemDatabase.IndexStorage.FlushReduceIndexes();
                    }
                }
                Index indexInstance = server.SystemDatabase.IndexStorage.GetIndexInstance(index.IndexName);

                commitPointsDirectory = Path.Combine(server.SystemDatabase.Configuration.IndexStoragePath,
                                                     indexInstance.IndexId + "\\CommitPoints");

                indexFullPath = Path.Combine(server.SystemDatabase.Configuration.IndexStoragePath,
                                             indexInstance.IndexId.ToString(CultureInfo.InvariantCulture));

                indexStoragePath = server.SystemDatabase.Configuration.IndexStoragePath;

                indexId = indexInstance.IndexId;
            }

            // make sure that there are 3 commit points
            var directories = Directory.GetDirectories(commitPointsDirectory);

            Assert.Equal(3, directories.Length);

            // mess "index.CommitPoint" file in the SECOND and THIRD commit points by adding additional files required to recover from it

            for (int i = 1; i < 3; i++)
            {
                IndexCommitPoint commitPoint;
                Assert.True(IndexStorage.TryGetCommitPoint(new IndexCommitPointDirectory(indexStoragePath, indexId.ToString(CultureInfo.InvariantCulture), directories[i].Split(new[] { '\\' }).Last()), out commitPoint));

                commitPoint.SegmentsInfo.ReferencedFiles.Add("file-that-doesnt-exist");

                using (var commitPointFile = File.Open(Path.Combine(directories[i], "index.CommitPoint"), FileMode.Open))
                {
                    using (var sw = new StreamWriter(commitPointFile))
                    {
                        var textWriter = new JsonTextWriter(sw);

                        JsonExtensions.CreateDefaultJsonSerializer().Serialize(textWriter, commitPoint);
                        sw.Flush();
                    }
                }
            }

            IndexMessing.MessSegmentsFile(indexFullPath);

            using (GetNewServer(runInMemory: false, dataDirectory: dataDir))             // do not delete previous directory
            {
                using (var store = new DocumentStore {
                    Url = "http://localhost:8079"
                }.Initialize())
                {
                    using (var session = store.OpenSession())
                    {
                        var result =
                            session.Query <Recovery, MapRecoveryTestIndex>().Customize(x => x.WaitForNonStaleResults()).ToList();

                        Assert.Equal(3, result.Count);
                    }
                }
            }

            // there should be exactly 2 commit points:
            // the first one which we used to recover
            // and the second one created because of indexing after recovery
            Assert.Equal(2, Directory.GetDirectories(commitPointsDirectory).Length);
        }