From f6b30d9b2ba0662934bb65e64c9139327c985aa4 Mon Sep 17 00:00:00 2001 From: Freek Gruntjes Date: Fri, 10 Nov 2023 10:17:36 +0100 Subject: [PATCH 1/4] Added test case for race condition when building test server #134 * Added graphql-aspnet-testframework-tests project with TestServerBuilderTests --- src/graphql-aspnet.sln | 6 +++ .../GlobalSuppressions.cs | 40 ++++++++++++++++ .../TestServerBuilderTests.cs | 47 +++++++++++++++++++ .../graphql-aspnet-testframework-tests.csproj | 37 +++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 src/unit-tests/graphql-aspnet-testframework-tests/GlobalSuppressions.cs create mode 100644 src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs create mode 100644 src/unit-tests/graphql-aspnet-testframework-tests/graphql-aspnet-testframework-tests.csproj diff --git a/src/graphql-aspnet.sln b/src/graphql-aspnet.sln index 22cdbb2e4..d3a72dd9c 100644 --- a/src/graphql-aspnet.sln +++ b/src/graphql-aspnet.sln @@ -36,6 +36,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "starwars-api70", "ancillary EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "graphql-aspnet-tests-common", "unit-tests\graphql-aspnet-tests-common\graphql-aspnet-tests-common.csproj", "{3CB086E3-5E7B-438B-9A95-AEA264009521}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "graphql-aspnet-testframework-tests", "unit-tests\graphql-aspnet-testframework-tests\graphql-aspnet-testframework-tests.csproj", "{E67D4FB2-73FF-4EC1-80F8-5D4DEC57F5AA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -79,6 +81,10 @@ Global {3CB086E3-5E7B-438B-9A95-AEA264009521}.Debug|Any CPU.Build.0 = Debug|Any CPU {3CB086E3-5E7B-438B-9A95-AEA264009521}.Release|Any CPU.ActiveCfg = Release|Any CPU {3CB086E3-5E7B-438B-9A95-AEA264009521}.Release|Any CPU.Build.0 = Release|Any CPU + {E67D4FB2-73FF-4EC1-80F8-5D4DEC57F5AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E67D4FB2-73FF-4EC1-80F8-5D4DEC57F5AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E67D4FB2-73FF-4EC1-80F8-5D4DEC57F5AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E67D4FB2-73FF-4EC1-80F8-5D4DEC57F5AA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/unit-tests/graphql-aspnet-testframework-tests/GlobalSuppressions.cs b/src/unit-tests/graphql-aspnet-testframework-tests/GlobalSuppressions.cs new file mode 100644 index 000000000..23073b202 --- /dev/null +++ b/src/unit-tests/graphql-aspnet-testframework-tests/GlobalSuppressions.cs @@ -0,0 +1,40 @@ +// ************************************************************* +// project: graphql-aspnet +// -- +// repo: https://github.com/graphql-aspnet +// docs: https://graphql-aspnet.github.io +// -- +// License: MIT +// ************************************************************* + +using System.Diagnostics.CodeAnalysis; + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage( + "StyleCop.CSharp.DocumentationRules", + "SA1600:Elements should be documented", + Justification = "Documenting test methods is unwarranted at this time.", + Scope = "module")] + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage( + "StyleCop.CSharp.NamingRules", + "SA1313:Parameter names should begin with lower-case letter", + Justification = "Testing of Alternative Naming schemas is required for unit tests", + Scope = "module")] + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage( + "StyleCop.CSharp.NamingRules", + "SA1300:Element should begin with upper-case letter", + Justification = "Testing of Alternative Naming schemas is required for unit tests", + Scope = "module")] + +[assembly: SuppressMessage( + "Design", + "CA1065:Do not raise exceptions in unexpected locations", + Justification = "Test Project exceptions are for testing only", + Scope = "module")] + +[assembly: SuppressMessage( + "Design", + "CA1063:Implement IDisposable Correctly", + Justification = "Proper IDisposable not necessary for unit test project", + Scope = "module")] \ No newline at end of file diff --git a/src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs b/src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs new file mode 100644 index 000000000..0bd0b75c9 --- /dev/null +++ b/src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs @@ -0,0 +1,47 @@ +namespace GraphQL.AspNet.TestFramework.Tests +{ + using System.Threading.Tasks; + using GraphQL.AspNet.Attributes; + using GraphQL.AspNet.Controllers; + using GraphQL.AspNet.Schemas; + using GraphQL.AspNet.Tests.Framework; + using NUnit.Framework; + + [TestFixture] + public class TestServerBuilderTests + { + [Test] + public void ParallelBuildSameControllerTest() + { + Task.WaitAll( + Task.Run(BuildServer), + Task.Run(BuildServer), + Task.Run(BuildServer), + Task.Run(BuildServer), + Task.Run(BuildServer)); + } + + [GraphRoute("with-param")] + public class AppController : GraphController + { + [Query("get")] + public string Get(string id) + { + return id; + } + } + + private void BuildServer() + where T : GraphController + { + var builder = new TestServerBuilder(); + + builder.AddGraphQL(options => + { + options.AddController(); + }); + + builder.Build(); + } + } +} \ No newline at end of file diff --git a/src/unit-tests/graphql-aspnet-testframework-tests/graphql-aspnet-testframework-tests.csproj b/src/unit-tests/graphql-aspnet-testframework-tests/graphql-aspnet-testframework-tests.csproj new file mode 100644 index 000000000..7c072d4b2 --- /dev/null +++ b/src/unit-tests/graphql-aspnet-testframework-tests/graphql-aspnet-testframework-tests.csproj @@ -0,0 +1,37 @@ + + + + net7.0;net6.0; + latest + $(NoWarn);1701;1702;1705;1591;NU1603;RCS1021;IDE0060;IDE0052;IDE0044;IDE0059;IDE0052;IDE0017;IDE0039;RCS1090;RCS1118;SA1601;RCS1163 + GraphQL.AspNet.TestFramework.Tests + graphql-aspnet-testframework-tests + true + true + false + + + + ..\..\styles.ruleset + + + + + + + + + + + + + + + + + + + + + + From b0464c1da3d3ba6c435bf6d336c6e89bc8530675 Mon Sep 17 00:00:00 2001 From: Freek Gruntjes Date: Fri, 10 Nov 2023 11:07:03 +0100 Subject: [PATCH 2/4] Bug fix: Race condition when building using multiple build servers (#134) * Ensure the SchemaItemPath.EnsurePathInitialized() method is only setting _pathInitialized when path is fully initialized. --- src/graphql-aspnet/Schemas/Structural/SchemaItemPath.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/graphql-aspnet/Schemas/Structural/SchemaItemPath.cs b/src/graphql-aspnet/Schemas/Structural/SchemaItemPath.cs index c3ce06bc9..dafe15709 100644 --- a/src/graphql-aspnet/Schemas/Structural/SchemaItemPath.cs +++ b/src/graphql-aspnet/Schemas/Structural/SchemaItemPath.cs @@ -87,7 +87,6 @@ private void EnsurePathInitialized() if (_pathInitialized) return; - _pathInitialized = true; var workingPath = SchemaItemPath.NormalizeFragment(this.Raw); // split the path into its fragments @@ -137,7 +136,7 @@ private void EnsurePathInitialized() } // ensure each fragment matches the naming specification - foreach (var fragment in pathFragments.Skip(this.RootCollection == SchemaItemCollections.Unknown ? 0 : 1)) + foreach (var fragment in pathFragments.Skip(_rootCollection == SchemaItemCollections.Unknown ? 0 : 1)) { if (!this.ValidateFragment(fragment)) return; @@ -147,9 +146,10 @@ private void EnsurePathInitialized() if (pathFragments.Count > 1) _parentField = new SchemaItemPath(string.Join(RouteConstants.PATH_SEPERATOR, pathFragments.Take(pathFragments.Count - 1))); - _isTopLevelField = pathFragments.Count == 1 || (pathFragments.Count == 2 && this.RootCollection > SchemaItemCollections.Unknown); // e.g. "[query]/name" - _isValid = this.Name.Length > 0; + _isTopLevelField = pathFragments.Count == 1 || (pathFragments.Count == 2 && _rootCollection > SchemaItemCollections.Unknown); // e.g. "[query]/name" + _isValid = _name.Length > 0; _path = this.GeneratePathString(pathFragments); + _pathInitialized = true; } } From 285275328cb0af52259df210c0076aae004d7114 Mon Sep 17 00:00:00 2001 From: Freek Gruntjes Date: Mon, 13 Nov 2023 15:51:20 +0100 Subject: [PATCH 3/4] Moved graphql-aspnet-testframework-tests to unit-tests solution folder --- src/graphql-aspnet.sln | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphql-aspnet.sln b/src/graphql-aspnet.sln index d3a72dd9c..9168d8d3c 100644 --- a/src/graphql-aspnet.sln +++ b/src/graphql-aspnet.sln @@ -98,6 +98,7 @@ Global {6E4A16F5-1B98-412E-9A88-F56301F5D0E4} = {350D3594-5D97-4D9B-A01D-D3A5C036318C} {B92A5C91-F88D-4F26-8775-20C72692BD43} = {22C7BC5B-EC8E-4A07-9968-961E86AB44E2} {3CB086E3-5E7B-438B-9A95-AEA264009521} = {350D3594-5D97-4D9B-A01D-D3A5C036318C} + {E67D4FB2-73FF-4EC1-80F8-5D4DEC57F5AA} = {350D3594-5D97-4D9B-A01D-D3A5C036318C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DD2C38B8-B029-4DE1-877E-B1A661AC412F} From 96da0ea48633d96349d091bed8077209b7b04f6f Mon Sep 17 00:00:00 2001 From: Freek Gruntjes Date: Mon, 13 Nov 2023 16:05:05 +0100 Subject: [PATCH 4/4] Fixed linting errors in graphql-aspnet-testframework-tests/TestServerBuilderTests.cs --- .../TestServerBuilderTests.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs b/src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs index 0bd0b75c9..ea427215a 100644 --- a/src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs +++ b/src/unit-tests/graphql-aspnet-testframework-tests/TestServerBuilderTests.cs @@ -1,3 +1,12 @@ +// ************************************************************* +// project: graphql-aspnet +// -- +// repo: https://github.com/graphql-aspnet +// docs: https://graphql-aspnet.github.io +// -- +// License: MIT +// ************************************************************* + namespace GraphQL.AspNet.TestFramework.Tests { using System.Threading.Tasks; @@ -43,5 +52,5 @@ private void BuildServer() builder.Build(); } - } + } } \ No newline at end of file