forked from akkadotnet/Akka.Persistence.SqlServer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split performance unit tests into its own project (akkadotnet#306)
- Loading branch information
Showing
8 changed files
with
314 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
...rsistence.SqlServer.Performance.Tests/Akka.Persistence.SqlServer.Performance.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup Condition="'$(OS)' == 'Windows_NT'"> | ||
<TargetFrameworks>$(NetFrameworkTestVersion);$(NetCoreTestVersion)</TargetFrameworks> | ||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<!-- disable .NET Framework (Mono) on Linux--> | ||
<PropertyGroup Condition="'$(OS)' != 'Windows_NT'"> | ||
<TargetFramework>$(NetCoreTestVersion)</TargetFramework> | ||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Data.SqlClient" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" /> | ||
<PackageReference Include="Akka.Persistence.Sql.TestKit" /> | ||
<PackageReference Include="Docker.DotNet" /> | ||
<PackageReference Include="xunit" /> | ||
<PackageReference Include="xunit.runner.visualstudio" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Akka.Persistence.SqlServer\Akka.Persistence.SqlServer.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
src/Akka.Persistence.SqlServer.Performance.Tests/DbUtils.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="DbUtils.cs" company="Akka.NET Project"> | ||
// Copyright (C) 2013 - 2023 .NET Foundation <https://github.com/akkadotnet/akka.net> | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.IO; | ||
using Microsoft.Data.SqlClient; | ||
|
||
namespace Akka.Persistence.SqlServer.Performance.Tests | ||
{ | ||
public static class DbUtils | ||
{ | ||
private static SqlConnectionStringBuilder _builder; | ||
public static string ConnectionString => _builder.ToString(); | ||
|
||
public static void Initialize(string connectionString) | ||
{ | ||
_builder = new SqlConnectionStringBuilder(connectionString); | ||
var databaseName = $"akka_persistence_tests_{Guid.NewGuid()}"; | ||
_builder.InitialCatalog = databaseName; | ||
|
||
var connectionBuilder = new SqlConnectionStringBuilder(connectionString) | ||
{ | ||
InitialCatalog = "master" | ||
}; | ||
|
||
using (var conn = new SqlConnection(connectionBuilder.ToString())) | ||
{ | ||
conn.Open(); | ||
|
||
using (var cmd = new SqlCommand()) | ||
{ | ||
cmd.CommandText = $@" | ||
IF db_id('{databaseName}') IS NULL | ||
BEGIN | ||
CREATE DATABASE [{databaseName}]; | ||
END"; | ||
cmd.Connection = conn; | ||
cmd.ExecuteScalar(); | ||
} | ||
} | ||
|
||
// Delete local snapshot flat file database | ||
var path = "./snapshots"; | ||
if (Directory.Exists(path)) | ||
Directory.Delete(path, true); | ||
} | ||
|
||
public static void Clean() | ||
{ | ||
var databaseName = $"akka_persistence_tests_{Guid.NewGuid()}"; | ||
_builder.InitialCatalog = databaseName; | ||
|
||
var connectionBuilder = new SqlConnectionStringBuilder(ConnectionString) | ||
{ | ||
InitialCatalog = "master" | ||
}; | ||
|
||
using (var conn = new SqlConnection(connectionBuilder.ToString())) | ||
{ | ||
conn.Open(); | ||
|
||
using (var cmd = new SqlCommand()) | ||
{ | ||
cmd.CommandText = $@" | ||
IF db_id('{databaseName}') IS NULL | ||
BEGIN | ||
CREATE DATABASE [{databaseName}]; | ||
END | ||
"; | ||
cmd.Connection = conn; | ||
cmd.ExecuteScalar(); | ||
} | ||
} | ||
|
||
// Delete local snapshot flat file database | ||
var path = "./snapshots"; | ||
if (Directory.Exists(path)) | ||
Directory.Delete(path, true); | ||
} | ||
} | ||
} |
186 changes: 186 additions & 0 deletions
186
src/Akka.Persistence.SqlServer.Performance.Tests/SqlServerFixture.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="SqlServerFixture.cs" company="Akka.NET Project"> | ||
// Copyright (C) 2013 - 2023 .NET Foundation <https://github.com/akkadotnet/akka.net> | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Data.Common; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Runtime.InteropServices; | ||
using System.Threading.Tasks; | ||
using Akka.Util; | ||
using Docker.DotNet; | ||
using Docker.DotNet.Models; | ||
using Xunit; | ||
using Xunit.Sdk; | ||
|
||
namespace Akka.Persistence.SqlServer.Performance.Tests | ||
{ | ||
[CollectionDefinition("SqlServerSpec")] | ||
public sealed class SqlServerSpecsFixture : ICollectionFixture<SqlServerFixture> | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Fixture used to run SQL Server | ||
/// </summary> | ||
public class SqlServerFixture : IAsyncLifetime | ||
{ | ||
protected readonly string SqlContainerName = $"sqlserver-{Guid.NewGuid():N}"; | ||
protected DockerClient Client; | ||
|
||
public SqlServerFixture() | ||
{ | ||
DockerClientConfiguration config; | ||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) | ||
config = new DockerClientConfiguration(new Uri("unix://var/run/docker.sock")); | ||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
config = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")); | ||
else | ||
throw new NotSupportedException($"Unsupported OS [{RuntimeInformation.OSDescription}]"); | ||
|
||
Client = config.CreateClient(); | ||
} | ||
|
||
protected string ImageName => "mcr.microsoft.com/mssql/server"; | ||
protected string Tag => "2019-latest"; | ||
|
||
protected string SqlServerImageName => $"{ImageName}:{Tag}"; | ||
|
||
public string ConnectionString { get; private set; } | ||
|
||
public async Task InitializeAsync() | ||
{ | ||
var sysInfo = await Client.System.GetSystemInfoAsync(); | ||
if (sysInfo.OSType.ToLowerInvariant() != "linux") | ||
throw new TestClassException("MSSQL docker image only available for linux containers"); | ||
|
||
var images = await Client.Images.ListImagesAsync(new ImagesListParameters | ||
{ | ||
Filters = new Dictionary<string, IDictionary<string, bool>> | ||
{ | ||
{ | ||
"reference", | ||
new Dictionary<string, bool> | ||
{ | ||
{ SqlServerImageName, true } | ||
} | ||
} | ||
} | ||
}); | ||
|
||
if (images.Count == 0) | ||
await Client.Images.CreateImageAsync( | ||
new ImagesCreateParameters { FromImage = ImageName, Tag = Tag }, null, | ||
new Progress<JSONMessage>(message => | ||
{ | ||
Console.WriteLine(!string.IsNullOrEmpty(message.ErrorMessage) | ||
? message.ErrorMessage | ||
: $"{message.ID} {message.Status} {message.ProgressMessage}"); | ||
})); | ||
|
||
var sqlServerHostPort = ThreadLocalRandom.Current.Next(9000, 10000); | ||
|
||
// create the container | ||
await Client.Containers.CreateContainerAsync(new CreateContainerParameters | ||
{ | ||
Image = SqlServerImageName, | ||
Name = SqlContainerName, | ||
Tty = true, | ||
ExposedPorts = new Dictionary<string, EmptyStruct> | ||
{ | ||
{ "1433/tcp", new EmptyStruct() } | ||
}, | ||
HostConfig = new HostConfig | ||
{ | ||
PortBindings = new Dictionary<string, IList<PortBinding>> | ||
{ | ||
{ | ||
"1433/tcp", | ||
new List<PortBinding> | ||
{ | ||
new PortBinding | ||
{ | ||
HostPort = $"{sqlServerHostPort}" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
Env = new[] | ||
{ | ||
"ACCEPT_EULA=Y", | ||
"MSSQL_SA_PASSWORD=l0l!Th1sIsOpenSource" | ||
} | ||
}); | ||
|
||
// start the container | ||
await Client.Containers.StartContainerAsync(SqlContainerName, new ContainerStartParameters()); | ||
|
||
// Wait until MSSQL is completely ready | ||
var logStream = await Client.Containers.GetContainerLogsAsync(SqlContainerName, new ContainerLogsParameters | ||
{ | ||
Follow = true, | ||
ShowStdout = true, | ||
ShowStderr = true | ||
}); | ||
|
||
string line = null; | ||
var timeoutInMilis = 60000; | ||
using (var reader = new StreamReader(logStream)) | ||
{ | ||
var stopwatch = Stopwatch.StartNew(); | ||
while (stopwatch.ElapsedMilliseconds < timeoutInMilis && (line = await reader.ReadLineAsync()) != null) | ||
{ | ||
if (!string.IsNullOrWhiteSpace(line)) | ||
Console.WriteLine(line); | ||
if (line.Contains("SQL Server is now ready for client connections.")) break; | ||
} | ||
|
||
stopwatch.Stop(); | ||
} | ||
#if NETCOREAPP3_1_OR_GREATER | ||
await logStream.DisposeAsync(); | ||
#else | ||
logStream.Dispose(); | ||
#endif | ||
if (!line?.Contains("SQL Server is now ready for client connections.") ?? false) | ||
throw new Exception("MSSQL docker image failed to run."); | ||
|
||
var connectionString = new DbConnectionStringBuilder | ||
{ | ||
["Server"] = $"localhost,{sqlServerHostPort}", | ||
["Database"] = "akka_persistence_tests", | ||
["User Id"] = "sa", | ||
["Password"] = "l0l!Th1sIsOpenSource" | ||
}; | ||
|
||
ConnectionString = connectionString.ToString(); | ||
Console.WriteLine($"Connection string: [{ConnectionString}]"); | ||
|
||
await Task.Delay(10000); | ||
} | ||
|
||
public async Task DisposeAsync() | ||
{ | ||
if (Client != null) | ||
try | ||
{ | ||
await Client.Containers.StopContainerAsync(SqlContainerName, new ContainerStopParameters()); | ||
await Client.Containers.RemoveContainerAsync(SqlContainerName, | ||
new ContainerRemoveParameters { Force = true }); | ||
} | ||
catch (DockerContainerNotFoundException) | ||
{ | ||
// no-op | ||
} | ||
finally | ||
{ | ||
Client.Dispose(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters