mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-05 04:47:21 +00:00
Upgraded to .NET 10 (#1147)
This commit is contained in:
1 parent
faae2951f7
commit
fc7399e81b
327 files changed
+3059
-3049
No files matched your search
@@ -75,7 +75,7 @@ public sealed class BackupChatImportTests
|
||||
var transcript = ((ContentText)chat!.Blocks.Single().Content!).FileAttachments.Single();
|
||||
var chatsWithEntries = await provenance.Client.GetChatIdsAsync(CancellationToken.None);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(chatsWithEntries, Is.Empty, "A backup without a provenance store, e.g., of an older version, brings its chats all the same.");
|
||||
Assert.That(preview.Success, Is.True, preview.Issue);
|
||||
@@ -85,7 +85,7 @@ public sealed class BackupChatImportTests
|
||||
Assert.That(result.ImportedWorkspaces, Is.EqualTo(1));
|
||||
Assert.That(transcript.FilePath, Does.StartWith(WorkspaceBehaviour.GetChatDirectory(storedChat.WorkspaceId, storedChat.ChatId)),"The transcript belongs to the chat on this computer, not to the data folder of the other one.");
|
||||
Assert.That(File.ReadAllText(transcript.FilePath), Does.Contain("Hello and welcome."));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -98,11 +98,11 @@ public sealed class BackupChatImportTests
|
||||
await ChatArchiveImporter.ImportAsync(this.ArchivePath, provenance.Client, ChatArchiveCollisionBehavior.SKIP, null, CancellationToken.None);
|
||||
var secondResult = await ChatArchiveImporter.ImportAsync(this.ArchivePath, provenance.Client, ChatArchiveCollisionBehavior.SKIP, null, CancellationToken.None);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(secondResult.ImportedChats, Is.Zero);
|
||||
Assert.That(secondResult.SkippedChats, Is.EqualTo(1), "Two chats with one ID would leave the app unable to tell them apart.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -119,13 +119,13 @@ public sealed class BackupChatImportTests
|
||||
var stagingDirectory = Path.Combine(this.TargetDataDirectory, ".backup-staging");
|
||||
var stagingLeftovers = Directory.Exists(stagingDirectory) ? Directory.GetFileSystemEntries(stagingDirectory) : Array.Empty<string>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(result.ImportedChats, Is.EqualTo(1));
|
||||
Assert.That(entries[storedChat.ProvenanceId.Value].Content, Is.EqualTo("Hello and welcome."), "The chat refers to the entry by its id, which the import keeps.");
|
||||
Assert.That(chatsWithEntries, Is.EqualTo(new[] { storedChat.ChatId }), "Another chat's entries of the source computer stay behind.");
|
||||
Assert.That(stagingLeftovers, Is.Empty, "The unpacked store of the backup is removed afterward.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -144,13 +144,13 @@ public sealed class BackupChatImportTests
|
||||
await using var context = provenance.CreateContext();
|
||||
var copiesOfTheEntry = await context.Entries.CountAsync(entry => entry.Id == entryKey);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(secondResult.ImportedChats, Is.EqualTo(1));
|
||||
Assert.That(chatsWithEntries, Has.Count.EqualTo(2), "The copy under its new id gets entries of its own, so deleting one of the two chats leaves the other whole.");
|
||||
Assert.That(chatsWithEntries, Does.Contain(storedChat.ChatId));
|
||||
Assert.That(copiesOfTheEntry, Is.EqualTo(2), "Both chats refer to the entry by the same id.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -166,11 +166,11 @@ public sealed class BackupChatImportTests
|
||||
|
||||
var preview = await ChatArchiveImporter.ReadPreviewAsync(this.ArchivePath, CancellationToken.None);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(preview.Success, Is.False, "This version cannot know what a later format holds.");
|
||||
Assert.That(preview.Issue, Is.Not.Empty);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -30,12 +30,12 @@ public sealed class DataBackupContentsTests
|
||||
{
|
||||
var paths = DataBackupContents.ENTRIES.Where(entry => entry.IsIncluded).Select(entry => entry.RelativePath).ToList();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(paths.Where(path => path.Contains('*')), Is.Empty, "A restore replaces exactly what the backup holds, so it has to know the names.");
|
||||
Assert.That(paths.Where(path => path.Contains('\\')), Is.Empty, "Paths use forward slashes on every OS.");
|
||||
Assert.That(paths.Where(path => path.StartsWith(DataBackupContents.SEPARATOR)), Is.Empty, "Paths are relative to their folder.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -27,7 +27,7 @@ public sealed class DataBackupSettingsTests
|
||||
|
||||
var copy = DataBackupSettings.CopyWithoutPluginObjects(settings);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(copy.Providers.Select(provider => provider.Id), Is.EqualTo(new[] { "user-provider" }));
|
||||
Assert.That(copy.TranscriptionProviders.Select(provider => provider.Id), Is.EqualTo(new[] { "user-transcription" }));
|
||||
@@ -36,7 +36,7 @@ public sealed class DataBackupSettingsTests
|
||||
Assert.That(copy.DataSources.Select(dataSource => dataSource.Id), Is.EqualTo(new[] { "user-data-source" }));
|
||||
Assert.That(copy.Profiles.Select(profile => profile.Id), Is.EqualTo(new[] { "user-profile" }));
|
||||
Assert.That(copy.DocumentAnalysis.Policies.Select(policy => policy.Id), Is.EqualTo(new[] { "user-policy" }));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -46,12 +46,12 @@ public sealed class DataBackupSettingsTests
|
||||
|
||||
DataBackupSettings.CopyWithoutPluginObjects(settings);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(settings.Providers, Has.Count.EqualTo(2));
|
||||
Assert.That(settings.DataSources, Has.Count.EqualTo(2));
|
||||
Assert.That(settings.DocumentAnalysis.Policies, Has.Count.EqualTo(2));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -63,11 +63,11 @@ public sealed class DataBackupSettingsTests
|
||||
|
||||
var copy = DataBackupSettings.CopyWithoutPluginObjects(settings);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(copy.ManagedLockedConfigurations["App.UpdateInterval"], Is.EqualTo(PLUGIN_ID), "After a restore, the clean-up hands the setting back to the user unless the plugin locks it again.");
|
||||
Assert.That(copy.ManagedUserValueSnapshots["App.UpdateInterval"], Is.EqualTo("\"CHECK_EVERY_DAY\""), "That is the value the user gets back.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static Data CreateSettingsWithObjectsOfTheUserAndOfAPlugin()
|
||||
|
||||
@@ -98,14 +98,14 @@ public sealed class DataBackupWriterTests
|
||||
DataBackupFormat.MANIFEST_ENTRY_NAME,
|
||||
}));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(archive["config/settings.json"], Is.EqualTo(SETTINGS_JSON), "The settings come from memory, without the objects of configuration plugins.");
|
||||
Assert.That(archive["data/databases/provenance/provenance.sqlite3"], Is.EqualTo("the copy of the provenance store"), "The chats write to the store at any time, so it comes from its copy, without the write-ahead log of the live one.");
|
||||
Assert.That(archive["data/databases/sqlite/rag-index.sqlite3"], Is.EqualTo("the copy of the index"));
|
||||
Assert.That(archive["data/databases/vector_database/stores/store_1/segments/segment"], Is.EqualTo("the copy of the store"));
|
||||
Assert.That(archive[$"data/{MEDIA_TRANSCRIPT}"], Is.EqualTo("the copy of the transcript"), "The transcripts are copied together with the index they belong to.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -130,11 +130,11 @@ public sealed class DataBackupWriterTests
|
||||
{
|
||||
var archive = await this.WriteBackupAsync(this.IndexCopiesDirectory, _ => Task.FromResult(string.Empty));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(archive["data/databases/provenance/provenance.sqlite3"], Is.EqualTo("the provenance store while AI Studio writes to it"), "A store AI Studio could not open is written by nothing, and the backup keeps whatever there is.");
|
||||
Assert.That(archive["data/databases/provenance/provenance.sqlite3-wal"], Is.EqualTo("the write-ahead log of the provenance store"), "Its write-ahead log may hold what the store itself lacks yet.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -173,11 +173,11 @@ public sealed class DataBackupWriterTests
|
||||
var hash = Convert.ToHexStringLower(await SHA256.HashDataAsync(stream));
|
||||
var listed = manifest.Entries.Single(listedEntry => listedEntry.Name == entry.FullName);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(listed.Sha256, Is.EqualTo(hash), $"The hash of '{entry.FullName}' lets a restore notice a damaged backup.");
|
||||
Assert.That(listed.Size, Is.EqualTo(entry.Length));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,14 +214,14 @@ public sealed class DataBackupWriterTests
|
||||
await using (var entryStream = largeEntry.Open())
|
||||
hash = Convert.ToHexStringLower(await SHA256.HashDataAsync(entryStream));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(new FileInfo(archivePath).Length, Is.GreaterThan(FOUR_GIBIBYTES), "Only then do positions need ZIP64 as well.");
|
||||
Assert.That(largeEntry.Length, Is.EqualTo(LARGE_FILE_SIZE));
|
||||
Assert.That(listed.Size, Is.EqualTo(LARGE_FILE_SIZE));
|
||||
Assert.That(listed.Sha256, Is.EqualTo(hash), "The large file comes back as it was.");
|
||||
Assert.That(manifest.Entries, Has.Count.EqualTo(zip.Entries.Count - 1), "The manifest lies behind the large file, beyond 4 GiB, and is still found.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Dictionary<string, string>> WriteBackupAsync(string indexCopiesDirectory, Func<CancellationToken, Task<string>>? copyProvenanceStoreAsync = null)
|
||||
|
||||
@@ -42,12 +42,12 @@ public sealed class DataRestoreFollowUpTests
|
||||
|
||||
DataRestoreFollowUp.RemoveLeftovers(this.DataDirectory, this.ConfigDirectory);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(Directory.Exists(Path.Combine(this.DataDirectory, ".backup-staging")), Is.False);
|
||||
Assert.That(Directory.Exists(Path.Combine(this.DataDirectory, ".restore-pending")), Is.False);
|
||||
Assert.That(Directory.Exists(Path.Combine(this.ConfigDirectory, ".restore-pending")), Is.False);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -58,12 +58,12 @@ public sealed class DataRestoreFollowUpTests
|
||||
|
||||
DataRestoreFollowUp.RemoveLeftovers(this.DataDirectory, this.ConfigDirectory);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(DataRestoreFollowUp.IsRestorePending(this.DataDirectory), Is.True);
|
||||
Assert.That(DataRestoreFollowUp.IsRestoreUnfinished(this.DataDirectory), Is.False);
|
||||
Assert.That(File.Exists(Path.Combine(this.DataDirectory, ".restore-pending", "workspaces", "chat", "thread.json")), Is.True);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -77,7 +77,7 @@ public sealed class DataRestoreFollowUpTests
|
||||
DataRestoreFollowUp.RemoveLeftovers(this.DataDirectory, this.ConfigDirectory);
|
||||
var removedReplacedData = DataRestoreFollowUp.RemoveReplacedData(this.DataDirectory, this.ConfigDirectory);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(DataRestoreFollowUp.IsRestoreUnfinished(this.DataDirectory), Is.True);
|
||||
Assert.That(DataRestoreFollowUp.IsRestorePending(this.DataDirectory), Is.False, "The runtime moves it back rather than applying it.");
|
||||
@@ -85,7 +85,7 @@ public sealed class DataRestoreFollowUpTests
|
||||
Assert.That(File.Exists(Path.Combine(this.DataDirectory, ".restore-previous", "workspaces", "chat", "thread.json")), Is.True, "These are the data of the user.");
|
||||
Assert.That(() => DataRestorePreparer.Discard(target), Throws.InvalidOperationException);
|
||||
Assert.That(File.Exists(Path.Combine(this.DataDirectory, ".restore-pending", DataRestoreFormat.JOURNAL_FILE_NAME)), Is.True);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -96,12 +96,12 @@ public sealed class DataRestoreFollowUpTests
|
||||
|
||||
var removedReplacedData = DataRestoreFollowUp.RemoveReplacedData(this.DataDirectory, this.ConfigDirectory);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(removedReplacedData, Is.True);
|
||||
Assert.That(Directory.Exists(Path.Combine(this.DataDirectory, ".restore-previous")), Is.False);
|
||||
Assert.That(Directory.Exists(Path.Combine(this.ConfigDirectory, ".restore-previous")), Is.False);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -120,13 +120,13 @@ public sealed class DataRestoreFollowUpTests
|
||||
|
||||
var report = await DataRestoreFollowUp.ReadReportAsync(this.DataDirectory, CancellationToken.None);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(report, Is.Not.Null);
|
||||
Assert.That(report!.Outcome, Is.EqualTo(DataRestoreOutcome.ROLLED_BACK));
|
||||
Assert.That(report.BackupAppVersion, Is.EqualTo("26.10.1"));
|
||||
Assert.That(report.Detail, Does.Contain("access denied"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -50,7 +50,7 @@ public sealed class DataRestorePreparerTests
|
||||
var threadPath = Path.Combine(dataPending, "workspaces", WORKSPACE_ID.ToString(), CHAT_ID.ToString(), "thread.json");
|
||||
var plan = JsonSerializer.Deserialize<DataRestorePlan>(await File.ReadAllTextAsync(Path.Combine(dataPending, DataRestoreFormat.PLAN_FILE_NAME)), DataBackupFormat.JSON_OPTIONS)!;
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(result.Success, Is.True, result.Issue);
|
||||
Assert.That(DataRestorePreparer.IsPrepared(this.Target), Is.True);
|
||||
@@ -61,7 +61,7 @@ public sealed class DataRestorePreparerTests
|
||||
|
||||
Assert.That(plan.Elements.Select(element => $"{element.Location}:{element.RelativePath}"), Is.EquivalentTo((string[])["CONFIG_DIRECTORY:settings.json", "DATA_DIRECTORY:workspaces/", "DATA_DIRECTORY:plugins/"]), "An element the backup holds nothing for, such as the tokenizers here, stays as it is.");
|
||||
Assert.That(plan.Elements.Single(element => element.RelativePath == "plugins/").Keep, Is.SupersetOf((string[])["plugins/.internal/", "plugins/.config/", "plugins/.config-tests/", "plugins/company-assistant/"]), "AI Studio and the organization bring their plugins themselves.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -73,12 +73,12 @@ public sealed class DataRestorePreparerTests
|
||||
var dataPending = Path.Combine(this.Target.DataDirectory, ".restore-pending");
|
||||
var plan = JsonSerializer.Deserialize<DataRestorePlan>(await File.ReadAllTextAsync(Path.Combine(dataPending, DataRestoreFormat.PLAN_FILE_NAME)), DataBackupFormat.JSON_OPTIONS)!;
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(result.Success, Is.True, result.Issue);
|
||||
Assert.That(plan.Elements.Select(element => element.RelativePath), Does.Contain("databases/provenance/"), "The chats of the backup refer to the contents in its store, so both are replaced together, whether the backup holds the indexes or not.");
|
||||
Assert.That(File.ReadAllText(Path.Combine(dataPending, "databases", "provenance", "provenance.sqlite3")), Is.EqualTo("the provenance store"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -88,13 +88,13 @@ public sealed class DataRestorePreparerTests
|
||||
|
||||
var result = await DataRestorePreparer.PrepareAsync(this.ArchivePath, this.Target, null, CancellationToken.None);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(result.Success, Is.False);
|
||||
Assert.That(result.Issue, Does.Contain("thread.json"));
|
||||
Assert.That(Directory.Exists(Path.Combine(this.Target.DataDirectory, ".restore-pending")), Is.False, "The next start must find nothing to apply.");
|
||||
Assert.That(Directory.Exists(Path.Combine(this.Target.ConfigDirectory, ".restore-pending")), Is.False);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("27.1.0", "V6")]
|
||||
@@ -105,11 +105,11 @@ public sealed class DataRestorePreparerTests
|
||||
|
||||
var result = await DataRestorePreparer.PrepareAsync(this.ArchivePath, this.Target, null, CancellationToken.None);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(result.Success, Is.False, "Its settings or its index may have a form this version cannot read.");
|
||||
Assert.That(DataRestorePreparer.IsPrepared(this.Target), Is.False);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -120,11 +120,11 @@ public sealed class DataRestorePreparerTests
|
||||
|
||||
DataRestorePreparer.Discard(this.Target);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(DataRestorePreparer.IsPrepared(this.Target), Is.False);
|
||||
Assert.That(Directory.Exists(Path.Combine(this.Target.ConfigDirectory, ".restore-pending")), Is.False);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
Reference in new issue
Block a user