From 9ff6e669201c68280d7f34f91eb2109fb1963847 Mon Sep 17 00:00:00 2001 From: Lev Skuditsky Date: Tue, 31 Dec 2024 11:47:45 +0200 Subject: [PATCH 1/4] RavenDB-23124: SlowTests.Issues.RavenDB_22659.CannotDeleteDatabaseWhenRestoreCancelledOnNonResponsibleNode (fix) --- src/Raven.Server/Web/System/AdminDatabasesHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Raven.Server/Web/System/AdminDatabasesHandler.cs b/src/Raven.Server/Web/System/AdminDatabasesHandler.cs index 06ae4825d96e..9572ff51b0e3 100644 --- a/src/Raven.Server/Web/System/AdminDatabasesHandler.cs +++ b/src/Raven.Server/Web/System/AdminDatabasesHandler.cs @@ -926,7 +926,7 @@ private void AssertCanDeleteDatabase(string databaseName, DatabaseStateStatus st if (state != DatabaseStateStatus.RestoreInProgress) return; - var restoredOnNode = topology.Members.First(); // we restore only on one node + var restoredOnNode = topology.AllNodes.First(); // we restore only on one node if (ServerStore.NodeTag != restoredOnNode) throw new InvalidOperationException($"Can't delete database '{databaseName}' while the restore " + $"process is in progress. In order to delete the database, " + From 92d97ec3b1aa60085e28aaaa582e5f57759e4fd0 Mon Sep 17 00:00:00 2001 From: Mateusz Bartosik Date: Sun, 22 Dec 2024 12:15:54 +0100 Subject: [PATCH 2/4] RavenDB-23433 Fix developer license color for Blue & Light theme --- src/Raven.Studio/wwwroot/Content/scss/_colors.scss | 7 ++++++- .../wwwroot/Content/scss/_custom-properties.scss | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Raven.Studio/wwwroot/Content/scss/_colors.scss b/src/Raven.Studio/wwwroot/Content/scss/_colors.scss index a7a3b0db437a..bcc054e784be 100644 --- a/src/Raven.Studio/wwwroot/Content/scss/_colors.scss +++ b/src/Raven.Studio/wwwroot/Content/scss/_colors.scss @@ -102,6 +102,8 @@ $token-keyword: $color-5; $token-deleted: $color-1; $token-important: $color-2-2; +$developer: #c7ff6b; + // Blue Theme @if $theme == "blue" { $black: #172138; @@ -173,6 +175,8 @@ $token-important: $color-2-2; $ace-character: $token-important; $ace-name: $token-keyword; $ace-constant: $token-operator; + + $developer: darken(#c7ff6b, 33%); } // Light Theme @@ -254,6 +258,8 @@ $token-important: $color-2-2; $row-bg: $white; $row-even-bg: $gray-100; + + $developer: darken(#c7ff6b, 33%); } // Classic Theme @@ -363,7 +369,6 @@ $progress-color: $color-2-3; $free: $color-4; $professional: $color-4-2; $enterprise: $color-5; -$developer: #c7ff6b; // Color system // scss-docs-end gray-color-variables diff --git a/src/Raven.Studio/wwwroot/Content/scss/_custom-properties.scss b/src/Raven.Studio/wwwroot/Content/scss/_custom-properties.scss index 84cee6748bb0..676cea669156 100644 --- a/src/Raven.Studio/wwwroot/Content/scss/_custom-properties.scss +++ b/src/Raven.Studio/wwwroot/Content/scss/_custom-properties.scss @@ -24,7 +24,7 @@ $prefix: "bs-"; --hover-filter: #{$hover-filter}; --shadow-color: #{to-rgb($shadow-color)}; - --license-developer: #c7ff6b; + --license-developer: #{$developer}; --license-cloud: #{$brand-cloud}; --license-community: #{$color-4}; --license-professional: #{$color-4-2}; From 1c79a8d9131b248cfe129f7ad516495f31942584 Mon Sep 17 00:00:00 2001 From: Lev Skuditsky Date: Sun, 5 Jan 2025 21:07:51 +0200 Subject: [PATCH 3/4] RavenDB-22907: Enhance backup operation status error reporting --- .../RavenTestBase.Backup.cs | 106 ++++++++++++------ 1 file changed, 69 insertions(+), 37 deletions(-) diff --git a/test/Tests.Infrastructure/RavenTestBase.Backup.cs b/test/Tests.Infrastructure/RavenTestBase.Backup.cs index 4637084847c7..8878dd2c8b86 100644 --- a/test/Tests.Infrastructure/RavenTestBase.Backup.cs +++ b/test/Tests.Infrastructure/RavenTestBase.Backup.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -10,6 +11,7 @@ using Raven.Client.Documents.Operations; using Raven.Client.Documents.Operations.Backups; using Raven.Client.Documents.Session; +using Raven.Client.Http; using Raven.Client.ServerWide.Operations; using Raven.Client.ServerWide.Operations.Configuration; using Raven.Client.Util; @@ -55,19 +57,20 @@ public async Task RunBackupAsync(RavenServer server, long taskId, Document { var documentDatabase = await server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var periodicBackupRunner = documentDatabase.PeriodicBackupRunner; - var op = periodicBackupRunner.StartBackupTask(taskId, isFullBackup); + var opId = periodicBackupRunner.StartBackupTask(taskId, isFullBackup); - BackupResult result = default; - var actual = await WaitForValueAsync(async () => + RavenCommand command = null; + await WaitForValueAsync(async () => { - var state = await store.Maintenance.SendAsync(new GetOperationStateOperation(op)); - result = state.Result as BackupResult; - return state.Status; - }, opStatus, timeout: timeout ?? _reasonableTimeout); + command = await ExecuteGetOperationStateCommand(store, opId); + return command.Result != null && + command.Result.Status == opStatus && + command.StatusCode == HttpStatusCode.OK; + }, expectedVal: true, timeout: timeout ?? _reasonableTimeout); - await CheckBackupOperationStatus(opStatus, actual, store, taskId, op, periodicBackupRunner, result); - Assert.Equal(opStatus, actual); - return op; + await CheckBackupOperationStatus(opStatus, command, store, taskId, opId, periodicBackupRunner); + Assert.Equal(opStatus, command.Result.Status); + return opId; } /// @@ -280,19 +283,28 @@ public async Task RunBackupInClusterAsync(DocumentStore store, long taskId, bool { var op = await store.Maintenance.SendAsync(new StartBackupOperation(isFullBackup, taskId)); - BackupResult result = default; - var actual = await WaitForValueAsync(async () => + RavenCommand command = null; + await WaitForValueAsync(async () => { - var state = await store.Maintenance.SendAsync(new GetOperationStateOperation(op.Result.OperationId, op.Result.ResponsibleNode)); - if (state == null) - return OperationStatus.Canceled; + command = await ExecuteGetOperationStateCommand(store, op.Result.OperationId, op.Result.ResponsibleNode); + return command.Result != null && + command.Result.Status == opStatus && + command.StatusCode == HttpStatusCode.OK; + }, expectedVal: true, timeout: timeout ?? _reasonableTimeout); - result = (BackupResult)state.Result; - return state.Status; - }, opStatus, timeout: timeout ?? _reasonableTimeout); + await CheckBackupOperationStatus(opStatus, command, store, taskId, op.Result.OperationId, periodicBackupRunner: null); + Assert.Equal(opStatus, command.Result.Status); + } - await CheckBackupOperationStatus(opStatus, actual, store, taskId, op.Result.OperationId, periodicBackupRunner: null, result); - Assert.Equal(opStatus, actual); + private static async Task> ExecuteGetOperationStateCommand(DocumentStore store, long operationId, string responsibleNode = null) + { + using (store.GetRequestExecutor().ContextPool.AllocateOperationContext(out JsonOperationContext context)) + { + var operation = new GetOperationStateOperation(operationId, responsibleNode); + var command = operation.GetCommand(store.GetRequestExecutor().Conventions, context); + await store.GetRequestExecutor().ExecuteAsync(command, context, sessionInfo: null); + return command; + } } public IDisposable RestoreDatabase(IDocumentStore store, RestoreBackupConfiguration config, TimeSpan? timeout = null, string nodeTag = null) @@ -331,7 +343,7 @@ public async Task GetBackupOperationIdAsync(IDocumentStore store, long tas return result.Status.LastOperationId.Value; } - internal static string PrintBackupStatus(PeriodicBackupStatus status, BackupResult result = default) + internal static string PrintBackupStatus(PeriodicBackupStatus status, BackupResult result = null) { var sb = new StringBuilder(); if (status == null) @@ -500,58 +512,78 @@ internal static string PrintBackupResultMessagesStatus(BackupResult result) return string.Join(Environment.NewLine, result.Messages); } - private static async Task CheckBackupOperationStatus(OperationStatus expected, OperationStatus actual, DocumentStore store, long taskId, long opId, - PeriodicBackupRunner periodicBackupRunner, BackupResult backupResult) + private static async Task CheckBackupOperationStatus(OperationStatus expected, RavenCommand command, DocumentStore store, long taskId, long opId, + PeriodicBackupRunner periodicBackupRunner) { + var backupResult = command.Result?.Result as BackupResult; + var actual = command.Result?.Status; + + // Check if GetOperationStateOperation completed successfully + // We expect both `backupResult` and `actual` to be `null` here due to HTTP error, + // but we'll try to print them anyway to catch any unexpected states + if (command.StatusCode != HttpStatusCode.OK) + { + var operation = new GetPeriodicBackupStatusOperation(taskId); + var status = (await store.Maintenance.SendAsync(operation)).Status; + + TryGetBackupStatusFromPeriodicBackupAndPrint(expected, actual: null, opId, periodicBackupRunner, status, backupResult); + + Assert.Fail($"GetOperationStateOperation failed. Expected status: '{expected}', actual: '{actual?.ToString( ) ?? "null"}',{Environment.NewLine}" + + $"HTTP Status Code: {command.StatusCode},{Environment.NewLine}" + + $"Backup status from storage for operation id: '{opId}':{Environment.NewLine}" + + PrintBackupStatus(status, backupResult)); + } + + // Check if backup completed with error if (expected == OperationStatus.Completed && actual == OperationStatus.Faulted) { - // gather debug info var operation = new GetPeriodicBackupStatusOperation(taskId); var status = (await store.Maintenance.SendAsync(operation)).Status; - TryGetBackupStatusFromPeriodicBackupAndPrint(expected, actual, opId, periodicBackupRunner, status, result: null); + TryGetBackupStatusFromPeriodicBackupAndPrint(expected, actual, opId, periodicBackupRunner, status); - Assert.Fail($"Backup status expected: '{expected}', actual '{actual}',{Environment.NewLine}" + - $"Backup status from storage for current operation id: '{opId}':{Environment.NewLine}" + + Assert.Fail($"Backup operation faulted. Expected status: '{expected}', actual: '{actual}',{Environment.NewLine}" + + $"Backup status from storage for operation id: '{opId}':{Environment.NewLine}" + PrintBackupStatus(status, backupResult)); } + // Check if backup didn't complete within the timeout period if (expected == OperationStatus.Completed && actual == OperationStatus.InProgress) { - // backup didn't complete in time, try to print running backup status, and backup result var pb = periodicBackupRunner?.PeriodicBackups.FirstOrDefault(x => x.RunningBackupStatus != null && x.BackupStatus.TaskId == taskId); if (pb == null) { - // print previous backup status saved in memory var operation = new GetPeriodicBackupStatusOperation(taskId); var result = await store.Maintenance.SendAsync(operation); - Assert.Fail($"Backup status expected: '{expected}', actual '{actual}',{Environment.NewLine}" + - $"Could not fetch running backup status for current task id: '{taskId}', previous backup status:{Environment.NewLine}" + + Assert.Fail($"Backup operation timed out. Expected status: '{expected}', actual: '{actual}',{Environment.NewLine}" + + $"Could not fetch running backup status for task id: '{taskId}', previous backup status:{Environment.NewLine}" + PrintBackupStatus(result.Status, backupResult)); } - Assert.Fail($"Backup status expected: '{expected}', actual '{actual}',{Environment.NewLine}" + - $"Running backup status for current task id: '{taskId}':{Environment.NewLine}" + + Assert.Fail($"Backup operation timed out. Expected status: '{expected}', actual: '{actual}',{Environment.NewLine}" + + $"Running backup status for task id: '{taskId}':{Environment.NewLine}" + PrintBackupStatus(pb.RunningBackupStatus, backupResult)); } } - private static void TryGetBackupStatusFromPeriodicBackupAndPrint(OperationStatus expected, OperationStatus actual, long opId, - PeriodicBackupRunner periodicBackupRunner, PeriodicBackupStatus status, BackupResult result) + private static void TryGetBackupStatusFromPeriodicBackupAndPrint(OperationStatus expected, OperationStatus? actual, long opId, + PeriodicBackupRunner periodicBackupRunner, PeriodicBackupStatus status, BackupResult result = null) { if (status?.LastOperationId == opId) return; + + var actualString = actual?.ToString() ?? "null"; // failed to save backup status, lets fetch it from memory var pb = periodicBackupRunner?.PeriodicBackups.FirstOrDefault(x => x.BackupStatus != null && x.BackupStatus.LastOperationId == opId); if (pb == null) { - Assert.Fail($"Backup status expected: '{expected}', actual '{actual}',{Environment.NewLine}" + + Assert.Fail($"Backup status expected: '{expected}', actual '{actualString}',{Environment.NewLine}" + $"Could not fetch backup status for current operation id: '{opId}', previous backup status:{Environment.NewLine}" + PrintBackupStatus(status, result)); } - Assert.Fail($"Backup status expected: '{expected}', actual '{actual}',{Environment.NewLine}" + + Assert.Fail($"Backup status expected: '{expected}', actual '{actualString}',{Environment.NewLine}" + $"Could not fetch backup status from storage for current operation id: '{opId}', current in memory backup status:{Environment.NewLine}" + PrintBackupStatus(pb.BackupStatus, result)); } From 5125c3d4f8538da807728fcac3319adae9e4eda6 Mon Sep 17 00:00:00 2001 From: Maciej Aszyk Date: Tue, 7 Jan 2025 11:39:13 +0100 Subject: [PATCH 4/4] RavenDB-23512 Use parent slices instead of dynamic binding slices, since dynamic bindings are disposed before the commit. --- src/Corax/Indexing/IndexedField.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Corax/Indexing/IndexedField.cs b/src/Corax/Indexing/IndexedField.cs index 794fcb960374..045cdd881a16 100644 --- a/src/Corax/Indexing/IndexedField.cs +++ b/src/Corax/Indexing/IndexedField.cs @@ -2,6 +2,7 @@ using Corax.Analyzers; using Corax.Mappings; using Sparrow.Collections; +using Sparrow.Server; using Voron; using Voron.Util; @@ -127,8 +128,8 @@ public IndexedField CreateVirtualIndexedField(IndexFieldBinding dynamicField) break; } - return new IndexedField(Constants.IndexWriter.DynamicField, dynamicField.FieldName, dynamicField.FieldNameLong, dynamicField.FieldNameDouble, - dynamicField.FieldTermTotalSumField, analyzer, fieldIndexingMode, dynamicField.HasSuggestions, dynamicField.ShouldStore, + return new IndexedField(Constants.IndexWriter.DynamicField, Name, NameLong, NameDouble, + NameTotalLengthOfTerms, analyzer, fieldIndexingMode, dynamicField.HasSuggestions, dynamicField.ShouldStore, SupportedFeatures, dynamicField.FieldNameForStatistics, FieldRootPage, TermsVectorFieldRootPage, Storage, Textual, Longs, Doubles, this); }