- 
                Notifications
    You must be signed in to change notification settings 
- Fork 2.1k
A basic test suite for orleans source generator #9459
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
Changes from 9 commits
5c5a5c8
              ddadf63
              4775e2c
              10875e8
              9c17ea9
              caa08ab
              f05bc26
              8333591
              e997945
              3966717
              7231869
              b5ff9be
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -214,3 +214,9 @@ src/SetupTestScriptOutput.txt | |
|  | ||
| # VS Code | ||
| .ionide/ | ||
|  | ||
| # Verify.Xunit | ||
| *.received.* | ||
|  | ||
| # code coverage | ||
| *.cobertura.xml | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|  | ||
| <PropertyGroup> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| <OrleansBuildTimeCodeGen>true</OrleansBuildTimeCodeGen> | ||
| <TargetFrameworks>$(TestTargetFrameworks)</TargetFrameworks> | ||
| </PropertyGroup> | ||
|  | ||
| <PropertyGroup> | ||
| <CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled> | ||
| <xUnitVersion>2.9.3</xUnitVersion> | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. due to the dependency on xunit.extensibility.execution see https://www.nuget.org/packages/Verify.Xunit/28.15.0#dependencies-body-tab could we upgrade the xunit versions in this repo? (maybe separate PR) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we can upgrade xUnit - either in this PR or a separate PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a separate PR would be better, are we still supporting netcoreapp3.1? There are some conditions there, we'll discuss this in the new PR for xunit upgrades There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We support it just for the code generator... we will drop it at some point (maybe for the .NET 10 release). It's ok if tests don't cover it. | ||
| <CollectCoverage>true</CollectCoverage> | ||
| <CoverletOutputFormat>cobertura</CoverletOutputFormat> | ||
| <Include>[Orleans.CodeGenerator]*</Include> | ||
| </PropertyGroup> | ||
|  | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" /> | ||
| <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" /> | ||
| <PackageReference Include="xunit" /> | ||
| <PackageReference Include="xunit.runner.visualstudio" /> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" /> | ||
| </ItemGroup> | ||
|  | ||
| <ItemGroup> | ||
| <!-- due to Verify.Xunit requiring newer versions of these libraries --> | ||
| <PackageReference Include="coverlet.msbuild"> | ||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
| <PrivateAssets>all</PrivateAssets> | ||
| </PackageReference> | ||
| <PackageReference Include="System.IO.Hashing" VersionOverride="9.0.3" /> | ||
| <PackageReference Include="System.CodeDom" VersionOverride="9.0.2" /> | ||
| <PackageReference Include="Verify.Xunit" /> | ||
| <Compile Remove="snapshots\**\*" /> | ||
| <None Include="snapshots\**\*" /> | ||
| </ItemGroup> | ||
|  | ||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\src\Orleans.CodeGenerator\Orleans.CodeGenerator.csproj" /> | ||
| <ProjectReference Include="..\..\src\Orleans.Sdk\Orleans.Sdk.csproj" /> | ||
| <ProjectReference Include="..\..\src\Orleans.Runtime\Orleans.Runtime.csproj" /> | ||
| </ItemGroup> | ||
|  | ||
|  | ||
|  | ||
| </Project> | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| using Microsoft.CodeAnalysis; | ||
| using Microsoft.CodeAnalysis.CSharp; | ||
| using Microsoft.CodeAnalysis.Testing; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Orleans.Serialization; | ||
| using Xunit; | ||
|  | ||
| namespace Orleans.CodeGenerator.Tests; | ||
|  | ||
| public class OrleansSourceGeneratorTests | ||
| { | ||
| [Fact] | ||
| public async Task TestBasicClass() | ||
| { | ||
| var projectName = "TestProject"; | ||
| var compilation = await CreateCompilation( | ||
| @"using Orleans; | ||
|  | ||
| namespace TestProject; | ||
|  | ||
| [Serializable, GenerateSerializer] | ||
| public class DemoData | ||
| { | ||
| [Id(0)] | ||
| public string Value { get; set; } = string.Empty; | ||
| } | ||
| ", projectName); | ||
|  | ||
| var generator = new OrleansSerializationSourceGenerator(); | ||
|  | ||
| GeneratorDriver driver = CSharpGeneratorDriver.Create( | ||
| generators: [generator], | ||
| driverOptions: new GeneratorDriverOptions(default)); | ||
|  | ||
| // Run the generator | ||
| driver = driver.RunGenerators(compilation); | ||
|  | ||
| var result = driver.GetRunResult().Results.Single(); | ||
| Assert.Empty(result.Diagnostics); | ||
|  | ||
| Assert.Single(result.GeneratedSources); | ||
| Assert.Equal($"{projectName}.orleans.g.cs", result.GeneratedSources[0].HintName); | ||
| var generatedSource = result.GeneratedSources[0].SourceText.ToString(); | ||
|  | ||
| await Verify(generatedSource, extension: "cs").UseDirectory("snapshots"); | ||
| } | ||
|  | ||
| private static async Task<CSharpCompilation> CreateCompilation(string sourceCode, string assemblyName = "TestProject") | ||
| { | ||
| var references = await ReferenceAssemblies.Net.Net80.ResolveAsync(LanguageNames.CSharp, default); | ||
|  | ||
| // Add the Orleans Orleans.Core.Abstractions assembly | ||
| references = references.AddRange( | ||
| // Orleans.Core.Abstractions | ||
| MetadataReference.CreateFromFile(typeof(GrainId).Assembly.Location), | ||
| // Orleans.Core | ||
| MetadataReference.CreateFromFile(typeof(IClusterClientLifecycle).Assembly.Location), | ||
| // Orleans.Runtime | ||
| MetadataReference.CreateFromFile(typeof(IGrainActivator).Assembly.Location), | ||
| // Orleans.Serialization | ||
| MetadataReference.CreateFromFile(typeof(Serializer).Assembly.Location), | ||
| // Orleans.Serialization.Abstractions | ||
| MetadataReference.CreateFromFile(typeof(GenerateFieldIds).Assembly.Location), | ||
| // Microsoft.Extensions.DependencyInjection.Abstractions | ||
| MetadataReference.CreateFromFile(typeof(ActivatorUtilitiesConstructorAttribute).Assembly.Location) | ||
| ); | ||
|  | ||
| var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode); | ||
|  | ||
| return CSharpCompilation.Create(assemblyName, [syntaxTree], references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); | ||
| } | ||
| } | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| #pragma warning disable CS1591, RS0016, RS0041 | ||
|         
                  Meir017 marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| [assembly: global::Orleans.ApplicationPartAttribute("TestProject")] | ||
| [assembly: global::Orleans.ApplicationPartAttribute("Orleans.Core.Abstractions")] | ||
| [assembly: global::Orleans.ApplicationPartAttribute("Orleans.Serialization")] | ||
| [assembly: global::Orleans.ApplicationPartAttribute("Orleans.Core")] | ||
| [assembly: global::Orleans.ApplicationPartAttribute("Orleans.Runtime")] | ||
| [assembly: global::Orleans.Serialization.Configuration.TypeManifestProviderAttribute(typeof(OrleansCodeGen.TestProject.Metadata_TestProject))] | ||
| namespace OrleansCodeGen.TestProject | ||
| { | ||
| using global::Orleans.Serialization.Codecs; | ||
| using global::Orleans.Serialization.GeneratedCodeHelpers; | ||
|  | ||
| [global::System.CodeDom.Compiler.GeneratedCodeAttribute("OrleansCodeGen", "9.0.0.0"), global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never), global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute] | ||
| public sealed class Codec_DemoData : global::Orleans.Serialization.Codecs.IFieldCodec<global::TestProject.DemoData>, global::Orleans.Serialization.Serializers.IBaseCodec<global::TestProject.DemoData> | ||
| { | ||
| private readonly global::System.Type _codecFieldType = typeof(global::TestProject.DemoData); | ||
| [global::System.Runtime.CompilerServices.MethodImplAttribute(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | ||
| public void Serialize<TBufferWriter>(ref global::Orleans.Serialization.Buffers.Writer<TBufferWriter> writer, global::TestProject.DemoData instance) | ||
| where TBufferWriter : global::System.Buffers.IBufferWriter<byte> | ||
| { | ||
| global::Orleans.Serialization.Codecs.StringCodec.WriteField(ref writer, 0U, instance.Value); | ||
| } | ||
|  | ||
| [global::System.Runtime.CompilerServices.MethodImplAttribute(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | ||
| public void Deserialize<TReaderInput>(ref global::Orleans.Serialization.Buffers.Reader<TReaderInput> reader, global::TestProject.DemoData instance) | ||
| { | ||
| uint id = 0U; | ||
| global::Orleans.Serialization.WireProtocol.Field header = default; | ||
| while (true) | ||
| { | ||
| reader.ReadFieldHeader(ref header); | ||
| if (header.IsEndBaseOrEndObject) | ||
| break; | ||
| id += header.FieldIdDelta; | ||
| if (id == 0U) | ||
| { | ||
| instance.Value = global::Orleans.Serialization.Codecs.StringCodec.ReadValue(ref reader, header); | ||
| reader.ReadFieldHeader(ref header); | ||
| } | ||
|  | ||
| reader.ConsumeEndBaseOrEndObject(ref header); | ||
| break; | ||
| } | ||
| } | ||
|  | ||
| [global::System.Runtime.CompilerServices.MethodImplAttribute(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | ||
| public void WriteField<TBufferWriter>(ref global::Orleans.Serialization.Buffers.Writer<TBufferWriter> writer, uint fieldIdDelta, global::System.Type expectedType, global::TestProject.DemoData @value) | ||
| where TBufferWriter : global::System.Buffers.IBufferWriter<byte> | ||
| { | ||
| if (@value is null || @value.GetType() == typeof(global::TestProject.DemoData)) | ||
| { | ||
| if (ReferenceCodec.TryWriteReferenceField(ref writer, fieldIdDelta, expectedType, @value)) | ||
| return; | ||
| writer.WriteStartObject(fieldIdDelta, expectedType, _codecFieldType); | ||
| Serialize(ref writer, @value); | ||
| writer.WriteEndObject(); | ||
| } | ||
| else | ||
| writer.SerializeUnexpectedType(fieldIdDelta, expectedType, @value); | ||
| } | ||
|  | ||
| [global::System.Runtime.CompilerServices.MethodImplAttribute(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | ||
| public global::TestProject.DemoData ReadValue<TReaderInput>(ref global::Orleans.Serialization.Buffers.Reader<TReaderInput> reader, global::Orleans.Serialization.WireProtocol.Field field) | ||
| { | ||
| if (field.IsReference) | ||
| return ReferenceCodec.ReadReference<global::TestProject.DemoData, TReaderInput>(ref reader, field); | ||
| field.EnsureWireTypeTagDelimited(); | ||
| global::System.Type valueType = field.FieldType; | ||
| if (valueType is null || valueType == _codecFieldType) | ||
| { | ||
| var result = new global::TestProject.DemoData(); | ||
| ReferenceCodec.RecordObject(reader.Session, result); | ||
| Deserialize(ref reader, result); | ||
| return result; | ||
| } | ||
|  | ||
| return reader.DeserializeUnexpectedType<TReaderInput, global::TestProject.DemoData>(ref field); | ||
| } | ||
| } | ||
|  | ||
| [global::System.CodeDom.Compiler.GeneratedCodeAttribute("OrleansCodeGen", "9.0.0.0"), global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never), global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute] | ||
| public sealed class Copier_DemoData : global::Orleans.Serialization.Cloning.IDeepCopier<global::TestProject.DemoData>, global::Orleans.Serialization.Cloning.IBaseCopier<global::TestProject.DemoData> | ||
| { | ||
| [global::System.Runtime.CompilerServices.MethodImplAttribute(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | ||
| public global::TestProject.DemoData DeepCopy(global::TestProject.DemoData original, global::Orleans.Serialization.Cloning.CopyContext context) | ||
| { | ||
| if (context.TryGetCopy(original, out global::TestProject.DemoData existing)) | ||
| return existing; | ||
| if (original.GetType() != typeof(global::TestProject.DemoData)) | ||
| return context.DeepCopy(original); | ||
| var result = new global::TestProject.DemoData(); | ||
| context.RecordCopy(original, result); | ||
| DeepCopy(original, result, context); | ||
| return result; | ||
| } | ||
|  | ||
| [global::System.Runtime.CompilerServices.MethodImplAttribute(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] | ||
| public void DeepCopy(global::TestProject.DemoData input, global::TestProject.DemoData output, global::Orleans.Serialization.Cloning.CopyContext context) | ||
| { | ||
| output.Value = input.Value; | ||
| } | ||
| } | ||
|  | ||
| [global::System.CodeDom.Compiler.GeneratedCodeAttribute("OrleansCodeGen", "9.0.0.0"), global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never), global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute] | ||
| internal sealed class Activator_DemoData : global::Orleans.Serialization.Activators.IActivator<global::TestProject.DemoData> | ||
| { | ||
| public global::TestProject.DemoData Create() => new global::TestProject.DemoData(); | ||
| } | ||
|  | ||
| [global::System.CodeDom.Compiler.GeneratedCodeAttribute("OrleansCodeGen", "9.0.0.0"), global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never), global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute] | ||
| internal sealed class Metadata_TestProject : global::Orleans.Serialization.Configuration.TypeManifestProviderBase | ||
| { | ||
| protected override void ConfigureInner(global::Orleans.Serialization.Configuration.TypeManifestOptions config) | ||
| { | ||
| config.Serializers.Add(typeof(OrleansCodeGen.TestProject.Codec_DemoData)); | ||
| config.Copiers.Add(typeof(OrleansCodeGen.TestProject.Copier_DemoData)); | ||
| config.Activators.Add(typeof(OrleansCodeGen.TestProject.Activator_DemoData)); | ||
| } | ||
| } | ||
| } | ||
| #pragma warning restore CS1591, RS0016, RS0041 | ||
Uh oh!
There was an error while loading. Please reload this page.