Skip to content

Commit

Permalink
adds test suite for data-convert (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
runeanielsen authored Dec 15, 2021
1 parent e8b5a43 commit d552f05
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 8 deletions.
9 changes: 9 additions & 0 deletions msssql-cdc.sln
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{5D
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "examples\Example\Example.csproj", "{7DC5DA8F-274F-4586-97F4-490E0F12AE09}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E9EECC5D-1729-4F68-B525-BD7CEE63BC05}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MsSqlCdc.Tests", "test\MsSqlCdc.Tests\MsSqlCdc.Tests.csproj", "{B9FA94EC-6E90-43CA-ACB6-D5BE12AB90AF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -28,9 +32,14 @@ Global
{7DC5DA8F-274F-4586-97F4-490E0F12AE09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7DC5DA8F-274F-4586-97F4-490E0F12AE09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DC5DA8F-274F-4586-97F4-490E0F12AE09}.Release|Any CPU.Build.0 = Release|Any CPU
{B9FA94EC-6E90-43CA-ACB6-D5BE12AB90AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9FA94EC-6E90-43CA-ACB6-D5BE12AB90AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9FA94EC-6E90-43CA-ACB6-D5BE12AB90AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9FA94EC-6E90-43CA-ACB6-D5BE12AB90AF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5349AA55-B231-44AA-B411-97590DB9BA49} = {69F94C69-D4A8-4347-BCF6-A28CA7A2EBA4}
{7DC5DA8F-274F-4586-97F4-490E0F12AE09} = {5DFEC30A-0E3B-42CA-A0EA-6743821DE000}
{B9FA94EC-6E90-43CA-ACB6-D5BE12AB90AF} = {E9EECC5D-1729-4F68-B525-BD7CEE63BC05}
EndGlobalSection
EndGlobal
2 changes: 1 addition & 1 deletion src/MsSqlCdc/ChangeData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace MsSqlCdc;

public enum Operation : ushort
public enum Operation
{
Delete = 1,
Insert = 2,
Expand Down
18 changes: 11 additions & 7 deletions src/MsSqlCdc/DataConvert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ public static class DataConvert
/// <summary>
/// Converts a a colection of columns represented as Tuple<string, object> to ChangeData<dynamic> representation.
/// </summary>
/// <param name="column">List of tuples with Item1 being the name column and Item2 being the column value</param>
/// <param name="columnFields">List of tuples with Item1 being the name column and Item2 being the column value</param>
/// <param name="captureInstance">The tablename of the column.</param>
/// <returns>Returns the CDC column as a ChangeData record.</returns>
public static ChangeData<dynamic> ConvertCdcColumn(List<Tuple<string, object>> column, string captureInstance)
/// <exception cref="Exception"></exception>
public static ChangeData<dynamic> ConvertCdcColumn(List<Tuple<string, object>> columnFields, string captureInstance)
{
var startLsn = ConvertBinaryLsn((byte[])column[0].Item2);
var seqVal = ConvertBinaryLsn((byte[])column[1].Item2);
var operation = ConvertIntOperation((int)column[2].Item2);
var updateMask = Encoding.UTF8.GetString((byte[])column[3].Item2);
if (columnFields.Count < 3)
throw new Exception($"Count of column fields should be 4 or greater, instead got '{columnFields.Count}'.");

var body = column.Skip(4)
var startLsn = ConvertBinaryLsn((byte[])columnFields[0].Item2);
var seqVal = ConvertBinaryLsn((byte[])columnFields[1].Item2);
var operation = ConvertIntOperation((int)columnFields[2].Item2);
var updateMask = Encoding.UTF8.GetString((byte[])columnFields[3].Item2);

var body = columnFields.Skip(4)
.Aggregate(new ExpandoObject() as IDictionary<string, object>,
(acc, x) => { acc[x.Item1] = x.Item2; return acc; }) as dynamic;

Expand Down
105 changes: 105 additions & 0 deletions test/MsSqlCdc.Tests/DataConvertTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Xunit;
using FluentAssertions;
using static FluentAssertions.FluentActions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using FluentAssertions.Execution;

namespace MsSqlCdc.Tests;

public class DataConverTest
{
[Theory]
[InlineData(25000L, 25002L, Operation.AfterUpdate, "ABB", 10, "Rune", 20000.00)]
[InlineData(25L, 25202L, Operation.BeforeUpdate, "DSDFS", 2, "Simon", 0.00)]
[InlineData(250000000L, 250021L, Operation.Delete, "DFS", 3, "Foo", 1000000000.00)]
[InlineData(0L, 2L, Operation.Insert, "DFS", 3, "John", 1000000000.00)]
public void ConvertCdcColumn_ShouldReturnChangeData_OnValidInput(
long startLsn,
long seqVal,
Operation operation,
string updateMask,
int id,
string name,
double salary)
{
var captureInstance = "dbo_Employee";
var columnFields = new List<Tuple<string, object>>
{
new Tuple<string, object>("__$start_lsn", BitConverter.GetBytes(startLsn).Reverse().ToArray()),
new Tuple<string, object>("__$seqval", BitConverter.GetBytes(seqVal).Reverse().ToArray()),
new Tuple<string, object>("__$operation", (int)operation),
new Tuple<string, object>("__$update_mask", Encoding.ASCII.GetBytes(updateMask)),
new Tuple<string, object>("Id", id),
new Tuple<string, object>("Name", name),
new Tuple<string, object>("Salary", salary),
};

var changeData = new ChangeData<dynamic>(
startLsn,
seqVal,
operation,
updateMask,
"dbo_Employee",
new
{
Id = id,
Name = name,
Salary = salary,
}
);

var result = DataConvert.ConvertCdcColumn(columnFields, captureInstance);

using (var scope = new AssertionScope())
{
Assert.True(result.Body.Id == changeData.Body.Id);
Assert.True(result.Body.Name == changeData.Body.Name);
Assert.True(result.Body.Salary == changeData.Body.Salary);
result.StartLineSequenceNumber.Should().Be(changeData.StartLineSequenceNumber);
result.SequenceValue.Should().Be(changeData.SequenceValue);
result.Operation.Should().Be(changeData.Operation);
result.UpdateMask.Should().Be(changeData.UpdateMask);
}
}

[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(2)]
[InlineData(3)]
public void ConvertCdcColumn_ShouldThrowException_OnColumnFieldsBeingLessThanFour(int columnFieldsCount)
{
var captureInstance = "dbo_Employee";

var columnFields = Enumerable.Range(0, columnFieldsCount)
.Select(x => new Tuple<string, object>(x.ToString(), x)).ToList();

Invoking(() => DataConvert.ConvertCdcColumn(columnFields, captureInstance)).Should().Throw<Exception>();
}

[Theory]
[InlineData(1, Operation.Delete)]
[InlineData(2, Operation.Insert)]
[InlineData(3, Operation.BeforeUpdate)]
[InlineData(4, Operation.AfterUpdate)]
public void ConvertIntOperation_ShouldReturnCorrectEnumConvertion(int input, Operation expected)
{
var operation = DataConvert.ConvertIntOperation(input);
operation.Should().Be(expected);
}

[Theory]
[InlineData(-1)]
[InlineData(-10)]
[InlineData(0)]
[InlineData(100)]
[InlineData(int.MinValue)]
[InlineData(int.MaxValue)]
public void ConvertIntOperation_ShouldThrowException_OnInvalidIntRepresentation(int input)
{
Invoking(() => DataConvert.ConvertIntOperation(input)).Should().Throw<ArgumentException>();
}
}
28 changes: 28 additions & 0 deletions test/MsSqlCdc.Tests/MsSqlCdc.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\MsSqlCdc\MsSqlCdc.csproj" />
</ItemGroup>

</Project>

0 comments on commit d552f05

Please sign in to comment.