Skip to content

Commit

Permalink
Parameterize almost-identical metrics tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrainger committed Jan 11, 2024
1 parent 8fffc06 commit 19fb8e5
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 126 deletions.
143 changes: 18 additions & 125 deletions tests/MySqlConnector.Tests/Metrics/ConnectionsUsageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ namespace MySqlConnector.Tests.Metrics;

public class ConnectionsUsageTests : MetricsTestsBase
{
[Fact(Skip = MetricsSkip)]
public void NamedDataSource()
[Theory(Skip = MetricsSkip)]
[MemberData(nameof(GetPoolCreators))]
public void PoolCreators(IConnectionCreator connectionCreator)
{
PoolName = "metrics-test";
using var dataSource = new MySqlDataSourceBuilder(CreateConnectionStringBuilder().ConnectionString)
.UseName(PoolName)
.Build();
connectionCreator.SetConnectionStringBuilder(CreateConnectionStringBuilder());
PoolName = connectionCreator.PoolName;

// no connections at beginning of test
AssertMeasurement("db.client.connections.usage", 0);
Expand All @@ -19,7 +18,7 @@ public void NamedDataSource()
Assert.Equal(0, Server.ActiveConnections);

// opening a connection creates a 'used' connection
using (var connection = dataSource.OpenConnection())
using (var connection = connectionCreator.OpenConnection())
{
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 0);
Expand All @@ -34,7 +33,7 @@ public void NamedDataSource()
Assert.Equal(1, Server.ActiveConnections);

// reopening the connection transitions it back to 'used'
using (var connection = dataSource.OpenConnection())
using (var connection = connectionCreator.OpenConnection())
{
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 0);
Expand All @@ -43,8 +42,8 @@ public void NamedDataSource()
Assert.Equal(1, Server.ActiveConnections);

// opening a second connection creates a net new 'used' connection
using (var connection = dataSource.OpenConnection())
using (var connection2 = dataSource.OpenConnection())
using (var connection = connectionCreator.OpenConnection())
using (var connection2 = connectionCreator.OpenConnection())
{
AssertMeasurement("db.client.connections.usage", 2);
AssertMeasurement("db.client.connections.usage|idle", 0);
Expand All @@ -56,6 +55,15 @@ public void NamedDataSource()
AssertMeasurement("db.client.connections.usage|idle", 2);
AssertMeasurement("db.client.connections.usage|used", 0);
Assert.Equal(2, Server.ActiveConnections);

connectionCreator.Dispose();
}

public static IEnumerable<object[]> GetPoolCreators()
{
yield return new object[] { new DataSourceConnectionCreator("metrics-test") };
yield return new object[] { new DataSourceConnectionCreator(null) };
yield return new object[] { new PlainConnectionCreator() };
}

[Fact(Skip = MetricsSkip)]
Expand Down Expand Up @@ -91,121 +99,6 @@ public void NamedDataSourceWithMinPoolSize()
Assert.Equal(3, Server.ActiveConnections);
}

[Fact(Skip = MetricsSkip)]
public void UnnamedDataSource()
{
var csb = CreateConnectionStringBuilder();

// NOTE: pool "name" is connection string (without password)
PoolName = csb.GetConnectionString(includePassword: false);

using var dataSource = new MySqlDataSourceBuilder(csb.ConnectionString)
.Build();

// no connections at beginning of test
AssertMeasurement("db.client.connections.usage", 0);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 0);
Assert.Equal(0, Server.ActiveConnections);

// opening a connection creates a 'used' connection
using (var connection = dataSource.OpenConnection())
{
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 1);
Assert.Equal(1, Server.ActiveConnections);
}

// closing it creates an 'idle' connection
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 1);
AssertMeasurement("db.client.connections.usage|used", 0);
Assert.Equal(1, Server.ActiveConnections);

// reopening the connection transitions it back to 'used'
using (var connection = dataSource.OpenConnection())
{
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 1);
}
Assert.Equal(1, Server.ActiveConnections);

// opening a second connection creates a net new 'used' connection
using (var connection = dataSource.OpenConnection())
using (var connection2 = dataSource.OpenConnection())
{
AssertMeasurement("db.client.connections.usage", 2);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 2);
Assert.Equal(2, Server.ActiveConnections);
}

AssertMeasurement("db.client.connections.usage", 2);
AssertMeasurement("db.client.connections.usage|idle", 2);
AssertMeasurement("db.client.connections.usage|used", 0);
Assert.Equal(2, Server.ActiveConnections);
}

[Fact(Skip = MetricsSkip)]
public void NoDataSource()
{
var csb = CreateConnectionStringBuilder();

// NOTE: pool "name" is connection string (without password)
PoolName = csb.GetConnectionString(includePassword: false);

// no connections at beginning of test
AssertMeasurement("db.client.connections.usage", 0);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 0);
Assert.Equal(0, Server.ActiveConnections);

// opening a connection creates a 'used' connection
using (var connection = new MySqlConnection(csb.ConnectionString))
{
connection.Open();
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 1);
Assert.Equal(1, Server.ActiveConnections);
}

// closing it creates an 'idle' connection
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 1);
AssertMeasurement("db.client.connections.usage|used", 0);
Assert.Equal(1, Server.ActiveConnections);

// reopening the connection transitions it back to 'used'
using (var connection = new MySqlConnection(csb.ConnectionString))
{
connection.Open();
AssertMeasurement("db.client.connections.usage", 1);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 1);
}
Assert.Equal(1, Server.ActiveConnections);

// opening a second connection creates a net new 'used' connection
using (var connection = new MySqlConnection(csb.ConnectionString))
using (var connection2 = new MySqlConnection(csb.ConnectionString))
{
connection.Open();
connection2.Open();
AssertMeasurement("db.client.connections.usage", 2);
AssertMeasurement("db.client.connections.usage|idle", 0);
AssertMeasurement("db.client.connections.usage|used", 2);
Assert.Equal(2, Server.ActiveConnections);
}

AssertMeasurement("db.client.connections.usage", 2);
AssertMeasurement("db.client.connections.usage|idle", 2);
AssertMeasurement("db.client.connections.usage|used", 0);
Assert.Equal(2, Server.ActiveConnections);
}

[Fact(Skip = MetricsSkip)]
public async Task PendingRequestForCreation()
{
Expand Down
47 changes: 47 additions & 0 deletions tests/MySqlConnector.Tests/Metrics/IConnectionCreator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#nullable enable

namespace MySqlConnector.Tests.Metrics;

public interface IConnectionCreator : IDisposable
{
void SetConnectionStringBuilder(MySqlConnectionStringBuilder connectionStringBuilder);
string PoolName { get; }
MySqlConnection OpenConnection();
}

internal sealed class DataSourceConnectionCreator(string? poolName) : IConnectionCreator
{
public void SetConnectionStringBuilder(MySqlConnectionStringBuilder connectionStringBuilder)
{
m_connectionStringBuilder = connectionStringBuilder;
m_dataSource = new MySqlDataSourceBuilder(connectionStringBuilder.ConnectionString)
.UseName(m_poolName)
.Build();
}

public MySqlConnection OpenConnection() => m_dataSource!.OpenConnection();
public string PoolName => m_poolName ?? m_connectionStringBuilder!.GetConnectionString(includePassword: false);
public override string ToString() => $"DataSource: {m_poolName ?? "(unnamed)"}";
public void Dispose() => m_dataSource!.Dispose();

private readonly string? m_poolName = poolName;
private MySqlConnectionStringBuilder? m_connectionStringBuilder;
private MySqlDataSource? m_dataSource;
}

internal sealed class PlainConnectionCreator : IConnectionCreator
{
public MySqlConnection OpenConnection()
{
var connection = new MySqlConnection(m_connectionStringBuilder!.ConnectionString);
connection.Open();
return connection;
}

public void SetConnectionStringBuilder(MySqlConnectionStringBuilder connectionStringBuilder) => m_connectionStringBuilder = connectionStringBuilder;
public string PoolName => m_connectionStringBuilder!.GetConnectionString(includePassword: false);
public override string ToString() => "Plain";
public void Dispose() { }

private MySqlConnectionStringBuilder? m_connectionStringBuilder;
}
2 changes: 1 addition & 1 deletion tests/MySqlConnector.Tests/MySqlConnector.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<AssemblyOriginatorKeyFile>..\..\MySqlConnector.snk</AssemblyOriginatorKeyFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>11.0</LangVersion>
<LangVersion>12.0</LangVersion>
</PropertyGroup>

<PropertyGroup Condition=" '$(GITHUB_ACTIONS)' == 'true' OR '$(APPVEYOR)' == 'True' OR '$(TF_BUILD)' == 'True' ">
Expand Down

0 comments on commit 19fb8e5

Please sign in to comment.