Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Test
run: |
cd tests/SuperSocket.MySQL.Test
dotnet test
dotnet test --logger "console;verbosity=detailed"
- name: Pack
run: dotnet pack -c Release -p:PackageVersion=${{ steps.nbgv.outputs.NuGetPackageVersion }}.${{ github.run_number }} -p:Version=${{ steps.nbgv.outputs.NuGetPackageVersion }}.${{ github.run_number }} -p:AssemblyVersion=${{ steps.nbgv.outputs.AssemblyVersion }} -p:AssemblyFileVersion=${{ steps.nbgv.outputs.AssemblyFileVersion }} -p:AssemblyInformationalVersion=${{ steps.nbgv.outputs.AssemblyInformationalVersion }} /p:NoPackageAnalysis=true /p:IncludeReleaseNotes=false
- name: Push
Expand Down
7 changes: 4 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="SuperSocket.Client" Version="2.0.2" />
<PackageVersion Include="SuperSocket.ProtoBase" Version="2.0.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageVersion Include="xunit" Version="2.4.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="xunit.v3" Version="1.0.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageVersion Include="Meziantou.Extensions.Logging.Xunit.v3" Version="1.0.0" />
</ItemGroup>
</Project>
10 changes: 6 additions & 4 deletions src/SuperSocket.MySQL/MySQLConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class MySQLConnection : EasyClient<MySQLPacket>
private readonly MySQLFilterContext filterContext;

public MySQLConnection(string host, int port, string userName, string password, ILogger logger = null)
: this(new MySQLPacketFilter(MySQLPacketDecoder.ClientInstance), logger)
: this(new MySQLPacketFilter(new MySQLPacketDecoder(MySQLPacketFactory.ClientInstance, logger)), logger)
{
_host = host ?? throw new ArgumentNullException(nameof(host));
_port = port > 0 ? port : DefaultPort;
Expand Down Expand Up @@ -67,9 +67,10 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
// Prepare handshake response
var handshakeResponse = new HandshakeResponsePacket
{
CapabilityFlags = (uint)(ClientCapabilities.CLIENT_PROTOCOL_41 |
ClientCapabilities.CLIENT_SECURE_CONNECTION |
ClientCapabilities.CLIENT_PLUGIN_AUTH),
CapabilityFlags = (uint)(ClientCapabilities.CLIENT_PROTOCOL_41
| ClientCapabilities.CLIENT_SECURE_CONNECTION
| ClientCapabilities.CLIENT_PLUGIN_AUTH
| ClientCapabilities.CLIENT_DEPRECATE_EOF),
MaxPacketSize = 16777216, // 16MB
CharacterSet = 0x21, // utf8_general_ci
Username = _userName,
Expand Down Expand Up @@ -100,6 +101,7 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
? errorPacket.ErrorMessage
: "Authentication failed";
throw new InvalidOperationException($"MySQL authentication failed: {errorMsg} (Error {errorPacket.ErrorCode})");

case EOFPacket eofPacket:
// EOF packet received, check if it indicates success
if ((eofPacket.StatusFlags & 0x0002) != 0)
Expand Down
13 changes: 6 additions & 7 deletions src/SuperSocket.MySQL/MySQLPacketDecoder.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
using System;
using System.Buffers;
using System.IO;
using Microsoft.Extensions.Logging;
using SuperSocket.ProtoBase;

namespace SuperSocket.MySQL
{
internal class MySQLPacketDecoder : IPackageDecoder<MySQLPacket>
{
public static MySQLPacketDecoder ClientInstance { get; }
static MySQLPacketDecoder()
{
ClientInstance = new MySQLPacketDecoder(MySQLPacketFactory.ClientInstance);
}

private readonly ILogger _logger;
private readonly IMySQLPacketFactory _packetFactory;

private MySQLPacketDecoder(IMySQLPacketFactory packetFactory)
public MySQLPacketDecoder(IMySQLPacketFactory packetFactory, ILogger logger)
{
_packetFactory = packetFactory ?? throw new ArgumentNullException(nameof(packetFactory));
this._logger = logger;
}

public MySQLPacket Decode(ref ReadOnlySequence<byte> buffer, object context)
Expand All @@ -44,6 +41,8 @@ public MySQLPacket Decode(ref ReadOnlySequence<byte> buffer, object context)
packetType = (int)packetTypeByte;
}

_logger?.LogDebug("Decoding MySQL packet with sequence ID {SequenceId} and type {PacketType}", sequenceId, packetType);

var package = _packetFactory.Create(packetType);

package = package.Decode(ref reader, context);
Expand Down
15 changes: 11 additions & 4 deletions tests/SuperSocket.MySQL.Test/MainTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
try
{
// Act
await connection.ConnectAsync();

Check warning on line 21 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)

// Assert
Assert.True(connection.IsAuthenticated, "Connection should be authenticated after successful handshake");
Expand All @@ -37,12 +37,19 @@
var connection = new MySQLConnection(TestConst.Host, TestConst.DefaultPort, "invalid_user", "invalid_password");

// Act & Assert
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
async () => await connection.ConnectAsync()
);
Exception exception = null;

try
{
await connection.ConnectAsync();

Check warning on line 44 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)
}
catch (Exception e)
{
exception = e;
}

Assert.Contains("authentication failed", exception.Message.ToLower());
Assert.False(connection.IsAuthenticated, "Connection should not be authenticated after failed handshake");
Assert.NotNull(exception);
}

[Fact]
Expand All @@ -54,7 +61,7 @@
try
{
// Act
await connection.ConnectAsync();

Check warning on line 64 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)

// Assert
// This test depends on your MySQL server configuration
Expand Down Expand Up @@ -84,8 +91,8 @@
try
{
// Act
await connection1.ConnectAsync();

Check warning on line 94 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)
await connection2.ConnectAsync();

Check warning on line 95 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)

// Assert
Assert.True(connection1.IsAuthenticated, "First connection should be authenticated");
Expand All @@ -104,7 +111,7 @@
{
// Arrange
var connection = new MySQLConnection(TestConst.Host, TestConst.DefaultPort, TestConst.Username, TestConst.Password);
await connection.ConnectAsync();

Check warning on line 114 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)
Assert.True(connection.IsAuthenticated, "Precondition: Connection should be authenticated");

// Act
Expand Down Expand Up @@ -148,7 +155,7 @@
var connection = new MySQLConnection("invalid-host-that-does-not-exist", TestConst.DefaultPort, TestConst.Username, TestConst.Password);

// Act & Assert
await Assert.ThrowsAnyAsync<Exception>(async () => await connection.ConnectAsync());

Check warning on line 158 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)
Assert.False(connection.IsAuthenticated, "Connection should not be authenticated when host is invalid");
}

Expand All @@ -159,7 +166,7 @@
var connection = new MySQLConnection(TestConst.Host, 12345, TestConst.Username, TestConst.Password);

// Act & Assert
await Assert.ThrowsAnyAsync<Exception>(async () => await connection.ConnectAsync());

Check warning on line 169 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)
Assert.False(connection.IsAuthenticated, "Connection should not be authenticated when port is invalid");
}

Expand All @@ -171,7 +178,7 @@

// Act & Assert
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
async () => await connection.ExecuteQueryAsync("SELECT 1")

Check warning on line 181 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)
);

Assert.Contains("not authenticated", exception.Message);
Expand All @@ -182,7 +189,7 @@
{
// Arrange
var connection = new MySQLConnection(TestConst.Host, TestConst.DefaultPort, TestConst.Username, TestConst.Password);
await connection.ConnectAsync();

Check warning on line 192 in tests/SuperSocket.MySQL.Test/MainTest.cs

View workflow job for this annotation

GitHub Actions / build

Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive. (https://xunit.net/xunit.analyzers/rules/xUnit1051)

try
{
Expand Down
14 changes: 13 additions & 1 deletion tests/SuperSocket.MySQL.Test/MySQLIntegrationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Threading.Tasks;
using Xunit;
using SuperSocket.MySQL;
using Microsoft.Extensions.Logging;
using Meziantou.Extensions.Logging.Xunit.v3;

namespace SuperSocket.MySQL.Test
{
Expand All @@ -12,6 +14,13 @@ namespace SuperSocket.MySQL.Test
/// </summary>
public class MySQLIntegrationTest
{
private protected readonly ITestOutputHelper outputHelper;

public MySQLIntegrationTest(ITestOutputHelper outputHelper)
{
this.outputHelper = outputHelper;
}

[Fact]
[Trait("Category", "Integration")]
public async Task MySQLConnection_CompleteHandshakeFlow_ShouldAuthenticate()
Expand Down Expand Up @@ -40,7 +49,10 @@ public async Task MySQLConnection_CompleteHandshakeFlow_ShouldAuthenticate()
public async Task MySQLConnection_InvalidCredentials_ShouldFailHandshake()
{
// Arrange
var connection = new MySQLConnection(TestConst.Host, TestConst.DefaultPort, "nonexistent_user", "wrong_password");
var loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new XUnitLoggerProvider(this.outputHelper));

var connection = new MySQLConnection(TestConst.Host, TestConst.DefaultPort, "nonexistent_user", "wrong_password", loggerFactory.CreateLogger(nameof(MySQLConnection_InvalidCredentials_ShouldFailHandshake)));

// Act & Assert
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
Expand Down
1 change: 0 additions & 1 deletion tests/SuperSocket.MySQL.Test/QueryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Threading.Tasks;
using SuperSocket.MySQL.Packets;
using Xunit;
using Xunit.Abstractions;

namespace SuperSocket.MySQL.Test
{
Expand Down
3 changes: 2 additions & 1 deletion tests/SuperSocket.MySQL.Test/SuperSocket.MySQL.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.v3" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="Meziantou.Extensions.Logging.Xunit.v3" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
</ItemGroup>
Expand Down
Loading