Skip to content

Commit

Permalink
Backup test repair
Browse files Browse the repository at this point in the history
  • Loading branch information
marcwittke committed May 23, 2018
1 parent 2ab418e commit 1807df0
Show file tree
Hide file tree
Showing 10 changed files with 636 additions and 22 deletions.
59 changes: 43 additions & 16 deletions src/Backend.Fx.Testing/Containers/MssqlDockerContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract class MssqlDockerContainer : DatabaseDockerContainer
private readonly string saPassword;

protected MssqlDockerContainer(string dockerApiUrl, [NotNull] string saPassword, string name = null, string baseImage = null)
: base(baseImage ?? "microsoft/mssql-server-linux:latest", name, new[] { $"SA_PASSWORD={saPassword}","ACCEPT_EULA=Y", "MSSQL_PID=Developer" }, dockerApiUrl)
: base(baseImage ?? "microsoft/mssql-server-linux:latest", name, new[] { $"SA_PASSWORD={saPassword}", "ACCEPT_EULA=Y", "MSSQL_PID=Developer" }, dockerApiUrl)
{
this.saPassword = saPassword ?? throw new ArgumentNullException(nameof(saPassword));
}
Expand Down Expand Up @@ -64,13 +64,43 @@ public async Task Restore(string bakFilePath, string dbName)
{
connection.Open();

using (var restoreCommand = connection.CreateCommand())
{
restoreCommand.CommandText = "USE master";
restoreCommand.ExecuteNonQuery();
}

string logicalDataName = "";
string logicalLogName = "";
using (var fileListCommand=connection.CreateCommand())
{
fileListCommand.CommandText = $"RESTORE FILELISTONLY FROM DISK = N'{targetPath}/{Path.GetFileName(bakFilePath)}'";
using (var reader = fileListCommand.ExecuteReader())
{
while(reader.Read())
{
int typeOrdinal = reader.GetOrdinal("Type");
int logicalNameOrdinal = reader.GetOrdinal("LogicalName");
if (reader.GetString(typeOrdinal) == "D")
{
logicalDataName = reader.GetString(logicalNameOrdinal);
}

if (reader.GetString(typeOrdinal) == "L")
{
logicalLogName = reader.GetString(logicalNameOrdinal);
}
}
}
}

using (var restoreCommand = connection.CreateCommand())
{
var restoreCommandCommandText
= $"RESTORE DATABASE [{dbName}] FROM DISK = N'{targetPath}/{Path.GetFileName(bakFilePath)}' " +
"WITH FILE = 1, " +
$"MOVE N'mep-prod-sql_Data' TO N'/var/opt/mssql/data/{dbName}_data.mdf', " +
$"MOVE N'mep-prod-sql_Log' TO N'/var/opt/mssql/data/{dbName}_log.ldf', " +
$"MOVE N'{logicalDataName}' TO N'/var/opt/mssql/data/{dbName}_data.mdf', " +
$"MOVE N'{logicalLogName}' TO N'/var/opt/mssql/data/{dbName}_log.ldf', " +
"NOUNLOAD, REPLACE ";

restoreCommand.CommandText = restoreCommandCommandText;
Expand All @@ -81,20 +111,17 @@ var restoreCommandCommandText

private Stream CreateTarGz(string sourceFile)
{
var tempFileName = Path.GetTempFileName();
Stream outStream = File.Create(tempFileName);
Stream gzoStream = new GZipOutputStream(outStream);
TarArchive tarArchive = TarArchive.CreateOutputTarArchive(gzoStream);

TarEntry tarEntry = TarEntry.CreateEntryFromFile(sourceFile);
tarArchive.WriteEntry(tarEntry, true);

tarArchive.Close();

Stream outStream = new MemoryStream();
using (Stream gzoStream = new GZipOutputStream(outStream))
{
using (TarArchive tarArchive = TarArchive.CreateOutputTarArchive(gzoStream))
{
TarEntry tarEntry = TarEntry.CreateEntryFromFile(sourceFile);
tarArchive.WriteEntry(tarEntry, true);
tarArchive.Close();
}
}

outStream.Seek(0, SeekOrigin.Begin);
return outStream;
return File.OpenRead(tempFileName);
}
}
}
6 changes: 6 additions & 0 deletions tests/Backend.Fx.Tests/Backend.Fx.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>

<ItemGroup>
<None Update="Backup.bak">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Binary file added tests/Backend.Fx.Tests/Backup.bak
Binary file not shown.
30 changes: 24 additions & 6 deletions tests/Backend.Fx.Tests/Containers/TheMssqlDockerContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using Environment;
using Environment.VisualStudioOnline;
using Fx.Extensions;
using RandomData;
using Testing.Containers;
using Xunit;

public class TestContainer : MssqlDockerContainer
{
public TestContainer(string dockerApiUrl)
: base(dockerApiUrl, TestRandom.NextPassword(), "BackendFxTests" + DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"))
public TestContainer(string dockerApiUrl, string name)
: base(dockerApiUrl, TestRandom.NextPassword(), name + DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"))
{ }

public override IDbConnection CreateConnection()
Expand All @@ -23,22 +25,38 @@ public override IDbConnection CreateConnection()

public class TheMssqlDockerContainer
{
private readonly string dockerApiUri;

public TheMssqlDockerContainer()
{
string apiUrl = AsyncHelper.RunSync(()=> DockerUtilities.DetectDockerClientApi());
AsyncHelper.RunSync(()=> DockerUtilities.KillAllOlderThan(apiUrl, TimeSpan.FromMinutes(30)));
dockerApiUri = AsyncHelper.RunSync(()=> DockerUtilities.DetectDockerClientApi());
if (Build.IsTfBuild)
{
AsyncHelper.RunSync(()=> DockerUtilities.KillAllOlderThan(dockerApiUri, TimeSpan.FromMinutes(30)));
}
}

[Fact]
public async Task CanBeUsed()
{
string apiUrl = await DockerUtilities.DetectDockerClientApi();
using (TestContainer container = new TestContainer(dockerApiUri, "TheMssqlDockerContainer_CanBeUsed"))
{
await container.CreateAndStart();
Assert.False(container.HealthCheck());
Assert.True(container.WaitUntilIsHealthy());
}
}

using (TestContainer container = new TestContainer(apiUrl))
[Fact]
public async Task CanRestore()
{
using (TestContainer container = new TestContainer(dockerApiUri, "TheMssqlDockerContainer_CanRestore"))
{
await container.CreateAndStart();
Assert.False(container.HealthCheck());
Assert.True(container.WaitUntilIsHealthy());

await container.Restore("Backup.bak", "RestoredDb");
}
}
}
Expand Down
63 changes: 63 additions & 0 deletions tests/Backend.Fx.Tests/Environment/VisualStudioOnline/Agent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
namespace Backend.Fx.Tests.Environment.VisualStudioOnline
{

public static class Agent
{
/// <summary>
/// The local path on the agent where all folders for a given build definition are created.
/// </summary>
public static string BuildDirectory
{
get { return global::System.Environment.GetEnvironmentVariable("AGENT_BUILDDIRECTORY"); }
}

/// <summary>
/// The directory the agent is installed into. This contains the agent software.
/// </summary>
public static string HomeDirectory
{
get { return global::System.Environment.GetEnvironmentVariable("AGENT_HOMEDIRECTORY"); }
}

/// <summary>
/// The ID of the agent.
/// </summary>
public static string Id
{
get { return global::System.Environment.GetEnvironmentVariable("AGENT_ID"); }
}

/// <summary>
/// The status of the build.
/// </summary>
public static AgentJobStatus JobStatus
{
get { return global::System.Enum.Parse<AgentJobStatus>(global::System.Environment.GetEnvironmentVariable("AGENT_JOBSTATUS") ?? "None"); }
}

/// <summary>
/// The name of the machine on which the agent is installed.
/// </summary>
public static string MachineName
{
get { return global::System.Environment.GetEnvironmentVariable("AGENT_MACHINENAME"); }
}

/// <summary>
/// The name of the agent that is registered with the pool.
/// If you are using an on-premises agent, this directory is specified by you.
/// </summary>
public static string Name
{
get { return global::System.Environment.GetEnvironmentVariable("AGENT_NAME"); }
}

/// <summary>
/// The working directory for this agent. For example: c:\agent\_work.
/// </summary>
public static string WorkFolder
{
get { return global::System.Environment.GetEnvironmentVariable("AGENT_WORKFOLDER"); }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Backend.Fx.Tests.Environment
{
public enum AgentJobStatus
{
None,
Canceled,
Failed,
Succeeded,

/// <summary>
/// partially successful
/// </summary>
SucceededWithIssues
}
}

0 comments on commit 1807df0

Please sign in to comment.