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

chore: implement integration testing #124

Merged
merged 42 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5aac445
some setup
DeagleGross Jul 28, 2024
74115ec
make it build and execute without AOT
DeagleGross Jul 28, 2024
db947b6
at this moment - i dont know
DeagleGross Jul 28, 2024
1f46429
minimal assembly references
DeagleGross Aug 1, 2024
72db8ac
bump packages and then it does not work still...
DeagleGross Aug 1, 2024
dd2914f
do it iteratively
DeagleGross Aug 1, 2024
6622ce8
move pieces around
DeagleGross Aug 1, 2024
5854b98
make it work with executable assembly!
DeagleGross Aug 1, 2024
eac14e3
omg it works.
DeagleGross Aug 1, 2024
4eec1c3
use existing local machine table name
DeagleGross Aug 1, 2024
0a7d0de
record stack traces
DeagleGross Aug 1, 2024
fca1675
remove package versions
DeagleGross Aug 1, 2024
a059484
refactor dependencies
DeagleGross Aug 1, 2024
a642e60
YES!!! YES!!! YES!!! YES!!! YES!!! YES!!! YES!!!
DeagleGross Aug 1, 2024
3dede81
fix dbstring global namespace + adjust test for DbString
DeagleGross Aug 1, 2024
d3cfa7f
and run tests for new proj
DeagleGross Aug 1, 2024
4a3ea61
last minute review
DeagleGross Aug 1, 2024
fb04933
rollback package updates (they break tests)
DeagleGross Aug 2, 2024
237d55e
remove coverlet collector
DeagleGross Aug 2, 2024
1b405e6
use sln
DeagleGross Aug 3, 2024
6e9f7c1
internal visible to
DeagleGross Aug 3, 2024
5bf27d1
try specific routes
DeagleGross Aug 3, 2024
45bd482
dont build it
DeagleGross Aug 3, 2024
23065ae
try with ubuntu agents
DeagleGross Aug 3, 2024
ac7b910
rollback CI\CD + create another for integrations on ubuntu
DeagleGross Aug 3, 2024
b312ca1
fix for dbstring + rename CI
DeagleGross Aug 7, 2024
b6eb088
debug test
DeagleGross Aug 9, 2024
ea09276
fix naming
DeagleGross Aug 9, 2024
fae081f
try publish directory
DeagleGross Aug 9, 2024
ae69d7b
move item group
DeagleGross Aug 9, 2024
1dd69c7
get logs from build
DeagleGross Aug 9, 2024
bf2d64d
maybe slash can fix it?
DeagleGross Aug 9, 2024
1da057b
remove detailed verbosity
DeagleGross Aug 9, 2024
35b6bd9
.
DeagleGross Aug 9, 2024
5e379ce
always?
DeagleGross Aug 10, 2024
436e611
test on wsl
DeagleGross Aug 10, 2024
ea553ba
build only test proj
DeagleGross Aug 10, 2024
17f53c8
move it to integration directly
DeagleGross Aug 10, 2024
9c4fbf5
give me logs
DeagleGross Aug 10, 2024
b8d55cb
dont use copy at all
DeagleGross Aug 10, 2024
93cb89a
cleanup debug CI
DeagleGross Aug 10, 2024
0120385
move to csproj
DeagleGross Aug 23, 2024
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
32 changes: 32 additions & 0 deletions .github/workflows/dotnet-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Integration Tests

on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:

runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # depth is needed for nbgv

- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: |
6.0.x
8.0.x
include-prerelease: true

- name: Build
run: dotnet build Dapper.AOT.sln -c Debug

- name: E2E Tests
run: dotnet test test/Dapper.AOT.Test.Integration/Dapper.AOT.Test.Integration.csproj --no-build --verbosity normal -c Debug
74 changes: 37 additions & 37 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,40 @@ jobs:
runs-on: windows-latest

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # depth is needed for nbgv
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: |
6.0.x
8.0.x
include-prerelease: true
- uses: dotnet/nbgv@master
with:
setAllVars: true

- name: Restore dependencies
run: dotnet restore Build.csproj

- name: Purge
run: del src/Dapper.*/bin/Release/Dapper.*.nupkg
- name: Build
run: dotnet build Build.csproj --no-restore -c Release

- name: Test
run: dotnet test Build.csproj --no-build --verbosity normal -c Release -f net6.0 --filter FullyQualifiedName!~Integration

- name: Pack
if: ${{ success() && !github.base_ref }}
run: dotnet pack src/Dapper.AOT/Dapper.AOT.csproj --no-build --verbosity normal -c Release

- name: Push to MyGet
if: ${{ success() && !github.base_ref }}
run: dotnet nuget push src/Dapper.*/bin/Release/Dapper.*.nupkg --source https://www.myget.org/F/dapper/api/v2/package --api-key "$env:MYGETAPIKEY"
env:
MYGETAPIKEY: ${{ secrets.MYGETAPIKEY }}
- uses: actions/checkout@v2
with:
fetch-depth: 0 # depth is needed for nbgv

- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: |
6.0.x
8.0.x
include-prerelease: true

- uses: dotnet/nbgv@master
with:
setAllVars: true

- name: Restore dependencies
run: dotnet restore Build.csproj

- name: Purge
run: del src/Dapper.*/bin/Release/Dapper.*.nupkg

- name: Build
run: dotnet build Build.csproj --no-restore -c Release

- name: Test
run: dotnet test Build.csproj --no-build --verbosity normal -c Release -f net6.0 --filter FullyQualifiedName!~Integration

- name: Pack
if: ${{ success() && !github.base_ref }}
run: dotnet pack src/Dapper.AOT/Dapper.AOT.csproj --no-build --verbosity normal -c Release

- name: Push to MyGet
if: ${{ success() && !github.base_ref }}
run: dotnet nuget push src/Dapper.*/bin/Release/Dapper.*.nupkg --source https://www.myget.org/F/dapper/api/v2/package --api-key "$env:MYGETAPIKEY"
env:
MYGETAPIKEY: ${{ secrets.MYGETAPIKEY }}
15 changes: 15 additions & 0 deletions Dapper.AOT.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props
.github\workflows\dotnet.yml = .github\workflows\dotnet.yml
.github\workflows\dotnet-integration.yml = .github\workflows\dotnet-integration.yml
global.json = global.json
nuget.config = nuget.config
README.md = README.md
Expand All @@ -40,6 +41,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs", "docs\docs.csproj",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UsageVanilla", "test\UsageVanilla\UsageVanilla.csproj", "{840EA1CA-62FF-409E-89F5-CD3BB269BAE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper.AOT.Test.Integration.Executables", "test\Dapper.AOT.Test.Integration.Executables\Dapper.AOT.Test.Integration.Executables.csproj", "{9FA6A3B4-5722-40B2-8B58-F418F5D8C9A8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper.AOT.Test.Integration", "test\Dapper.AOT.Test.Integration\Dapper.AOT.Test.Integration.csproj", "{CAB51448-4F0D-497B-A035-2B7ACB2DD9EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -78,6 +83,14 @@ Global
{840EA1CA-62FF-409E-89F5-CD3BB269BAE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{840EA1CA-62FF-409E-89F5-CD3BB269BAE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{840EA1CA-62FF-409E-89F5-CD3BB269BAE3}.Release|Any CPU.Build.0 = Release|Any CPU
{9FA6A3B4-5722-40B2-8B58-F418F5D8C9A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FA6A3B4-5722-40B2-8B58-F418F5D8C9A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FA6A3B4-5722-40B2-8B58-F418F5D8C9A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FA6A3B4-5722-40B2-8B58-F418F5D8C9A8}.Release|Any CPU.Build.0 = Release|Any CPU
{CAB51448-4F0D-497B-A035-2B7ACB2DD9EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CAB51448-4F0D-497B-A035-2B7ACB2DD9EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CAB51448-4F0D-497B-A035-2B7ACB2DD9EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CAB51448-4F0D-497B-A035-2B7ACB2DD9EB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -91,6 +104,8 @@ Global
{A77B633C-573E-43CD-85A4-8063B33143B4} = {FE215D4B-811B-47BB-9F05-6382DD1C6729}
{C6527566-38F4-43CC-9E0E-91C4B8854774} = {1135D4FD-770E-41DF-920B-A8F75E42A832}
{840EA1CA-62FF-409E-89F5-CD3BB269BAE3} = {9A846B95-90CE-4335-9043-48C5B8EA4FB8}
{9FA6A3B4-5722-40B2-8B58-F418F5D8C9A8} = {9A846B95-90CE-4335-9043-48C5B8EA4FB8}
{CAB51448-4F0D-497B-A035-2B7ACB2DD9EB} = {9A846B95-90CE-4335-9043-48C5B8EA4FB8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A89CDAFA-494F-4168-9648-1138BA738D43}
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.7.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="1.1.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="1.1.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0" />
<!-- 4.8 would be nice, but: let's try to offer down-level compiler support -->
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="[4.4.0]" />
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic.Analyzer.Testing.XUnit" Version="1.1.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using static Dapper.Internal.Inspection;
Expand All @@ -26,12 +25,33 @@ namespace Dapper.CodeAnalysis;
[Generator(LanguageNames.CSharp), DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed partial class DapperInterceptorGenerator : InterceptorGeneratorBase
{
private readonly bool _withInterceptionRecording = false;

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => DiagnosticsBase.All<Diagnostics>();

#pragma warning disable CS0067 // unused; retaining for now
public event Action<string>? Log;
#pragma warning restore CS0067

/// <summary>
/// Creates an interceptor generator for Dapper
/// </summary>
public DapperInterceptorGenerator()
{
}

/// <summary>
/// Creates an interceptor generator for Dapper used for Tests.
/// </summary>
/// <note>
/// It will insert very specific call with known method name.
/// Users will not have a reference to inserted assembly code, therefore: don't make it public
/// </note>
internal DapperInterceptorGenerator(bool withInterceptionRecording)
{
_withInterceptionRecording = withInterceptionRecording;
}

public override void Initialize(IncrementalGeneratorInitializationContext context)
{
var nodes = context.SyntaxProvider.CreateSyntaxProvider(PreFilter, Parse)
Expand Down Expand Up @@ -360,6 +380,13 @@ internal void Generate(in GenerateState ctx)

sb.NewLine();

if (_withInterceptionRecording)
{
sb.Append("// record interception for tests assertions").NewLine();
sb.Append("global::Dapper.AOT.Test.Integration.Executables.Recording.InterceptorRecorderResolver.Resolve().Record();").NewLine();
sb.NewLine();
}

if (flags.HasAny(OperationFlags.GetRowParser))
{
WriteGetRowParser(sb, resultType, readers);
Expand Down
4 changes: 4 additions & 0 deletions src/Dapper.AOT.Analyzers/Dapper.AOT.Analyzers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@
<DependentUpon>DapperAnalyzer.cs</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="Dapper.AOT.Test.Integration, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a17ba361da0990b3da23f3c20f2a002242397b452a28f27832d61d49f35edb54a68b98d98557b8a02be79be42142339c7861af309c8917dee972775e2c358dd6b96109a9147987652b25b8dc52e7f61f22a755831674f0a3cea17bef9abb6b23ef1856a02216864a1ffbb04a4c549258d32ba740fe141dad2f298a8130ea56d0" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/Dapper.AOT.Analyzers/Internal/Inspection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ public DapperSpecialType DapperSpecialType
ContainingNamespace:
{
Name: "Dapper",
IsGlobalNamespace: true
ContainingNamespace.IsGlobalNamespace: true
}
}) return DapperSpecialType.DbString;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net6.0;net48</TargetFrameworks>
<RootNamespace>Dapper.AOT.Test.Integration.Executables</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" Condition="'$(TargetFramework)' == 'net6.0'" />
<PackageReference Include="Dapper.StrongName" Condition="'$(TargetFramework)'=='net48'" />
<PackageReference Include="Dapper" Condition="'$(TargetFramework)' == 'net8.0'" />

<ProjectReference Include="..\..\src\Dapper.AOT.Analyzers\Dapper.AOT.Analyzers.csproj" />
<ProjectReference Include="..\..\src\Dapper.AOT\Dapper.AOT.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Dapper.AOT.Test.Integration.Executables.Recording;
using Dapper.CodeAnalysis;

namespace Dapper.AOT.Test.Integration.Executables;

public class ExceptedCodeInterceptorRecorder<TExecutable> : IInterceptorRecorder
{
readonly string expectedFileName;

public ExceptedCodeInterceptorRecorder(string expectedFileName)
{
this.expectedFileName = expectedFileName ?? throw new ArgumentNullException(nameof(expectedFileName));
}

public bool WasCalled { get; private set; }
public string? Diagnostics { get; private set; }

public void Record()
{
WasCalled = true;
var diagnostics = new StringBuilder();

var stackTrace = new StackTrace(fNeedFileInfo: true);
var recentFrames = stackTrace.GetFrames().Take(15).ToList(); // we dont need everything

var userCodeFrameIndex = recentFrames.FindIndex(frame =>
frame.GetFileName()?.Contains(expectedFileName) == true && frame.GetMethod()?.Name.Equals(nameof(IExecutable<TExecutable>.Execute)) == true);
if (userCodeFrameIndex == -1)
{
diagnostics.AppendLine("- User code execution is not found");
}

var dapperInterceptionFrameIndex = recentFrames.FindIndex(frame =>
frame.GetFileName()?.Contains(".generated.cs") == true && frame.GetFileName()?.Contains(nameof(DapperInterceptorGenerator)) == true);
if (dapperInterceptionFrameIndex == -1)
{
diagnostics.AppendLine("- User code execution is not found");
}

if (userCodeFrameIndex < dapperInterceptionFrameIndex)
{
diagnostics.AppendLine("- User code call should be higher (executed before) on the stack trace than intercepted code");
}

Diagnostics = diagnostics.ToString();
}
}
8 changes: 8 additions & 0 deletions test/Dapper.AOT.Test.Integration.Executables/IExecutable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Data;

namespace Dapper.AOT.Test.Integration.Executables;

public interface IExecutable<T>
{
public T Execute(IDbConnection connection);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Dapper.AOT.Test.Integration.Executables.Models;

public class DbStringPoco
{
public const string TableName = "dbStringPoco";

public int Id { get; set; }
public string Name { get; set; }

Check warning on line 8 in test/Dapper.AOT.Test.Integration.Executables/Models/DbStringPoco.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 8 in test/Dapper.AOT.Test.Integration.Executables/Models/DbStringPoco.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 8 in test/Dapper.AOT.Test.Integration.Executables/Models/DbStringPoco.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 8 in test/Dapper.AOT.Test.Integration.Executables/Models/DbStringPoco.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 8 in test/Dapper.AOT.Test.Integration.Executables/Models/DbStringPoco.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 8 in test/Dapper.AOT.Test.Integration.Executables/Models/DbStringPoco.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Dapper.AOT.Test.Integration.Executables.Recording;

public interface IInterceptorRecorder
{
/// <summary>
/// returns true if expected interception was called
/// </summary>
public bool WasCalled { get; }

/// <summary>
/// Returns diagnostics of recording
/// </summary>
public string? Diagnostics { get; }

/// <summary>
/// Is executed in the interception
/// </summary>
public void Record();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Dapper.AOT.Test.Integration.Executables.Recording;

public static class InterceptorRecorderResolver
{
static IInterceptorRecorder? _recorder;

public static IInterceptorRecorder? Resolve() => _recorder;
public static void Register(IInterceptorRecorder? recorder) => _recorder = recorder;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Data;
using System.Linq;
using Dapper.AOT.Test.Integration.Executables.Models;

namespace Dapper.AOT.Test.Integration.Executables.UserCode;

[DapperAot]
public class DbStringUsage : IExecutable<DbStringPoco>
{
public DbStringPoco Execute(IDbConnection connection)
{
var results = connection.Query<DbStringPoco>(
$"select * from {DbStringPoco.TableName} where name = @name",
new
{
name = new DbString
{
Value = "my-dbString"
}
});
return results.First();
}
}
Loading
Loading