public void CanUseCustomAnalyzer_Restart_Faulty() { var serverPath = NewDataPath(); var databasePath = NewDataPath(); IOExtensions.DeleteDirectory(serverPath); IOExtensions.DeleteDirectory(databasePath); var analyzerName = GetDatabaseName(); using (var server = GetNewServer(new ServerCreationOptions { DataDirectory = serverPath, RunInMemory = false })) using (var store = GetDocumentStore(new Options { ModifyDatabaseName = _ => analyzerName, Path = databasePath, RunInMemory = false, Server = server, DeleteDatabaseOnDispose = false })) { var e = Assert.Throws <IndexCompilationException>(() => store.ExecuteIndex(new MyIndex(analyzerName))); Assert.Contains($"Cannot find analyzer type '{analyzerName}' for field: Name", e.Message); var analyzerCode = GetAnalyzer("RavenDB_14939.MyAnalyzer.cs", "MyAnalyzer", analyzerName); store.Maintenance.Server.Send(new PutServerWideAnalyzersOperation(new AnalyzerDefinition { Name = analyzerName, Code = analyzerCode })); store.ExecuteIndex(new MyIndex(analyzerName)); Fill(store); Indexes.WaitForIndexing(store); AssertCount <MyIndex>(store); server.ServerStore.DatabasesLandlord.UnloadDirectly(store.Database); // skipping compilation on purpose using (server.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context)) using (var tx = context.OpenWriteTransaction()) { var command = new PutServerWideAnalyzerCommand( new AnalyzerDefinition { Name = analyzerName, Code = analyzerCode.Replace(analyzerName, "MyAnalyzer") }, RaftIdGenerator.NewId()); using (var json = context.ReadObject(command.ValueToJson(), command.Name)) { ClusterStateMachine.PutValueDirectly(context, command.Name, json, 1); } tx.Commit(); } } AnalyzerCompilationCache.Instance.RemoveServerWideItem(analyzerName); using (var server = GetNewServer(new ServerCreationOptions { DataDirectory = serverPath, RunInMemory = false, DeletePrevious = false })) using (var store = GetDocumentStore(new Options { ModifyDatabaseName = _ => analyzerName, Path = databasePath, RunInMemory = false, Server = server, CreateDatabase = false })) { store.Maintenance.Send(new ResetIndexOperation(new MyIndex(analyzerName).IndexName)); AssertErrors(store); // can override with database analyzer store.Maintenance.Send(new PutAnalyzersOperation(new AnalyzerDefinition { Name = analyzerName, Code = GetAnalyzer("RavenDB_14939.MyAnalyzer.cs", "MyAnalyzer", analyzerName) })); store.Maintenance.Send(new ResetIndexOperation(new MyIndex(analyzerName).IndexName)); Indexes.WaitForIndexing(store); AssertCount <MyIndex>(store); // can go back to server analyzer store.Maintenance.Send(new DeleteAnalyzerOperation(analyzerName)); store.Maintenance.Send(new ResetIndexOperation(new MyIndex(analyzerName).IndexName)); AssertErrors(store); // can fix server analyzer store.Maintenance.Server.Send(new PutServerWideAnalyzersOperation(new AnalyzerDefinition { Name = analyzerName, Code = GetAnalyzer("RavenDB_14939.MyAnalyzer.cs", "MyAnalyzer", analyzerName) })); store.Maintenance.Send(new ResetIndexOperation(new MyIndex(analyzerName).IndexName)); Indexes.WaitForIndexing(store); AssertCount <MyIndex>(store); } void AssertErrors(IDocumentStore store) { var errors = Indexes.WaitForIndexingErrors(store); Assert.Equal(1, errors.Length); Assert.Equal(1, errors[0].Errors.Length); Assert.Contains("is an implementation of a faulty analyzer", errors[0].Errors[0].Error); Assert.Contains("Could not find type", errors[0].Errors[0].Error); } }
public void CanUseCustomSorter_Restart_Faulty() { var serverPath = NewDataPath(); var databasePath = NewDataPath(); IOExtensions.DeleteDirectory(serverPath); IOExtensions.DeleteDirectory(databasePath); var sorterName = GetDatabaseName(); using (var server = GetNewServer(new ServerCreationOptions { DataDirectory = serverPath, RunInMemory = false })) using (var store = GetDocumentStore(new Options { ModifyDatabaseName = _ => sorterName, Path = databasePath, RunInMemory = false, Server = server, DeleteDatabaseOnDispose = false })) { using (var session = store.OpenSession()) { session.Store(new Company { Name = "C1" }); session.Store(new Company { Name = "C2" }); session.SaveChanges(); } CanUseSorterInternal <SorterDoesNotExistException>(store, $"There is no sorter with '{sorterName}' name", $"There is no sorter with '{sorterName}' name", sorterName); var sorterCode = GetSorter("RavenDB_8355.MySorter.cs", "MySorter", sorterName); store.Maintenance.Server.Send(new PutServerWideSortersOperation(new SorterDefinition { Name = sorterName, Code = sorterCode })); CanUseSorterInternal <RavenException>(store, "Catch me: Name:2:0:False", "Catch me: Name:2:0:True", sorterName); server.ServerStore.DatabasesLandlord.UnloadDirectly(store.Database); // skipping compilation on purpose using (server.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context)) using (var tx = context.OpenWriteTransaction()) { var command = new PutServerWideSorterCommand( new SorterDefinition { Name = sorterName, Code = sorterCode.Replace(sorterCode, "MySorter") }, RaftIdGenerator.NewId()); using (var json = context.ReadObject(command.ValueToJson(), command.Name)) { ClusterStateMachine.PutValueDirectly(context, command.Name, json, 1); } tx.Commit(); } } SorterCompilationCache.Instance.RemoveServerWideItem(sorterName); using (var server = GetNewServer(new ServerCreationOptions { DataDirectory = serverPath, RunInMemory = false, DeletePrevious = false })) using (var store = GetDocumentStore(new Options { ModifyDatabaseName = _ => sorterName, Path = databasePath, RunInMemory = false, Server = server, CreateDatabase = false })) { CanUseSorterInternal <RavenException>(store, "is an implementation of a faulty sorter", "is an implementation of a faulty sorter", sorterName); // can override with database sorter store.Maintenance.Send(new PutSortersOperation(new SorterDefinition { Name = sorterName, Code = GetSorter("RavenDB_8355.MySorter.cs", "MySorter", sorterName) })); CanUseSorterInternal <RavenException>(store, "Catch me: Name:2:0:False", "Catch me: Name:2:0:True", sorterName); // can go back to server analyzer store.Maintenance.Send(new DeleteSorterOperation(sorterName)); CanUseSorterInternal <RavenException>(store, "is an implementation of a faulty sorter", "is an implementation of a faulty sorter", sorterName); // can fix server sorter store.Maintenance.Server.Send(new PutServerWideSortersOperation(new SorterDefinition { Name = sorterName, Code = GetSorter("RavenDB_8355.MySorter.cs", "MySorter", sorterName) })); CanUseSorterInternal <RavenException>(store, "Catch me: Name:2:0:False", "Catch me: Name:2:0:True", sorterName); } }