diff --git a/test/SlowTests/Data/RavenDB_23100/2024-11-18-18-07-42-3204449.ravendb-snapshot b/test/SlowTests/Data/RavenDB_23100/2024-11-18-18-07-42-3204449.ravendb-snapshot deleted file mode 100644 index fdfd5bc8b839..000000000000 Binary files a/test/SlowTests/Data/RavenDB_23100/2024-11-18-18-07-42-3204449.ravendb-snapshot and /dev/null differ diff --git a/test/SlowTests/Data/RavenDB_23100/2024-11-19-08-30-34-7519596.ravendb-snapshot b/test/SlowTests/Data/RavenDB_23100/2024-11-19-08-30-34-7519596.ravendb-snapshot new file mode 100644 index 000000000000..99306f9ef2d5 Binary files /dev/null and b/test/SlowTests/Data/RavenDB_23100/2024-11-19-08-30-34-7519596.ravendb-snapshot differ diff --git a/test/SlowTests/Data/RavenDB_23100/2024-11-19-10-39-25-6242058.ravendb-snapshot b/test/SlowTests/Data/RavenDB_23100/2024-11-19-10-39-25-6242058.ravendb-snapshot new file mode 100644 index 000000000000..069849c3c7c8 Binary files /dev/null and b/test/SlowTests/Data/RavenDB_23100/2024-11-19-10-39-25-6242058.ravendb-snapshot differ diff --git a/test/SlowTests/Data/RavenDB_23100/2024-11-19-10-43-34-8245899.ravendb-snapshot b/test/SlowTests/Data/RavenDB_23100/2024-11-19-10-43-34-8245899.ravendb-snapshot new file mode 100644 index 000000000000..9c9e9d2419d6 Binary files /dev/null and b/test/SlowTests/Data/RavenDB_23100/2024-11-19-10-43-34-8245899.ravendb-snapshot differ diff --git a/test/SlowTests/Issues/RavenDB-23100.cs b/test/SlowTests/Issues/RavenDB-23100.cs index bb705af29fc2..d4e5239fcb14 100644 --- a/test/SlowTests/Issues/RavenDB-23100.cs +++ b/test/SlowTests/Issues/RavenDB-23100.cs @@ -30,12 +30,14 @@ public RavenDB_23100(ITestOutputHelper output) : base(output) private static readonly Employee _employee1 = new Employee { Id = EmployeeId1, CompanyId = _company.Id }; private static readonly Employee _employee2 = new Employee { Id = EmployeeId2, CompanyId = _company.Id }; - [RavenFact(RavenTestCategory.Indexes)] - public async Task Can_Delete_Document_References() + [RavenTheory(RavenTestCategory.Indexes)] + [InlineData(typeof(DocumentsIndex))] + [InlineData(typeof(DocumentsIndexMapReduce))] + public async Task Can_Delete_Document_References(Type type) { using (var store = GetDocumentStore()) { - var index = new DocumentsIndex(); + var index = (AbstractIndexCreationTask)Activator.CreateInstance(type); await store.ExecuteIndexAsync(index); using (var session = store.OpenAsyncSession()) @@ -197,11 +199,109 @@ public async Task Can_Delete_Document_References_For_Legacy_Index() } [RavenFact(RavenTestCategory.Indexes)] - public async Task Can_Delete_CompareExchange_References() + public async Task Can_Delete_Document_References_Map_Reduce_For_Legacy_Index() + { + var backupPath = NewDataPath(forceCreateDir: true); + var fullBackupPath = Path.Combine(backupPath, "2024-11-19-08-30-34-7519596.ravendb-snapshot"); + + await using (var file = File.Create(fullBackupPath)) + { + await using (var stream = typeof(RavenDB_23100).Assembly.GetManifestResourceStream("SlowTests.Data.RavenDB_23100.2024-11-19-08-30-34-7519596.ravendb-snapshot")) + { + await stream.CopyToAsync(file); + } + } + + using (var store = GetDocumentStore(new Options + { + CreateDatabase = false + })) + { + using (Backup.RestoreDatabase(store, new RestoreBackupConfiguration + { + BackupLocation = backupPath, + DatabaseName = store.Database + })) + { + var database = await GetDatabase(store.Database); + var indexInstance = database.IndexStore.GetIndex(new DocumentsIndexMapReduce().IndexName); + + using (indexInstance._contextPool.AllocateOperationContext(out TransactionOperationContext context)) + using (var tx = context.OpenReadTransaction()) + { + var counts = indexInstance._indexStorage.ReferencesForDocuments.GetReferenceTablesCount("Employees", tx); + + Assert.Equal(2, counts.ReferenceTableCount); + Assert.Equal(1, counts.CollectionTableCount); + } + + using (var session = store.OpenAsyncSession()) + { + var company = await session.LoadAsync(CompanyId); + company.Name += " LTD"; + await session.SaveChangesAsync(); + } + + Indexes.WaitForIndexing(store); + + using (var session = store.OpenAsyncSession()) + { + var results = await session.Query() + .ProjectInto().ToListAsync(); + + Assert.Equal(1, results.Count); + Assert.Equal("RavenDB LTD", results[0].CompanyName); + } + + using (var session = store.OpenAsyncSession()) + { + session.Delete(EmployeeId1); + session.Delete(EmployeeId2); + await session.SaveChangesAsync(); + // deleting the documents won't change the internal references tree like in new indexes + } + + Indexes.WaitForIndexing(store); + + using (indexInstance._contextPool.AllocateOperationContext(out TransactionOperationContext context)) + using (var tx = context.OpenReadTransaction()) + { + var counts = indexInstance._indexStorage.ReferencesForDocuments.GetReferenceTablesCount("Employees", tx); + + Assert.Equal(2, counts.ReferenceTableCount); + Assert.Equal(1, counts.CollectionTableCount); + } + + using (var session = store.OpenAsyncSession()) + { + var company = await session.LoadAsync(CompanyId); + company.Name += " HR"; + await session.SaveChangesAsync(); + // when we update the references, this will clean the leftovers + } + + Indexes.WaitForIndexing(store); + + using (indexInstance._contextPool.AllocateOperationContext(out TransactionOperationContext context)) + using (var tx = context.OpenReadTransaction()) + { + var counts = indexInstance._indexStorage.ReferencesForDocuments.GetReferenceTablesCount("Employees", tx); + + Assert.Equal(0, counts.ReferenceTableCount); + Assert.Equal(0, counts.CollectionTableCount); + } + } + } + } + + [RavenTheory(RavenTestCategory.Indexes)] + [InlineData(typeof(CompareExchangeIndex))] + [InlineData(typeof(CompareExchangeMapReduceIndex))] + public async Task Can_Delete_CompareExchange_References(Type type) { using (var store = GetDocumentStore()) { - var index = new DocumentsWithCompareExchangeIndex(); + var index = (AbstractIndexCreationTask)Activator.CreateInstance(type); await store.ExecuteIndexAsync(index); @@ -273,11 +373,11 @@ public async Task Can_Delete_CompareExchange_References() public async Task Can_Delete_CompareExchange_References_For_Legacy_Index() { var backupPath = NewDataPath(forceCreateDir: true); - var fullBackupPath = Path.Combine(backupPath, "2024-11-18-18-07-42-3204449.ravendb-snapshot"); + var fullBackupPath = Path.Combine(backupPath, "2024-11-19-10-43-34-8245899.ravendb-snapshot"); await using (var file = File.Create(fullBackupPath)) { - await using (var stream = typeof(RavenDB_23100).Assembly.GetManifestResourceStream("SlowTests.Data.RavenDB_23100.2024-11-18-18-07-42-3204449.ravendb-snapshot")) + await using (var stream = typeof(RavenDB_23100).Assembly.GetManifestResourceStream("SlowTests.Data.RavenDB_23100.2024-11-19-10-43-34-8245899.ravendb-snapshot")) { await stream.CopyToAsync(file); } @@ -295,7 +395,7 @@ public async Task Can_Delete_CompareExchange_References_For_Legacy_Index() })) { var database = await GetDatabase(store.Database); - var indexInstance = database.IndexStore.GetIndex(new DocumentsWithCompareExchangeIndex().IndexName); + var indexInstance = database.IndexStore.GetIndex(new CompareExchangeIndex().IndexName); using (indexInstance._contextPool.AllocateOperationContext(out TransactionOperationContext context)) using (var tx = context.OpenReadTransaction()) @@ -317,8 +417,8 @@ public async Task Can_Delete_CompareExchange_References_For_Legacy_Index() using (var session = store.OpenAsyncSession()) { - var results = await session.Query() - .ProjectInto().ToListAsync(); + var results = await session.Query() + .ProjectInto().ToListAsync(); Assert.Equal(2, results.Count); @@ -369,6 +469,100 @@ public async Task Can_Delete_CompareExchange_References_For_Legacy_Index() } } + [RavenFact(RavenTestCategory.Indexes, Skip = "https://issues.hibernatingrhinos.com/issue/RavenDB-23166/Snapshot-restore-of-with-compare-exchange-references")] + public async Task Can_Delete_CompareExchange_References_For_Legacy_Index_Map_Reduce() + { + var backupPath = NewDataPath(forceCreateDir: true); + var fullBackupPath = Path.Combine(backupPath, "2024-11-19-10-39-25-6242058.ravendb-snapshot"); + + await using (var file = File.Create(fullBackupPath)) + { + await using (var stream = typeof(RavenDB_23100).Assembly.GetManifestResourceStream("SlowTests.Data.RavenDB_23100.2024-11-19-10-39-25-6242058.ravendb-snapshot")) + { + await stream.CopyToAsync(file); + } + } + + using (var store = GetDocumentStore(new Options + { + CreateDatabase = false + })) + { + using (Backup.RestoreDatabase(store, new RestoreBackupConfiguration + { + BackupLocation = backupPath, + DatabaseName = store.Database + })) + { + var database = await GetDatabase(store.Database); + var indexInstance = database.IndexStore.GetIndex(new CompareExchangeMapReduceIndex().IndexName); + + using (indexInstance._contextPool.AllocateOperationContext(out TransactionOperationContext context)) + using (var tx = context.OpenReadTransaction()) + { + var counts = indexInstance._indexStorage.ReferencesForCompareExchange.GetReferenceTablesCount("Employees", tx); + + Assert.Equal(2, counts.ReferenceTableCount); + Assert.Equal(1, counts.CollectionTableCount); + } + + using (var session = store.OpenAsyncSession(new SessionOptions { TransactionMode = TransactionMode.ClusterWide })) + { + var company = await session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync(CompanyId); + company.Value.Name += " LTD"; + await session.SaveChangesAsync(); + } + + Indexes.WaitForIndexing(store); + + using (var session = store.OpenAsyncSession()) + { + var results = await session.Query().ToListAsync(); + Assert.Equal(1, results.Count); + Assert.Equal("RavenDB LTD", results[0].CompanyName); + } + + using (var session = store.OpenAsyncSession()) + { + session.Delete(EmployeeId1); + session.Delete(EmployeeId2); + await session.SaveChangesAsync(); + // deleting the documents won't change the internal references tree like in new indexes + } + + Indexes.WaitForIndexing(store); + + using (indexInstance._contextPool.AllocateOperationContext(out TransactionOperationContext context)) + using (var tx = context.OpenReadTransaction()) + { + var counts = indexInstance._indexStorage.ReferencesForCompareExchange.GetReferenceTablesCount("Employees", tx); + + Assert.Equal(2, counts.ReferenceTableCount); + Assert.Equal(1, counts.CollectionTableCount); + } + + using (var session = store.OpenAsyncSession(new SessionOptions { TransactionMode = TransactionMode.ClusterWide })) + { + var company = await session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync(CompanyId); + company.Value.Name += " HR"; + await session.SaveChangesAsync(); + // when we update the references, this will clean the leftovers + } + + Indexes.WaitForIndexing(store); + + using (indexInstance._contextPool.AllocateOperationContext(out TransactionOperationContext context)) + using (var tx = context.OpenReadTransaction()) + { + var counts = indexInstance._indexStorage.ReferencesForCompareExchange.GetReferenceTablesCount("Employees", tx); + + Assert.Equal(0, counts.ReferenceTableCount); + Assert.Equal(0, counts.CollectionTableCount); + } + } + } + } + [RavenFact(RavenTestCategory.Indexes)] public async Task Can_Delete_Counters_References() { @@ -563,14 +757,41 @@ public DocumentsIndex() } } - private class DocumentsWithCompareExchangeIndex : AbstractIndexCreationTask + private class DocumentsIndexMapReduce : AbstractIndexCreationTask + { + public class Result + { + public string CompanyName { get; set; } + public int Count { get; set; } + } + + public DocumentsIndexMapReduce() + { + Map = employees => from employee in employees + select new Result + { + CompanyName = LoadDocument(employee.CompanyId).Name, + Count = 1 + }; + + Reduce = results => from result in results + group result by result.CompanyName into g + select new Result + { + CompanyName = g.Key, + Count = g.Sum(x => x.Count) + }; + } + } + + private class CompareExchangeIndex : AbstractIndexCreationTask { public class Result { public string CompanyName { get; set; } } - public DocumentsWithCompareExchangeIndex() + public CompareExchangeIndex() { Map = employees => from employee in employees @@ -583,6 +804,66 @@ from employee in employees } } + private class CompareExchangeMapReduceIndex : AbstractIndexCreationTask + { + public class Result + { + public string CompanyName { get; set; } + + public int Count { get; set; } + } + + public CompareExchangeMapReduceIndex() + { + Map = employees => + from employee in employees + select new Result + { + CompanyName = LoadCompareExchangeValue(employee.CompanyId).Name, + Count = 1 + }; + + Reduce = results => from result in results + group result by result.CompanyName into g + select new Result + { + CompanyName = g.Key, + Count = g.Sum(x => x.Count) + }; + + StoreAllFields(FieldStorage.Yes); + } + } + + private class DocumentsWithCompareExchangeIndexMapReduce : AbstractIndexCreationTask + { + public class Result + { + public string CompanyName { get; set; } + public int Count { get; set; } + } + + public DocumentsWithCompareExchangeIndexMapReduce() + { + Map = employees => + from employee in employees + select new Result + { + CompanyName = LoadCompareExchangeValue(employee.CompanyId).Name, + Count = 1 + }; + + Reduce = results => from result in results + group result by result.CompanyName into g + select new Result + { + CompanyName = g.Key, + Count = g.Sum(x => x.Count) + }; + + } + } + private class CountersIndex : AbstractCountersIndexCreationTask { public class Result diff --git a/test/SlowTests/SlowTests.csproj b/test/SlowTests/SlowTests.csproj index 325cc2ae85c8..0c95c61ce840 100644 --- a/test/SlowTests/SlowTests.csproj +++ b/test/SlowTests/SlowTests.csproj @@ -46,7 +46,9 @@ - + + + @@ -125,7 +127,9 @@ - + + +