diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5d80e8f..68fe8ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,7 @@ jobs: runs-on: windows-latest steps: - name: Set up JDK 17 + if: github.repository == 'KxSystems/csharpkdb' uses: actions/setup-java@v5 with: java-version: 17 @@ -30,12 +31,14 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - name: Cache SonarQube Cloud packages + if: github.repository == 'KxSystems/csharpkdb' uses: actions/cache@v5 with: path: ~\sonar\cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache SonarQube Cloud scanner + if: github.repository == 'KxSystems/csharpkdb' id: cache-sonar-scanner uses: actions/cache@v5 with: @@ -43,13 +46,13 @@ jobs: key: ${{ runner.os }}-sonar-scanner restore-keys: ${{ runner.os }}-sonar-scanner - name: Install SonarQube Cloud scanner - if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' + if: github.repository == 'KxSystems/csharpkdb' && steps.cache-sonar-scanner.outputs.cache-hit != 'true' shell: powershell run: | New-Item -Path ${{ runner.temp }}\scanner -ItemType Directory dotnet tool update dotnet-sonarscanner --tool-path ${{ runner.temp }}\scanner - name: SonarQube Cloud scanner begin - if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && env.SONAR_TOKEN != '') }} + if: github.repository == 'KxSystems/csharpkdb' && (github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && env.SONAR_TOKEN != '')) run: ${{ runner.temp }}\scanner\dotnet-sonarscanner begin /k:"KxSystems_csharpkdb" /o:"kxsystems" /d:sonar.token="$env:SONAR_TOKEN" /d:sonar.cs.vstest.reportsPaths="**\TestResults\*.trx" /d:sonar.cs.opencover.reportsPaths="*\coverage.net8.0.opencover.xml" /d:sonar.verbose=false /d:sonar.exclusions="kx.Test/Scripts/GenerateLocalReport.ps1" - name: Build run : dotnet build /p:Configuration=Release .\CSharpKdb.sln @@ -60,5 +63,5 @@ jobs: - name: Test .NET 8 run: dotnet test .\kx.Test\kx.Test.csproj -c Release -f net8.0 --no-build --logger:trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover - name: SonarQube Cloud scanner finish - if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && env.SONAR_TOKEN != '') }} + if: github.repository == 'KxSystems/csharpkdb' && (github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && env.SONAR_TOKEN != '')) run: ${{ runner.temp }}\scanner\dotnet-sonarscanner end /d:sonar.token="$env:SONAR_TOKEN" diff --git a/kx.Test/Connection/ConnectionSerialisationTests.cs b/kx.Test/Connection/ConnectionSerialisationTests.cs index 6bf03be..b8655bc 100644 --- a/kx.Test/Connection/ConnectionSerialisationTests.cs +++ b/kx.Test/Connection/ConnectionSerialisationTests.cs @@ -1124,6 +1124,107 @@ public void ConnectionDeserialisesBigEndianIntArrayInput() } } + [Test] + public void ConnectionDeserialisesBigEndianShortArrayInput() + { + short[] expected = { 0x0102, -2, short.MaxValue, short.MinValue }; + byte[] message = CreateBigEndianList( + 5, + expected.Length, + 0x01, 0x02, + 0xff, 0xfe, + 0x7f, 0xff, + 0x80, 0x00); + + using (var connection = new c(_testVersionNumber)) + { + short[] result = connection.Deserialize(message) as short[]; + + Assert.IsNotNull(result); + Assert.IsTrue(Enumerable.SequenceEqual(expected, result)); + } + } + + [Test] + public void ConnectionDeserialisesBigEndianLongArrayInput() + { + long[] expected = { 0x0102030405060708L, -2L }; + byte[] message = CreateBigEndianList( + 7, + expected.Length, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe); + + using (var connection = new c(_testVersionNumber)) + { + long[] result = connection.Deserialize(message) as long[]; + + Assert.IsNotNull(result); + Assert.IsTrue(Enumerable.SequenceEqual(expected, result)); + } + } + + [Test] + public void ConnectionDeserialisesBigEndianFloatArrayInput() + { + float[] expected = { 47.25F, -1.5F }; + byte[] message = CreateBigEndianList( + 8, + expected.Length, + GetBigEndianBytes(expected[0]), + GetBigEndianBytes(expected[1])); + + using (var connection = new c(_testVersionNumber)) + { + float[] result = connection.Deserialize(message) as float[]; + + Assert.IsNotNull(result); + Assert.IsTrue(Enumerable.SequenceEqual(expected, result)); + } + } + + [Test] + public void ConnectionDeserialisesBigEndianDoubleArrayInput() + { + double[] expected = { 47.25, -1.5 }; + byte[] message = CreateBigEndianList( + 9, + expected.Length, + GetBigEndianBytes(expected[0]), + GetBigEndianBytes(expected[1])); + + using (var connection = new c(_testVersionNumber)) + { + double[] result = connection.Deserialize(message) as double[]; + + Assert.IsNotNull(result); + Assert.IsTrue(Enumerable.SequenceEqual(expected, result)); + } + } + + [Test] + public void ConnectionDeserialisesLegacyDatetimeArrayInput() + { + DateTime[] expected = + { + new DateTime(2000, 1, 2, 12, 0, 0, DateTimeKind.Unspecified), + new DateTime(1999, 12, 31, 0, 0, 0, DateTimeKind.Unspecified) + }; + byte[] message = CreateBigEndianList( + 15, + expected.Length, + GetBigEndianBytes(1.5), + GetBigEndianBytes(-1.0)); + + using (var connection = new c(_testVersionNumber)) + { + DateTime[] result = connection.Deserialize(message) as DateTime[]; + + Assert.IsNotNull(result); + Assert.IsTrue(Enumerable.SequenceEqual(expected, result)); + } + } + [Test] public void ConnectionDeserialisesLegacyDatetimeInput() { @@ -1190,6 +1291,23 @@ public void ConnectionDeserialisesGenericNull() } } + [Test] + public void ConnectionDeserialisesUnknownListTypeAsNull() + { + byte[] message = CreateLittleEndianMessage( + 1, + 20, // unsupported list type + 0, // attributes + 0, 0, 0, 0); // empty list + + using (var connection = new c(_testVersionNumber)) + { + object result = connection.Deserialize(message); + + Assert.IsNull(result); + } + } + [Test] public void ConnectionThrowsKExceptionForUnsupportedFunction() { @@ -1331,5 +1449,49 @@ private static byte[] CreateBigEndianMessage( return message; } + + private static byte[] CreateBigEndianList( + byte type, + int count, + params byte[][] values) + { + return CreateBigEndianList(type, count, values.SelectMany(value => value).ToArray()); + } + + private static byte[] CreateBigEndianList( + byte type, + int count, + params byte[] values) + { + byte[] payload = new byte[6 + values.Length]; + payload[0] = type; + payload[1] = 0; + payload[2] = (byte)(count >> 24); + payload[3] = (byte)(count >> 16); + payload[4] = (byte)(count >> 8); + payload[5] = (byte)count; + Buffer.BlockCopy(values, 0, payload, 6, values.Length); + + return CreateBigEndianMessage(1, payload); + } + + private static byte[] GetBigEndianBytes(float value) + { + return ToBigEndian(BitConverter.GetBytes(value)); + } + + private static byte[] GetBigEndianBytes(double value) + { + return ToBigEndian(BitConverter.GetBytes(value)); + } + + private static byte[] ToBigEndian(byte[] value) + { + if (BitConverter.IsLittleEndian) + { + Array.Reverse(value); + } + return value; + } } }