diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb00c3e..980ba6c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 diff --git a/Directory.Packages.props b/Directory.Packages.props index 507f27a..816f7ad 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,10 +6,11 @@ - - - + + + + \ No newline at end of file diff --git a/src/SuperSocket.MySQL/MySQLConnection.cs b/src/SuperSocket.MySQL/MySQLConnection.cs index 993ee61..0568da3 100644 --- a/src/SuperSocket.MySQL/MySQLConnection.cs +++ b/src/SuperSocket.MySQL/MySQLConnection.cs @@ -30,7 +30,7 @@ public class MySQLConnection : EasyClient 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; @@ -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, @@ -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) diff --git a/src/SuperSocket.MySQL/MySQLPacketDecoder.cs b/src/SuperSocket.MySQL/MySQLPacketDecoder.cs index da58266..ac5a5d6 100644 --- a/src/SuperSocket.MySQL/MySQLPacketDecoder.cs +++ b/src/SuperSocket.MySQL/MySQLPacketDecoder.cs @@ -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 { - 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 buffer, object context) @@ -44,6 +41,8 @@ public MySQLPacket Decode(ref ReadOnlySequence 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); diff --git a/tests/SuperSocket.MySQL.Test/MainTest.cs b/tests/SuperSocket.MySQL.Test/MainTest.cs index 00e1b13..24c2274 100644 --- a/tests/SuperSocket.MySQL.Test/MainTest.cs +++ b/tests/SuperSocket.MySQL.Test/MainTest.cs @@ -37,12 +37,19 @@ public async Task ConnectAsync_WithInvalidCredentials_ShouldThrowException() var connection = new MySQLConnection(TestConst.Host, TestConst.DefaultPort, "invalid_user", "invalid_password"); // Act & Assert - var exception = await Assert.ThrowsAsync( - async () => await connection.ConnectAsync() - ); + Exception exception = null; + + try + { + await connection.ConnectAsync(); + } + 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] diff --git a/tests/SuperSocket.MySQL.Test/MySQLIntegrationTest.cs b/tests/SuperSocket.MySQL.Test/MySQLIntegrationTest.cs index d0381a1..363f4d3 100644 --- a/tests/SuperSocket.MySQL.Test/MySQLIntegrationTest.cs +++ b/tests/SuperSocket.MySQL.Test/MySQLIntegrationTest.cs @@ -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 { @@ -12,6 +14,13 @@ namespace SuperSocket.MySQL.Test /// 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() @@ -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( diff --git a/tests/SuperSocket.MySQL.Test/QueryTest.cs b/tests/SuperSocket.MySQL.Test/QueryTest.cs index 139a56e..4a3a03c 100644 --- a/tests/SuperSocket.MySQL.Test/QueryTest.cs +++ b/tests/SuperSocket.MySQL.Test/QueryTest.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using SuperSocket.MySQL.Packets; using Xunit; -using Xunit.Abstractions; namespace SuperSocket.MySQL.Test { diff --git a/tests/SuperSocket.MySQL.Test/SuperSocket.MySQL.Test.csproj b/tests/SuperSocket.MySQL.Test/SuperSocket.MySQL.Test.csproj index 3996e48..f6b8061 100644 --- a/tests/SuperSocket.MySQL.Test/SuperSocket.MySQL.Test.csproj +++ b/tests/SuperSocket.MySQL.Test/SuperSocket.MySQL.Test.csproj @@ -7,8 +7,9 @@ - + +