Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C# endianness fixes #1964

Merged
merged 12 commits into from
Nov 20, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<RootNamespace>SpacetimeDB</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CsCheck" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../BSATN.Runtime/BSATN.Runtime.csproj" />
</ItemGroup>

</Project>
142 changes: 142 additions & 0 deletions crates/bindings-csharp/BSATN.Runtime.Tests/Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
namespace SpacetimeDB;

using CsCheck;
using Xunit;

public static class BSATNRuntimeTests
{
[Fact]
public static void AddressRoundtrips()
{
var str = "00112233445566778899AABBCCDDEEFF";
kazimuth marked this conversation as resolved.
Show resolved Hide resolved
var addr = Address.FromHexString(str);

Assert.NotNull(addr);
Assert.Equal(addr.ToString(), str);

var bytes = Convert.FromHexString(str);

var addr2 = Address.FromBigEndian(bytes);
Assert.Equal(addr2, addr);

Array.Reverse(bytes);
var addr3 = Address.From(bytes);
Assert.Equal(addr3, addr);

var memoryStream = new MemoryStream();
var bsatn = new Address.BSATN();
using (var writer = new BinaryWriter(memoryStream))
{
if (addr is { } addrNotNull)
{
bsatn.Write(writer, addrNotNull);
}
else
{
Assert.Fail("Impossible");
}
}

var littleEndianBytes = memoryStream.ToArray();
var reader = new BinaryReader(new MemoryStream(littleEndianBytes));
var addr4 = bsatn.Read(reader);
Assert.Equal(addr4, addr);

// Note: From = FromLittleEndian
var addr5 = Address.From(littleEndianBytes);
Assert.Equal(addr5, addr);
}

static readonly Gen<string> genHex = Gen.String[Gen.Char["0123456789abcdef"], 0, 128];

[Fact]
public static void AddressLengthCheck()
{
genHex.Sample(s =>
{
if (s.Length == 32)
{
return;
}
Assert.ThrowsAny<Exception>(() => Address.FromHexString(s));
});
Gen.Byte.Array[0, 64]
.Sample(arr =>
{
if (arr.Length == 16)
{
return;
}
Assert.ThrowsAny<Exception>(() => Address.FromBigEndian(arr));
Assert.ThrowsAny<Exception>(() => Address.From(arr));
});
}

[Fact]
public static void IdentityRoundtrips()
{
var str = "00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF";
var ident = Identity.FromHexString(str);

Assert.Equal(ident.ToString(), str);

// We can't use this in the implementation because it isn't available
// in Unity's .NET. But we can use it in tests.
var bytes = Convert.FromHexString(str);

var ident2 = Identity.FromBigEndian(bytes);
Assert.Equal(ident2, ident);

Array.Reverse(bytes);
var ident3 = Identity.From(bytes);
Assert.Equal(ident3, ident);

var memoryStream = new MemoryStream();
var bsatn = new Identity.BSATN();
using (var writer = new BinaryWriter(memoryStream))
{
bsatn.Write(writer, ident);
}

var littleEndianBytes = memoryStream.ToArray();
var reader = new BinaryReader(new MemoryStream(littleEndianBytes));
var ident4 = bsatn.Read(reader);
Assert.Equal(ident4, ident);

// Note: From = FromLittleEndian
var ident5 = Identity.From(littleEndianBytes);
Assert.Equal(ident5, ident);
}

[Fact]
public static void IdentityLengthCheck()
kazimuth marked this conversation as resolved.
Show resolved Hide resolved
{
genHex.Sample(s =>
{
if (s.Length == 64)
{
return;
}
Assert.ThrowsAny<Exception>(() => Identity.FromHexString(s));
});
Gen.Byte.Array[0, 64]
.Sample(arr =>
{
if (arr.Length == 32)
{
return;
}
Assert.ThrowsAny<Exception>(() => Identity.FromBigEndian(arr));
Assert.ThrowsAny<Exception>(() => Identity.From(arr));
});
}

[Fact]
public static void NonHexStrings()
{
// n.b. 32 chars long
Assert.ThrowsAny<Exception>(
() => Address.FromHexString("these are not hex characters....")
);
}
}
Loading
Loading