Publish curated Knowledge Hub source from 2ed833f290b439a7bc91e5fd19b042c269e3bee9
This commit is contained in:
1 parent
10f2edcd29
commit
59f15b2d08
218 files changed
+23995
-1849
No files matched your search
@@ -46,40 +46,120 @@ public sealed class RestoreModeRunnerTests
|
||||
[Fact]
|
||||
public async Task A_successful_restore_returns_exit_code_zero()
|
||||
{
|
||||
var connectionString = "Host=restore-db;Username=restore;Password=public-fixture";
|
||||
var connectionFile = await CreateConnectionFileAsync(connectionString);
|
||||
string? receivedConnectionString = null;
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IRestoreService>(new FakeRestoreService(shouldSucceed: true))
|
||||
.AddSingleton<IRestoreService>(new FakeRestoreService(shouldSucceed: true,
|
||||
target => receivedConnectionString = target.ConnectionString))
|
||||
.BuildServiceProvider();
|
||||
using var output = new StringWriter();
|
||||
|
||||
var exitCode = await RestoreModeRunner.RunAsync(
|
||||
["--restore", "--backup-id=abc", "--target-connection=conn", "--target-attachments=/tmp/x"],
|
||||
services, output, CancellationToken.None);
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
exitCode = await RestoreModeRunner.RunAsync(
|
||||
["--restore", "--backup-id=abc", $"--target-connection-file={connectionFile}", "--target-attachments=/tmp/x"],
|
||||
services, output, CancellationToken.None);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(connectionFile);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
Assert.Contains("GESLAAGD", output.ToString(), StringComparison.Ordinal);
|
||||
Assert.Equal(connectionString, receivedConnectionString);
|
||||
Assert.DoesNotContain(connectionString, output.ToString(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task A_failed_restore_returns_a_non_zero_exit_code_and_reports_the_mismatch()
|
||||
{
|
||||
var connectionFile = await CreateConnectionFileAsync("Host=restore-db;Username=restore;Password=public-fixture");
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IRestoreService>(new FakeRestoreService(shouldSucceed: false))
|
||||
.BuildServiceProvider();
|
||||
using var output = new StringWriter();
|
||||
|
||||
var exitCode = await RestoreModeRunner.RunAsync(
|
||||
["--restore", "--backup-id=abc", "--target-connection=conn", "--target-attachments=/tmp/x"],
|
||||
services, output, CancellationToken.None);
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
exitCode = await RestoreModeRunner.RunAsync(
|
||||
["--restore", "--backup-id=abc", $"--target-connection-file={connectionFile}", "--target-attachments=/tmp/x"],
|
||||
services, output, CancellationToken.None);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(connectionFile);
|
||||
}
|
||||
|
||||
Assert.Equal(1, exitCode);
|
||||
Assert.Contains("MISLUKT", output.ToString(), StringComparison.Ordinal);
|
||||
Assert.Contains("AFWIJKING", output.ToString(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private sealed class FakeRestoreService(bool shouldSucceed) : IRestoreService
|
||||
[Fact]
|
||||
public async Task Plaintext_connection_argument_is_not_accepted_or_echoed()
|
||||
{
|
||||
const string secret = "Password=public-fixture";
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IRestoreService>(new FakeRestoreService(shouldSucceed: true))
|
||||
.BuildServiceProvider();
|
||||
using var output = new StringWriter();
|
||||
|
||||
var exitCode = await RestoreModeRunner.RunAsync(
|
||||
["--restore", "--backup-id=abc", $"--target-connection={secret}", "--target-attachments=/tmp/x"],
|
||||
services, output, CancellationToken.None);
|
||||
|
||||
Assert.Equal(2, exitCode);
|
||||
Assert.DoesNotContain(secret, output.ToString(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Restore_failure_does_not_print_exception_details_that_may_contain_credentials()
|
||||
{
|
||||
const string secret = "Password=public-fixture";
|
||||
var connectionFile = await CreateConnectionFileAsync("Host=restore-db;" + secret);
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IRestoreService>(new FakeRestoreService(exception: new InvalidOperationException(secret)))
|
||||
.BuildServiceProvider();
|
||||
using var output = new StringWriter();
|
||||
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
exitCode = await RestoreModeRunner.RunAsync(
|
||||
["--restore", "--backup-id=abc", $"--target-connection-file={connectionFile}", "--target-attachments=/tmp/x"],
|
||||
services, output, CancellationToken.None);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(connectionFile);
|
||||
}
|
||||
|
||||
Assert.Equal(1, exitCode);
|
||||
Assert.DoesNotContain(secret, output.ToString(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> CreateConnectionFileAsync(string connectionString)
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), "ikh-restore-connection-" + Guid.NewGuid().ToString("N"));
|
||||
await File.WriteAllTextAsync(path, connectionString);
|
||||
if (!OperatingSystem.IsWindows())
|
||||
File.SetUnixFileMode(path, UnixFileMode.UserRead | UnixFileMode.UserWrite);
|
||||
return path;
|
||||
}
|
||||
|
||||
private sealed class FakeRestoreService(
|
||||
bool shouldSucceed = true,
|
||||
Action<RestoreTarget>? onRestore = null,
|
||||
Exception? exception = null) : IRestoreService
|
||||
{
|
||||
public Task<RestoreReport> RestoreAsync(string backupId, RestoreTarget target, CancellationToken cancellationToken)
|
||||
{
|
||||
if (exception is not null) throw exception;
|
||||
onRestore?.Invoke(target);
|
||||
var tables = shouldSucceed
|
||||
? new List<RestoreTableReport> { new("pages", 3, 3) }
|
||||
: new List<RestoreTableReport> { new("pages", 2, 3) };
|
||||
|
||||
Reference in new issue
Block a user