This is an automated email from the ASF dual-hosted git repository. mmartell pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/geode-native.git
The following commit(s) were added to refs/heads/develop by this push: new 620479a GEODE-9600: Add Cluster Support to NetCore Test Framework (#880) 620479a is described below commit 620479a5069a7c97956cdf46f2b0f69384ff6b94 Author: Michael Martell <mmart...@pivotal.io> AuthorDate: Tue Oct 12 08:44:25 2021 -0700 GEODE-9600: Add Cluster Support to NetCore Test Framework (#880) * Add cluster support to netcore-integration-test and netcore-session integration-test * Add top level solution for netcore * Add programmatic cluster files in shared folder for use by both test projects * Address Rat check issue: Add using statement to new Process * Remove gfsh based cluster scripts, now supported in cluster.cs, etc. * Update refs to Cluster.cs, etc. in project files * cmake configure Config.cs.in so environment vars are not required * Remove old netcore solution file * Cleanup per review: Geode .Net Core, not .net Core --- netcore/CMakeLists.txt | 1 + netcore/geode-dotnet-core.sln | 56 --- netcore/netcore-integration-test/CMakeLists.txt | 27 -- .../netcore-integration-test/CacheFactoryTest.cs | 12 +- netcore/netcore-integration-test/CacheTest.cs | 4 +- .../NetCoreCollectionFixture.cs | 2 +- netcore/netcore-integration-test/ObjectLeakTest.cs | 4 +- .../netcore-integration-test/PoolFactoryTest.cs | 4 +- .../netcore-integration-test/PoolManagerTest.cs | 4 +- .../netcore-integration-test/RegionFactoryTest.cs | 60 ++- .../netcore-integration-test.csproj | 9 + .../CMakeLists.txt | 27 -- .../SessionStateIntegrationTests.cs | 336 ++++++++------ .../netcore-session-integration-test.csproj | 9 + netcore/netcore.sln | 49 ++ netcore/{ => shared}/CMakeLists.txt | 15 +- netcore/shared/Cluster.cs | 300 +++++++++++++ .../Config.cs.in} | 39 +- .../Framework.cs} | 33 +- netcore/shared/Gfsh.cs | 493 +++++++++++++++++++++ netcore/shared/GfshExecute.cs | 201 +++++++++ netcore/shared/TestBase.cs | 55 +++ 22 files changed, 1428 insertions(+), 312 deletions(-) diff --git a/netcore/CMakeLists.txt b/netcore/CMakeLists.txt index b5c3536..0caa268 100644 --- a/netcore/CMakeLists.txt +++ b/netcore/CMakeLists.txt @@ -24,5 +24,6 @@ if(DOTNET AND INCLUDE_DOTNET_CORE) add_subdirectory(netcore-integration-test) add_subdirectory(netcore-session-integration-test) add_subdirectory(utility) + add_subdirectory(shared) endif() diff --git a/netcore/geode-dotnet-core.sln b/netcore/geode-dotnet-core.sln deleted file mode 100644 index 83316b9..0000000 --- a/netcore/geode-dotnet-core.sln +++ /dev/null @@ -1,56 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30001.183 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore", "netcore\netcore.csproj", "{09ABBCE7-B217-43F1-A51B-CC5BDCD8EE98}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore-integration-test", "netcore-integration-test\netcore-integration-test.csproj", "{501DEA7E-8985-42A8-8BC9-C073E1B6DFE0}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Session", "Session", "{520C96EC-F929-4365-8D78-CC5785419B62}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore-session", "netcore-session\netcore-session.csproj", "{B88C58EB-B144-403B-85F7-7A5B45E643E3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore-session-integration-test", "netcore-session-integration-test\netcore-session-integration-test.csproj", "{94D2CD59-A5F3-4504-BF01-0A3B95CE12B5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "asp-netcore-session-sample", "asp-netcore-session-sample\asp-netcore-session-sample.csproj", "{4E830BC8-D1CA-40AF-9C9C-D15E193C6585}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {09ABBCE7-B217-43F1-A51B-CC5BDCD8EE98}.Debug|x64.ActiveCfg = Debug|x64 - {09ABBCE7-B217-43F1-A51B-CC5BDCD8EE98}.Debug|x64.Build.0 = Debug|x64 - {09ABBCE7-B217-43F1-A51B-CC5BDCD8EE98}.Release|x64.ActiveCfg = Release|x64 - {09ABBCE7-B217-43F1-A51B-CC5BDCD8EE98}.Release|x64.Build.0 = Release|x64 - {501DEA7E-8985-42A8-8BC9-C073E1B6DFE0}.Debug|x64.ActiveCfg = Debug|x64 - {501DEA7E-8985-42A8-8BC9-C073E1B6DFE0}.Debug|x64.Build.0 = Debug|x64 - {501DEA7E-8985-42A8-8BC9-C073E1B6DFE0}.Release|x64.ActiveCfg = Release|x64 - {501DEA7E-8985-42A8-8BC9-C073E1B6DFE0}.Release|x64.Build.0 = Release|x64 - {B88C58EB-B144-403B-85F7-7A5B45E643E3}.Debug|x64.ActiveCfg = Debug|x64 - {B88C58EB-B144-403B-85F7-7A5B45E643E3}.Debug|x64.Build.0 = Debug|x64 - {B88C58EB-B144-403B-85F7-7A5B45E643E3}.Release|x64.ActiveCfg = Release|x64 - {B88C58EB-B144-403B-85F7-7A5B45E643E3}.Release|x64.Build.0 = Release|x64 - {94D2CD59-A5F3-4504-BF01-0A3B95CE12B5}.Debug|x64.ActiveCfg = Debug|x64 - {94D2CD59-A5F3-4504-BF01-0A3B95CE12B5}.Debug|x64.Build.0 = Debug|x64 - {94D2CD59-A5F3-4504-BF01-0A3B95CE12B5}.Release|x64.ActiveCfg = Release|x64 - {94D2CD59-A5F3-4504-BF01-0A3B95CE12B5}.Release|x64.Build.0 = Release|x64 - {4E830BC8-D1CA-40AF-9C9C-D15E193C6585}.Debug|x64.ActiveCfg = Debug|x64 - {4E830BC8-D1CA-40AF-9C9C-D15E193C6585}.Debug|x64.Build.0 = Debug|x64 - {4E830BC8-D1CA-40AF-9C9C-D15E193C6585}.Release|x64.ActiveCfg = Release|x64 - {4E830BC8-D1CA-40AF-9C9C-D15E193C6585}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {B88C58EB-B144-403B-85F7-7A5B45E643E3} = {520C96EC-F929-4365-8D78-CC5785419B62} - {94D2CD59-A5F3-4504-BF01-0A3B95CE12B5} = {520C96EC-F929-4365-8D78-CC5785419B62} - {4E830BC8-D1CA-40AF-9C9C-D15E193C6585} = {520C96EC-F929-4365-8D78-CC5785419B62} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {B30A49F0-1C96-4D6C-A222-0088B1D7FBBE} - EndGlobalSection -EndGlobal diff --git a/netcore/netcore-integration-test/CMakeLists.txt b/netcore/netcore-integration-test/CMakeLists.txt index 6756bcf..3b9c863 100644 --- a/netcore/netcore-integration-test/CMakeLists.txt +++ b/netcore/netcore-integration-test/CMakeLists.txt @@ -24,34 +24,7 @@ enable_testing() set(AUTH_OPTS "--J=-Dgemfire.security-username=server --J=-Dgemfire.security-password=server --classpath=$<SHELL_PATH:${CMAKE_CURRENT_BINARY_DIR}/../utility/netcore-utility.jar>") set(AUTH_LOCATOR_OPTS "${AUTH_OPTS} --J=-Dgemfire.security-manager=javaobject.SimpleSecurityManager") -add_test(NAME startclusters COMMAND ${Geode_gfsh_EXECUTABLE} - -e "start locator --name=locator --port=10334 --http-service-port=6060 --J=-Dgemfire.jmx-manager-port=1099" - -e "start server --name=server --server-port=0" - -e "create region --name=exampleRegion --type=PARTITION" - -e "create region --name=geodeSessionState --type=PARTITION" - -e "disconnect" - -e "start locator --name=auth_locator ${AUTH_LOCATOR_OPTS} --port=10335 --http-service-port=7070 --J=-Dgemfire.jmx-manager-port=2099" - -e "connect --locator=localhost[10335] --user=server --password=server" - -e "start server --name=auth_server ${AUTH_OPTS} --server-port=0" - -e "create region --name=authExampleRegion --type=PARTITION" - -e "create region --name=authGeodeSessionState --type=PARTITION") -add_test(NAME stopclusters - COMMAND ${Geode_gfsh_EXECUTABLE} - -e "connect --locator=localhost[10335] --user=server --password=server" - -e "stop server --name=auth_server" - -e "stop locator --name=auth_locator" - -e "connect --locator=localhost[10334]" - -e "stop server --name=server" - -e "stop locator --name=locator") -add_test(NAME remove_dirs - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/remove_dirs.cmake) - add_test(NAME netcore-test COMMAND dotnet test -c $<CONFIG> WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -set_tests_properties(startclusters PROPERTIES FIXTURES_SETUP geode) -set_tests_properties(netcore-test PROPERTIES FIXTURES_REQUIRED geode) -set_tests_properties(stopclusters PROPERTIES FIXTURES_CLEANUP geode) -set_tests_properties(remove_dirs PROPERTIES DEPENDS stopclusters) - diff --git a/netcore/netcore-integration-test/CacheFactoryTest.cs b/netcore/netcore-integration-test/CacheFactoryTest.cs index 442c825..18ae8d4 100644 --- a/netcore/netcore-integration-test/CacheFactoryTest.cs +++ b/netcore/netcore-integration-test/CacheFactoryTest.cs @@ -16,10 +16,16 @@ */ using System; using Xunit; +using Xunit.Abstractions; + +namespace Apache.Geode.Client.IntegrationTests +{ + [Collection("Geode .Net Core Collection")] + public class CacheFactoryTest : TestBase { + public CacheFactoryTest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + } -namespace Apache.Geode.Client { - [Collection("Geode .net Core Collection")] - public class CacheFactoryTest { [Fact] public void CreateFactoryNotNull() { using (var cacheFactory = CacheFactory.Create()) { diff --git a/netcore/netcore-integration-test/CacheTest.cs b/netcore/netcore-integration-test/CacheTest.cs index d06d2fd..f35d181 100644 --- a/netcore/netcore-integration-test/CacheTest.cs +++ b/netcore/netcore-integration-test/CacheTest.cs @@ -18,8 +18,8 @@ using System; using System.Net.Cache; using Xunit; -namespace Apache.Geode.Client { - [Collection("Geode .net Core Collection")] +namespace Apache.Geode.Client.IntegrationTests { + [Collection("Geode .Net Core Collection")] public class CacheTest { [Fact] public void ClientCacheGetPdxReadSerialized() { diff --git a/netcore/netcore-integration-test/NetCoreCollectionFixture.cs b/netcore/netcore-integration-test/NetCoreCollectionFixture.cs index d30833e..f2cf3ee 100644 --- a/netcore/netcore-integration-test/NetCoreCollectionFixture.cs +++ b/netcore/netcore-integration-test/NetCoreCollectionFixture.cs @@ -29,5 +29,5 @@ public class NetCoreCollectionFixture : IDisposable { Client client_; } -[CollectionDefinition("Geode .net Core Collection")] +[CollectionDefinition("Geode .Net Core Collection")] public class NetCoreCollection : ICollectionFixture<NetCoreCollectionFixture> {} diff --git a/netcore/netcore-integration-test/ObjectLeakTest.cs b/netcore/netcore-integration-test/ObjectLeakTest.cs index c1440f9..c87daee 100644 --- a/netcore/netcore-integration-test/ObjectLeakTest.cs +++ b/netcore/netcore-integration-test/ObjectLeakTest.cs @@ -17,8 +17,8 @@ using System; using Xunit; -namespace Apache.Geode.Client { - [Collection("Geode .net Core Collection")] +namespace Apache.Geode.Client.IntegrationTests { + [Collection("Geode .Net Core Collection")] public class ObjectLeakTest { [Fact] public void LeakCacheFactoryVerifyThrows() { diff --git a/netcore/netcore-integration-test/PoolFactoryTest.cs b/netcore/netcore-integration-test/PoolFactoryTest.cs index 668be53..1bbc02b 100644 --- a/netcore/netcore-integration-test/PoolFactoryTest.cs +++ b/netcore/netcore-integration-test/PoolFactoryTest.cs @@ -17,8 +17,8 @@ using System.Net.Cache; using Xunit; -namespace Apache.Geode.Client { - [Collection("Geode .net Core Collection")] +namespace Apache.Geode.Client.IntegrationTests { + [Collection("Geode .Net Core Collection")] public class PoolFactoryTest { [Fact] public void PoolFactoryAddLocatorAllObjectsNotNull() { diff --git a/netcore/netcore-integration-test/PoolManagerTest.cs b/netcore/netcore-integration-test/PoolManagerTest.cs index e33f53b..19e3ddd 100644 --- a/netcore/netcore-integration-test/PoolManagerTest.cs +++ b/netcore/netcore-integration-test/PoolManagerTest.cs @@ -17,8 +17,8 @@ using System.Net.Cache; using Xunit; -namespace Apache.Geode.Client { - [Collection("Geode .net Core Collection")] +namespace Apache.Geode.Client.IntegrationTests { + [Collection("Geode .Net Core Collection")] public class PoolManagerTest { [Fact] public void PoolManagerCreatePoolFactoryAllObjectsNotNull() { diff --git a/netcore/netcore-integration-test/RegionFactoryTest.cs b/netcore/netcore-integration-test/RegionFactoryTest.cs index 970109f..9f0e6d9 100644 --- a/netcore/netcore-integration-test/RegionFactoryTest.cs +++ b/netcore/netcore-integration-test/RegionFactoryTest.cs @@ -18,8 +18,9 @@ using System; using System.Collections.Generic; using System.Net.Cache; using Xunit; +using Xunit.Abstractions; -namespace Apache.Geode.Client { +namespace Apache.Geode.Client.IntegrationTests { public class SimpleAuthInitialize : IAuthInitialize { public Dictionary<string, string> GetCredentials() { Console.WriteLine("SimpleAuthInitialize::GetCredentials called"); @@ -34,8 +35,13 @@ namespace Apache.Geode.Client { } } - [Collection("Geode .net Core Collection")] - public class RegionFactoryTest { + [Collection("Geode .Net Core Collection")] + public class RegionFactoryTest : TestBase + { + public RegionFactoryTest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + } + private const string Username1 = "rtimmons"; private const string Username2 = "scharles"; @@ -82,25 +88,53 @@ namespace Apache.Geode.Client { [Fact] public void RegionFactoryCreateProxyRegionStringPutGet() { - using var cacheFactory = CacheFactory.Create() - .SetProperty("log-level", "debug") - .SetProperty("log-file", "geode_native.log"); - using var cache = cacheFactory.CreateCache(); - - createPool(cache, 10334); - CreateRegionAndDoWork(cache, "exampleRegion", RegionShortcut.Proxy); + using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) + { + Assert.True(cluster.Start()); + Assert.Equal(0, cluster.Gfsh + .create() + .region() + .withName("exampleRegion") + .withType("PARTITION") + .execute()); + + using var cacheFactory = CacheFactory.Create() + .SetProperty("log-level", "debug") + .SetProperty("log-file", "geode_native.log"); + using var cache = cacheFactory.CreateCache(); + + using var pool = cluster.ApplyLocators(cache.PoolFactory) + .CreatePool("myPool"); + + //int port = cluster. + //createPool(cache, 10334); + CreateRegionAndDoWork(cache, "exampleRegion", RegionShortcut.Proxy); + } } [Fact] public void RegionFactoryCreateRegionStringPutGetWithAuthentication() { - using var cacheFactory = CacheFactory.Create() + using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) + { + Assert.True(cluster.Start()); + Assert.Equal(0, cluster.Gfsh + .create() + .region() + .withName("authExampleRegion") + .withType("PARTITION") + .execute()); + + using var cacheFactory = CacheFactory.Create() .SetProperty("log-level", "debug") .SetProperty("log-file", "geode_native_with_auth.log"); cacheFactory.AuthInitialize = new SimpleAuthInitialize(); using var cache = cacheFactory.CreateCache(); - createPool(cache, 10335); - CreateRegionAndDoWork(cache, "authExampleRegion", RegionShortcut.CachingProxy); + using var pool = cluster.ApplyLocators(cache.PoolFactory) + .CreatePool("myPool"); + + CreateRegionAndDoWork(cache, "authExampleRegion", RegionShortcut.CachingProxy); + } } } } diff --git a/netcore/netcore-integration-test/netcore-integration-test.csproj b/netcore/netcore-integration-test/netcore-integration-test.csproj index 01fc77c..ac8be9a 100644 --- a/netcore/netcore-integration-test/netcore-integration-test.csproj +++ b/netcore/netcore-integration-test/netcore-integration-test.csproj @@ -8,6 +8,15 @@ </PropertyGroup> <ItemGroup> + <Compile Include="..\shared\Config.cs" Link="Config.cs" /> + <Compile Include="..\shared\Cluster.cs" Link="Cluster.cs" /> + <Compile Include="..\shared\Gfsh.cs" Link="Gfsh.cs" /> + <Compile Include="..\shared\Framework.cs" Link="Framework.cs" /> + <Compile Include="..\shared\GfshExecute.cs" Link="GfshExecute.cs" /> + <Compile Include="..\shared\TestBase.cs" Link="TestBase.cs" /> + </ItemGroup> + + <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> diff --git a/netcore/netcore-session-integration-test/CMakeLists.txt b/netcore/netcore-session-integration-test/CMakeLists.txt index 0b5e905..365cbe0 100644 --- a/netcore/netcore-session-integration-test/CMakeLists.txt +++ b/netcore/netcore-session-integration-test/CMakeLists.txt @@ -21,33 +21,6 @@ add_custom_target(netcore-session-integration-test ALL enable_testing() -add_test(NAME startclusters COMMAND ${Geode_gfsh_EXECUTABLE} - -e "start locator --name=locator --port=10334 --http-service-port=6060 --J=-Dgemfire.jmx-manager-port=1099" - -e "start server --name=server --server-port=0" - -e "create region --name=exampleRegion --type=PARTITION" - -e "create region --name=geodeSessionState --type=PARTITION" - -e "disconnect" - -e "start locator --name=auth_locator ${AUTH_LOCATOR_OPTS} --port=10335 --http-service-port=7070 --J=-Dgemfire.jmx-manager-port=2099" - -e "connect --locator=localhost[10335] --user=server --password=server" - -e "start server --name=auth_server ${AUTH_OPTS} --server-port=0" - -e "create region --name=authExampleRegion --type=PARTITION" - -e "create region --name=authGeodeSessionState --type=PARTITION") -add_test(NAME stopclusters - COMMAND ${Geode_gfsh_EXECUTABLE} - -e "connect --locator=localhost[10335] --user=server --password=server" - -e "stop server --name=auth_server" - -e "stop locator --name=auth_locator" - -e "connect --locator=localhost[10334]" - -e "stop server --name=server" - -e "stop locator --name=locator") -add_test(NAME remove_dirs - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/remove_dirs.cmake) - add_test(NAME netcore-session-test COMMAND dotnet test -c $<CONFIG> WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - -set_tests_properties(startclusters PROPERTIES FIXTURES_SETUP geode) -set_tests_properties(netcore-session-test PROPERTIES FIXTURES_REQUIRED geode) -set_tests_properties(stopclusters PROPERTIES FIXTURES_CLEANUP geode) -set_tests_properties(remove_dirs PROPERTIES DEPENDS stopclusters) diff --git a/netcore/netcore-session-integration-test/SessionStateIntegrationTests.cs b/netcore/netcore-session-integration-test/SessionStateIntegrationTests.cs index d34002c..6930c7e 100644 --- a/netcore/netcore-session-integration-test/SessionStateIntegrationTests.cs +++ b/netcore/netcore-session-integration-test/SessionStateIntegrationTests.cs @@ -16,160 +16,226 @@ */ using System; using System.Text; -using Xunit; -using Apache.Geode.Client; using System.Linq; using Microsoft.Extensions.Caching.Distributed; using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; +using Apache.Geode.Client.IntegrationTests; namespace Apache.Geode.Session.IntegrationTests { - public class SessionStateIntegrationTests { + [Collection("Geode .Net Core Collection")] + public class SessionStateIntegrationTests : TestBase { - [Fact] - public void SetGet() { - var ssCacheOptions = new GeodeSessionStateCacheOptions(); - ssCacheOptions.Host = "localhost"; - ssCacheOptions.Port = 10334; - ssCacheOptions.RegionName = "exampleRegion"; - - using var ssCache = new GeodeSessionStateCache(ssCacheOptions); - - var options = new DistributedCacheEntryOptions(); - var localTime = DateTime.Now.AddDays(1); - var dateAndOffset = - new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime)); - options.AbsoluteExpiration = dateAndOffset; - var testValue = new byte[] { 1, 2, 3, 4, 5 }; - ssCache.Set("testKey", testValue, options); - var value = ssCache.Get("testKey"); - Assert.True(testValue.SequenceEqual(value)); + public SessionStateIntegrationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { } [Fact] - public void Refresh() { - var ssCacheOptions = new GeodeSessionStateCacheOptions(); - ssCacheOptions.Host = "localhost"; - ssCacheOptions.Port = 10334; - ssCacheOptions.RegionName = "exampleRegion"; - - using var ssCache = new GeodeSessionStateCache(ssCacheOptions); - - var options = new DistributedCacheEntryOptions(); - var numSeconds = 20; - options.SlidingExpiration = new TimeSpan(0, 0, numSeconds); - var testValue = new byte[] { 1, 2, 3, 4, 5 }; - - // Set a value - ssCache.Set("testKey", testValue, options); - - // Wait half a timeout then refresh - System.Threading.Thread.Sleep(numSeconds / 2 * 1000); - ssCache.Refresh("testKey"); - - // Wait beyond the original expiration - System.Threading.Thread.Sleep(numSeconds / 2 * 1000 + 1); + public void SetGet() + { + using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) + { + Assert.True(cluster.Start()); + Assert.Equal(0, cluster.Gfsh + .create() + .region() + .withName("exampleRegion") + .withType("PARTITION") + .execute()); + + var ssCacheOptions = new GeodeSessionStateCacheOptions(); + ssCacheOptions.Host = "localhost"; + ssCacheOptions.Port = cluster.Locators[0].Address.port; + ssCacheOptions.RegionName = "exampleRegion"; + + using var ssCache = new GeodeSessionStateCache(ssCacheOptions); + + var options = new DistributedCacheEntryOptions(); + var localTime = DateTime.Now.AddDays(1); + var dateAndOffset = + new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime)); + options.AbsoluteExpiration = dateAndOffset; + var testValue = new byte[] { 1, 2, 3, 4, 5 }; + ssCache.Set("testKey", testValue, options); + var value = ssCache.Get("testKey"); + Assert.True(testValue.SequenceEqual(value)); + } + } - // Ensure it's not expired - var value = ssCache.Get("testKey"); - Assert.True(testValue.SequenceEqual(value)); + [Fact] + public void Refresh() + { + using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) + { + Assert.True(cluster.Start()); + Assert.Equal(0, cluster.Gfsh + .create() + .region() + .withName("exampleRegion") + .withType("PARTITION") + .execute()); + + var ssCacheOptions = new GeodeSessionStateCacheOptions(); + ssCacheOptions.Host = "localhost"; + ssCacheOptions.Port = cluster.Locators[0].Address.port; + ssCacheOptions.RegionName = "exampleRegion"; + + using var ssCache = new GeodeSessionStateCache(ssCacheOptions); + + var options = new DistributedCacheEntryOptions(); + var numSeconds = 20; + options.SlidingExpiration = new TimeSpan(0, 0, numSeconds); + var testValue = new byte[] { 1, 2, 3, 4, 5 }; + + // Set a value + ssCache.Set("testKey", testValue, options); + + // Wait half a timeout then refresh + System.Threading.Thread.Sleep(numSeconds / 2 * 1000); + ssCache.Refresh("testKey"); + + // Wait beyond the original expiration + System.Threading.Thread.Sleep(numSeconds / 2 * 1000 + 1); + + // Ensure it's not expired + var value = ssCache.Get("testKey"); + Assert.True(testValue.SequenceEqual(value)); + } } [Fact] - public void SetWithAbsoluteExpiration() { - var ssCacheOptions = new GeodeSessionStateCacheOptions(); - ssCacheOptions.Host = "localhost"; - ssCacheOptions.Port = 10334; - ssCacheOptions.RegionName = "exampleRegion"; - - using var ssCache = new GeodeSessionStateCache(ssCacheOptions); - - var options = new DistributedCacheEntryOptions(); - options.AbsoluteExpiration = DateTime.Now.AddSeconds(5); - ssCache.Set("testKey", Encoding.UTF8.GetBytes("testValue"), options); - System.Threading.Thread.Sleep(6000); - var value = ssCache.Get("testKey"); - Assert.Null(value); + public void SetWithAbsoluteExpiration() + { + using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) + { + Assert.True(cluster.Start()); + Assert.Equal(0, cluster.Gfsh + .create() + .region() + .withName("exampleRegion") + .withType("PARTITION") + .execute()); + + var ssCacheOptions = new GeodeSessionStateCacheOptions(); + ssCacheOptions.Host = "localhost"; + ssCacheOptions.Port = cluster.Locators[0].Address.port; + ssCacheOptions.RegionName = "exampleRegion"; + + using var ssCache = new GeodeSessionStateCache(ssCacheOptions); + + var options = new DistributedCacheEntryOptions(); + options.AbsoluteExpiration = DateTime.Now.AddSeconds(5); + ssCache.Set("testKey", Encoding.UTF8.GetBytes("testValue"), options); + System.Threading.Thread.Sleep(6000); + var value = ssCache.Get("testKey"); + Assert.Null(value); + } } [Fact] - public void Remove() { - var ssCacheOptions = new GeodeSessionStateCacheOptions(); - ssCacheOptions.Host = "localhost"; - ssCacheOptions.Port = 10334; - ssCacheOptions.RegionName = "exampleRegion"; - - using var ssCache = new GeodeSessionStateCache(ssCacheOptions); - - var options = new DistributedCacheEntryOptions(); - var localTime = DateTime.Now.AddDays(1); - var dateAndOffset = - new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime)); - options.AbsoluteExpiration = dateAndOffset; - var testValue = new byte[] { 1, 2, 3, 4, 5 }; - ssCache.Set("testKey", testValue, options); - var value = ssCache.Get("testKey"); - - ssCache.Remove("testKey"); - value = ssCache.Get("testKey"); - Assert.Null(value); + public void Remove() + { + using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) + { + Assert.True(cluster.Start()); + Assert.Equal(0, cluster.Gfsh + .create() + .region() + .withName("exampleRegion") + .withType("PARTITION") + .execute()); + + var ssCacheOptions = new GeodeSessionStateCacheOptions(); + ssCacheOptions.Host = "localhost"; + ssCacheOptions.Port = cluster.Locators[0].Address.port; + ssCacheOptions.RegionName = "exampleRegion"; + + using var ssCache = new GeodeSessionStateCache(ssCacheOptions); + + var options = new DistributedCacheEntryOptions(); + var localTime = DateTime.Now.AddDays(1); + var dateAndOffset = + new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime)); + options.AbsoluteExpiration = dateAndOffset; + var testValue = new byte[] { 1, 2, 3, 4, 5 }; + ssCache.Set("testKey", testValue, options); + var value = ssCache.Get("testKey"); + + ssCache.Remove("testKey"); + value = ssCache.Get("testKey"); + Assert.Null(value); + } } [Fact] - public void SetGetRemoveAsync() { - var ssCacheOptions = new GeodeSessionStateCacheOptions(); - ssCacheOptions.Host = "localhost"; - ssCacheOptions.Port = 10334; - ssCacheOptions.RegionName = "exampleRegion"; - - using var ssCache = new GeodeSessionStateCache(ssCacheOptions); - - var options = new DistributedCacheEntryOptions(); - var localTime = DateTime.Now.AddDays(1); - var dateAndOffset = - new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime)); - options.AbsoluteExpiration = dateAndOffset; - - var testValue1 = new byte[] { 1, 2, 3, 4, 5 }; - var testValue2 = new byte[] { 11, 12, 13, 14, 15 }; - var testValue3 = new byte[] { 21, 22, 23, 24, 25 }; - var testValue4 = new byte[] { 31, 32, 33, 34, 35 }; - var testValue5 = new byte[] { 41, 42, 43, 44, 45 }; - - var set1 = ssCache.SetAsync("testKey1", testValue1, options); - var set2 = ssCache.SetAsync("testKey2", testValue2, options); - var set3 = ssCache.SetAsync("testKey3", testValue3, options); - var set4 = ssCache.SetAsync("testKey4", testValue4, options); - var set5 = ssCache.SetAsync("testKey5", testValue5, options); - - Task.WaitAll(set1, set2, set3, set4, set5); - - var value1 = ssCache.GetAsync("testKey1"); - var value2 = ssCache.GetAsync("testKey2"); - var value3 = ssCache.GetAsync("testKey3"); - var value4 = ssCache.GetAsync("testKey4"); - var value5 = ssCache.GetAsync("testKey5"); - - Task.WaitAll(value1, value2, value3, value4, value5); - - Assert.True(testValue1.SequenceEqual(value1.Result)); - Assert.True(testValue2.SequenceEqual(value2.Result)); - Assert.True(testValue3.SequenceEqual(value3.Result)); - Assert.True(testValue4.SequenceEqual(value4.Result)); - Assert.True(testValue5.SequenceEqual(value5.Result)); - - var rm1 = ssCache.RemoveAsync("testKey1"); - var rm2 = ssCache.RemoveAsync("testKey2"); - var rm3 = ssCache.RemoveAsync("testKey3"); - var rm4 = ssCache.RemoveAsync("testKey4"); - var rm5 = ssCache.RemoveAsync("testKey5"); - - Task.WaitAll(rm1, rm2, rm3, rm4, rm5); - - Assert.Null(ssCache.Get("testKey1")); - Assert.Null(ssCache.Get("testKey2")); - Assert.Null(ssCache.Get("testKey3")); - Assert.Null(ssCache.Get("testKey4")); - Assert.Null(ssCache.Get("testKey5")); + public void SetGetRemoveAsync() + { + using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) + { + Assert.True(cluster.Start()); + Assert.Equal(0, cluster.Gfsh + .create() + .region() + .withName("exampleRegion") + .withType("PARTITION") + .execute()); + + var ssCacheOptions = new GeodeSessionStateCacheOptions(); + ssCacheOptions.Host = "localhost"; + ssCacheOptions.Port = cluster.Locators[0].Address.port; + ssCacheOptions.RegionName = "exampleRegion"; + + using var ssCache = new GeodeSessionStateCache(ssCacheOptions); + + var options = new DistributedCacheEntryOptions(); + var localTime = DateTime.Now.AddDays(1); + var dateAndOffset = + new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime)); + options.AbsoluteExpiration = dateAndOffset; + + var testValue1 = new byte[] { 1, 2, 3, 4, 5 }; + var testValue2 = new byte[] { 11, 12, 13, 14, 15 }; + var testValue3 = new byte[] { 21, 22, 23, 24, 25 }; + var testValue4 = new byte[] { 31, 32, 33, 34, 35 }; + var testValue5 = new byte[] { 41, 42, 43, 44, 45 }; + + var set1 = ssCache.SetAsync("testKey1", testValue1, options); + var set2 = ssCache.SetAsync("testKey2", testValue2, options); + var set3 = ssCache.SetAsync("testKey3", testValue3, options); + var set4 = ssCache.SetAsync("testKey4", testValue4, options); + var set5 = ssCache.SetAsync("testKey5", testValue5, options); + + Task.WaitAll(set1, set2, set3, set4, set5); + + var value1 = ssCache.GetAsync("testKey1"); + var value2 = ssCache.GetAsync("testKey2"); + var value3 = ssCache.GetAsync("testKey3"); + var value4 = ssCache.GetAsync("testKey4"); + var value5 = ssCache.GetAsync("testKey5"); + + Task.WaitAll(value1, value2, value3, value4, value5); + + Assert.True(testValue1.SequenceEqual(value1.Result)); + Assert.True(testValue2.SequenceEqual(value2.Result)); + Assert.True(testValue3.SequenceEqual(value3.Result)); + Assert.True(testValue4.SequenceEqual(value4.Result)); + Assert.True(testValue5.SequenceEqual(value5.Result)); + + var rm1 = ssCache.RemoveAsync("testKey1"); + var rm2 = ssCache.RemoveAsync("testKey2"); + var rm3 = ssCache.RemoveAsync("testKey3"); + var rm4 = ssCache.RemoveAsync("testKey4"); + var rm5 = ssCache.RemoveAsync("testKey5"); + + Task.WaitAll(rm1, rm2, rm3, rm4, rm5); + + Assert.Null(ssCache.Get("testKey1")); + Assert.Null(ssCache.Get("testKey2")); + Assert.Null(ssCache.Get("testKey3")); + Assert.Null(ssCache.Get("testKey4")); + Assert.Null(ssCache.Get("testKey5")); + } } } } diff --git a/netcore/netcore-session-integration-test/netcore-session-integration-test.csproj b/netcore/netcore-session-integration-test/netcore-session-integration-test.csproj index e8a76d7..301d1b9 100644 --- a/netcore/netcore-session-integration-test/netcore-session-integration-test.csproj +++ b/netcore/netcore-session-integration-test/netcore-session-integration-test.csproj @@ -8,6 +8,15 @@ </PropertyGroup> <ItemGroup> + <Compile Include="..\shared\Config.cs" Link="Config.cs" /> + <Compile Include="..\shared\Cluster.cs" Link="Cluster.cs" /> + <Compile Include="..\shared\Gfsh.cs" Link="Gfsh.cs" /> + <Compile Include="..\shared\Framework.cs" Link="Framework.cs" /> + <Compile Include="..\shared\GfshExecute.cs" Link="GfshExecute.cs" /> + <Compile Include="..\shared\TestBase.cs" Link="TestBase.cs" /> + </ItemGroup> + + <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> diff --git a/netcore/netcore.sln b/netcore/netcore.sln new file mode 100644 index 0000000..f4249d3 --- /dev/null +++ b/netcore/netcore.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31702.278 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore-lib", "netcore-lib\netcore-lib.csproj", "{27274EF5-E606-4D98-98C0-8214B80FC267}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore-integration-test", "netcore-integration-test\netcore-integration-test.csproj", "{1FB30EB0-1121-4E9D-AAB9-6ABF88378219}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "asp-netcore-session-sample", "asp-netcore-session-sample\asp-netcore-session-sample.csproj", "{94BC7C9E-1967-4E87-983A-FECD32F7DDE2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore-session", "netcore-session\netcore-session.csproj", "{72C7BDE7-F933-464A-A5E7-F024D73CD8F1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "netcore-session-integration-test", "netcore-session-integration-test\netcore-session-integration-test.csproj", "{8C06FA0E-A460-442B-978D-C0195259893F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + RelWithDebInfo|x64 = RelWithDebInfo|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {27274EF5-E606-4D98-98C0-8214B80FC267}.Debug|x64.ActiveCfg = Debug|x64 + {27274EF5-E606-4D98-98C0-8214B80FC267}.Debug|x64.Build.0 = Debug|x64 + {27274EF5-E606-4D98-98C0-8214B80FC267}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 + {27274EF5-E606-4D98-98C0-8214B80FC267}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 + {1FB30EB0-1121-4E9D-AAB9-6ABF88378219}.Debug|x64.ActiveCfg = Debug|x64 + {1FB30EB0-1121-4E9D-AAB9-6ABF88378219}.Debug|x64.Build.0 = Debug|x64 + {1FB30EB0-1121-4E9D-AAB9-6ABF88378219}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 + {1FB30EB0-1121-4E9D-AAB9-6ABF88378219}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 + {94BC7C9E-1967-4E87-983A-FECD32F7DDE2}.Debug|x64.ActiveCfg = Debug|x64 + {94BC7C9E-1967-4E87-983A-FECD32F7DDE2}.Debug|x64.Build.0 = Debug|x64 + {94BC7C9E-1967-4E87-983A-FECD32F7DDE2}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 + {94BC7C9E-1967-4E87-983A-FECD32F7DDE2}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 + {72C7BDE7-F933-464A-A5E7-F024D73CD8F1}.Debug|x64.ActiveCfg = Debug|x64 + {72C7BDE7-F933-464A-A5E7-F024D73CD8F1}.Debug|x64.Build.0 = Debug|x64 + {72C7BDE7-F933-464A-A5E7-F024D73CD8F1}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 + {72C7BDE7-F933-464A-A5E7-F024D73CD8F1}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 + {8C06FA0E-A460-442B-978D-C0195259893F}.Debug|x64.ActiveCfg = Debug|x64 + {8C06FA0E-A460-442B-978D-C0195259893F}.Debug|x64.Build.0 = Debug|x64 + {8C06FA0E-A460-442B-978D-C0195259893F}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 + {8C06FA0E-A460-442B-978D-C0195259893F}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1C2B71F0-E68A-43D1-9AA1-6A1CEE82C993} + EndGlobalSection +EndGlobal diff --git a/netcore/CMakeLists.txt b/netcore/shared/CMakeLists.txt similarity index 68% copy from netcore/CMakeLists.txt copy to netcore/shared/CMakeLists.txt index b5c3536..c9e0ed5 100644 --- a/netcore/CMakeLists.txt +++ b/netcore/shared/CMakeLists.txt @@ -12,17 +12,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -project(netcore LANGUAGES NONE) - -option(INCLUDE_DOTNET_CORE "Build .NET Core client." ON) - -find_program(DOTNET dotnet) - -if(DOTNET AND INCLUDE_DOTNET_CORE) - add_subdirectory(netcore-lib) - add_subdirectory(netcore-session) - add_subdirectory(netcore-integration-test) - add_subdirectory(netcore-session-integration-test) - add_subdirectory(utility) -endif() +project(netcore-shared LANGUAGES NONE) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cs.in ${CMAKE_CURRENT_SOURCE_DIR}/Config.cs) diff --git a/netcore/shared/Cluster.cs b/netcore/shared/Cluster.cs new file mode 100644 index 0000000..c3d0004 --- /dev/null +++ b/netcore/shared/Cluster.cs @@ -0,0 +1,300 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using Xunit.Abstractions; + +namespace Apache.Geode.Client.IntegrationTests +{ + public class Cluster : IDisposable + { + private int locatorCount_; + private int serverCount_; + private bool started_; + private List<Locator> locators_; + private string name_; + internal int jmxManagerPort = Framework.FreeTcpPort(); + internal string keyStore_ = Config.SslServerKeyPath + "/server_keystore_chained.jks"; + internal string keyStorePassword_ = "apachegeode"; + internal string trustStore_ = Config.SslServerKeyPath + "/server_truststore_chained_root.jks"; + internal string trustStorePassword_ = "apachegeode"; + + public Gfsh Gfsh { get; private set; } + + public bool UseSSL { get; set; } + + public List<Locator> Locators + { + get { return locators_; } + } + + internal PoolFactory ApplyLocators(PoolFactory poolFactory) + { + foreach (var locator in locators_) + { + poolFactory.AddLocator(locator.Address.address, locator.Address.port); + } + return poolFactory; + } + + public Cluster(ITestOutputHelper output, string name, int locatorCount, int serverCount) + { + started_ = false; + Gfsh = new GfshExecute(output); + UseSSL = false; + name_ = name; + locatorCount_ = locatorCount; + serverCount_ = serverCount; + locators_ = new List<Locator>(); + } + + private bool StartLocators() + { + var success = true; + + for (var i = 0; i < locatorCount_; i++) + { + var locator = new Locator(this, new List<Locator>(), + name_ + "/locator/" + i.ToString()); + locators_.Add(locator); + success = (locator.Start() == 0); + } + return success; + } + + private bool StartServers() + { + var success = true; + + for (var i = 0; i < serverCount_; i++) + { + var server = new Server(this, locators_, + name_ + "/server/" + i.ToString()); + var localResult = server.Start(); + if (localResult != 0) + { + success = false; + } + } + return success; + } + + private void RemoveClusterDirectory() + { + if (Directory.Exists(name_)) + { + Directory.Delete(name_, true); + } + } + + public bool Start() + { + if (!started_) + { + RemoveClusterDirectory(); + var locatorSuccess = StartLocators(); + var serverSuccess = StartServers(); + started_ = (locatorSuccess && serverSuccess); + } + return (started_); + } + + public void Dispose() + { + if (started_) + { + this.Gfsh + .shutdown() + .withIncludeLocators(true) + .execute(); + } + } + + public IGeodeCache CreateCache(IDictionary<string, string> properties) + { + var cacheFactory = new CacheFactory(); + + cacheFactory + .SetProperty("log-level", "none") + .SetProperty("statistic-sampling-enabled", "false"); + + foreach (var pair in properties) + { + cacheFactory.SetProperty(pair.Key, pair.Value); + } + + var cache = cacheFactory.CreateCache(); + + ApplyLocators(cache.PoolFactory).CreatePool("default"); + + return cache; + } + + public IGeodeCache CreateCache() + { + return CreateCache(new Dictionary<string, string>()); + } + + } + + public struct Address + { + public string address; + public int port; + } + + public class Locator + { + private Cluster cluster_; + private string name_; + private List<Locator> locators_; + private bool started_; + + public Locator(Cluster cluster, List<Locator> locators, string name) + { + cluster_ = cluster; + locators_ = locators; + name_ = name; + var address = new Address(); + address.address = "localhost"; + address.port = Framework.FreeTcpPort(); + Address = address; + } + + public Address Address { get; private set; } + + public int Start() + { + var result = -1; + if (!started_) + { + var locator = cluster_.Gfsh + .start() + .locator() + .withDir(name_) + .withName(name_.Replace('/', '_')) + .withBindAddress(Address.address) + .withPort(Address.port) + .withMaxHeap("256m") + .withJmxManagerPort(cluster_.jmxManagerPort) + .withJmxManagerStart(true) + .withHttpServicePort(0); + if (cluster_.UseSSL) + { + locator + .withConnect(false) + .withSslEnableComponents("all") + .withSslKeyStore(cluster_.keyStore_) + .withSslKeyStorePassword(cluster_.keyStorePassword_) + .withSslTrustStore(cluster_.trustStore_) + .withSslTrustStorePassword(cluster_.trustStorePassword_); + } + result = locator.execute(); + + if (cluster_.UseSSL) + { + cluster_.Gfsh.connect() + .withJmxManager(Address.address, cluster_.jmxManagerPort) + .withUseSsl(true) + .withKeyStore(cluster_.keyStore_) + .withKeyStorePassword(cluster_.keyStorePassword_) + .withTrustStore(cluster_.trustStore_) + .withTrustStorePassword(cluster_.trustStorePassword_) + .execute(); + } + + started_ = true; + + } + return result; + } + + public int Stop() + { + var result = cluster_.Gfsh + .stop() + .locator() + .withDir(name_) + .execute(); + started_ = false; + return result; + } + } + + public class Server + { + private Cluster cluster_; + private string name_; + private List<Locator> locators_; + private bool started_; + + public Server(Cluster cluster, List<Locator> locators, string name) + { + cluster_ = cluster; + locators_ = locators; + name_ = name; + var address = new Address(); + address.address = "localhost"; + address.port = 0; + Address = address; + } + + public Address Address { get; private set; } + + public int Start() + { + var result = -1; + if (!started_) + { + var server = cluster_.Gfsh + .start() + .server() + .withDir(name_) + .withName(name_.Replace('/', '_')) + .withBindAddress(Address.address) + .withPort(Address.port) + .withMaxHeap("1g"); + if (cluster_.UseSSL) + { + server + .withSslEnableComponents("all") + .withSslKeyStore(cluster_.keyStore_) + .withSslKeyStorePassword(cluster_.keyStorePassword_) + .withSslTrustStore(cluster_.trustStore_) + .withSslTrustStorePassword(cluster_.trustStorePassword_); + + } + result = server.execute(); + started_ = true; + } + return result; + } + + public int Stop() + { + var result = cluster_.Gfsh + .stop() + .server() + .withDir(name_) + .execute(); + started_ = false; + return result; + } + } +} diff --git a/netcore/netcore-integration-test/NetCoreCollectionFixture.cs b/netcore/shared/Config.cs.in similarity index 57% copy from netcore/netcore-integration-test/NetCoreCollectionFixture.cs copy to netcore/shared/Config.cs.in index d30833e..4111ec2 100644 --- a/netcore/netcore-integration-test/NetCoreCollectionFixture.cs +++ b/netcore/shared/Config.cs.in @@ -1,4 +1,4 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -14,20 +14,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -using System; -using Apache.Geode.Client; -using Xunit; -public class NetCoreCollectionFixture : IDisposable { - public NetCoreCollectionFixture() { - client_ = new Client(); +// GENERATED FROM Config.cs.in DO NOT EDIT Config.cs + +public class Config +{ + public static string GeodeGfsh + { + get { return @"@Geode_gfsh_EXECUTABLE@"; } } - public void Dispose() { - client_.Dispose(); + + public static string JavaobjectJarPath + { + get { return @"@JAVAOBJECT_JAR_PATH@"; } } - Client client_; -} + public static string SslServerKeyPath + { + get { return @"@CMAKE_CURRENT_SOURCE_DIR@/../../ssl_keys/server_keys"; } + } -[CollectionDefinition("Geode .net Core Collection")] -public class NetCoreCollection : ICollectionFixture<NetCoreCollectionFixture> {} + public static string SslClientKeyPath + { + get { return @"@CMAKE_CURRENT_SOURCE_DIR@/../../ssl_keys/client_keys"; } + } + + public static string SniConfigPath + { + get { return @"@CMAKE_CURRENT_SOURCE_DIR@/../../sni-test-config"; } + } +} diff --git a/netcore/netcore-integration-test/NetCoreCollectionFixture.cs b/netcore/shared/Framework.cs similarity index 65% copy from netcore/netcore-integration-test/NetCoreCollectionFixture.cs copy to netcore/shared/Framework.cs index d30833e..d005c07 100644 --- a/netcore/netcore-integration-test/NetCoreCollectionFixture.cs +++ b/netcore/shared/Framework.cs @@ -1,4 +1,4 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -14,20 +14,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -using System; -using Apache.Geode.Client; -using Xunit; -public class NetCoreCollectionFixture : IDisposable { - public NetCoreCollectionFixture() { - client_ = new Client(); - } - public void Dispose() { - client_.Dispose(); - } +using System.Net; +using System.Net.Sockets; - Client client_; -} - -[CollectionDefinition("Geode .net Core Collection")] -public class NetCoreCollection : ICollectionFixture<NetCoreCollectionFixture> {} +namespace Apache.Geode.Client.IntegrationTests +{ + public abstract class Framework + { + public static int FreeTcpPort() + { + var tcpListner = new TcpListener(IPAddress.Loopback, 0); + tcpListner.Start(); + var port = ((IPEndPoint)tcpListner.LocalEndpoint).Port; + tcpListner.Stop(); + return port; + } + } +} \ No newline at end of file diff --git a/netcore/shared/Gfsh.cs b/netcore/shared/Gfsh.cs new file mode 100644 index 0000000..14ba81b --- /dev/null +++ b/netcore/shared/Gfsh.cs @@ -0,0 +1,493 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Net; +using System.Net.Sockets; + +namespace Apache.Geode.Client.IntegrationTests +{ + public abstract class Gfsh + { + + //TODO: Understand what C++ Command class is doing. Why is it a template, + //when the only <T> class we're passing is void? How can you call a ctor + //or a (non-existent?) 'parse' function on void? So many questions... + public class Command + { + public Command(Gfsh gfsh, string command) + { + gfsh_ = gfsh; + command_ = command; + } + + public int execute() + { + return gfsh_.execute(command_); + } + + public override string ToString() + { + return command_; + } + + protected Gfsh gfsh_; + protected string command_; + } + + public class Start + { + public Start(Gfsh gfsh) + { + gfsh_ = gfsh; + } + + public class Server : Command + { + public Server(Gfsh gfsh) : base(gfsh, "start server") + { + gfsh_ = gfsh; + } + + public Server withName(string name) + { + command_ += " --name=" + name; + return this; + } + + public Server withDir(string dir) + { + command_ += " --dir=" + dir; + return this; + } + + public Server withBindAddress(string bindAddress) + { + command_ += " --bind-address=" + bindAddress; + return this; + } + + public Server withPort(int port) + { + command_ += " --server-port=" + port.ToString(); + return this; + } + + public Server withLocators(string locators) + { + command_ += " --locators=" + locators; + return this; + } + + public Server withLogLevel(string logLevel) + { + command_ += " --log-level=" + logLevel; + return this; + } + + public Server withMaxHeap(string maxHeap) + { + command_ += " --max-heap=" + maxHeap; + return this; + } + + public Server withSslKeyStore(string keyStore) + { + command_ += " --J=-Dgemfire.ssl-keystore=" + keyStore; + return this; + } + + public Server withSslKeyStorePassword(string keyStorePassword) + { + command_ += " --J=-Dgemfire.ssl-keystore-password=" + keyStorePassword; + return this; + } + + public Server withSslTrustStore(string trustStore) + { + command_ += " --J=-Dgemfire.ssl-truststore=" + trustStore; + return this; + } + + public Server withSslTrustStorePassword(string trustStorePassword) + { + command_ += " --J=-Dgemfire.ssl-truststore-password=" + trustStorePassword; + return this; + } + + public Server withSslEnableComponents(string components) + { + command_ += " --J=-Dgemfire.ssl-enabled-components=" + components; + return this; + } + } + + public Server server() + { + return new Server(gfsh_); + } + + public class Locator : Command + { + public Locator(Gfsh gfsh) : base(gfsh, "start locator") + { + } + + public Locator withName(string name) + { + command_ += " --name=" + name; + return this; + } + + public Locator withDir(string dir) + { + command_ += " --dir=" + dir; + return this; + } + + public Locator withBindAddress(string bindAddress) + { + command_ += " --bind-address=" + bindAddress; + return this; + } + + public Locator withPort(int port) + { + command_ += " --port=" + port; + return this; + } + + public Locator withJmxManagerPort(int jmxManagerPort) + { + command_ += " --J=-Dgemfire.jmx-manager-port=" + jmxManagerPort; + return this; + } + + public Locator withJmxManagerStart(bool start) + { + command_ += " --J=-Dgemfire.jmx-manager-start=" + (start ? "true" : "false"); + return this; + } + + public Locator withHttpServicePort(int httpServicePort) + { + command_ += " --http-service-port=" + httpServicePort; + return this; + } + + public Locator withLogLevel(string logLevel) + { + command_ += " --log-level=" + logLevel; + return this; + } + + public Locator withMaxHeap(string maxHeap) + { + command_ += " --max-heap=" + maxHeap; + return this; + } + + public Locator withConnect(bool connect) + { + command_ += " --connect="; + command_ += connect ? "true" : "false"; + return this; + } + + public Locator withSslKeyStore(string keyStore) + { + command_ += " --J=-Dgemfire.ssl-keystore=" + keyStore; + return this; + } + + public Locator withSslKeyStorePassword(string keyStorePassword) + { + command_ += " --J=-Dgemfire.ssl-keystore-password=" + keyStorePassword; + return this; + } + + public Locator withSslTrustStore(string trustStore) + { + command_ += " --J=-Dgemfire.ssl-truststore=" + trustStore; + return this; + } + + public Locator withSslTrustStorePassword(string trustStorePassword) + { + command_ += " --J=-Dgemfire.ssl-truststore-password=" + trustStorePassword; + return this; + } + + public Locator withSslEnableComponents(string components) + { + command_ += " --J=-Dgemfire.ssl-enabled-components=" + components; + return this; + } + } + + public Locator locator() + { + return new Locator(gfsh_); + } + + private Gfsh gfsh_; + } + + public Start start() + { + return new Start(this); + } + + public class Stop + { + public Stop(Gfsh gfsh) + { + gfsh_ = gfsh; + } + + public class Locator : Command + { + public Locator(Gfsh gfsh) : base(gfsh, "stop locator") + { + } + + public Locator withName(string name) + { + command_ += " --name=" + name; + return this; + } + + public Locator withDir(string dir) + { + command_ += " --dir=" + dir; + return this; + } + } + + public Locator locator() + { + return new Locator(gfsh_); + } + + public class Server : Command + { + public Server(Gfsh gfsh) : base(gfsh, "stop server") + { + } + + public Server withName(string name) + { + command_ += " --name=" + name; + return this; + } + + public Server withDir(string dir) + { + command_ += " --dir=" + dir; + return this; + } + } + public Server server() + { + return new Server(gfsh_); + } + + private Gfsh gfsh_; + } + + public Stop stop() + { + return new Stop(this); + } + + public class Create + { + public Create(Gfsh gfsh) + { + gfsh_ = gfsh; + } + + public class Region : Command + { + public Region(Gfsh gfsh) : base(gfsh, "create region") { } + + public Region withName(string name) + { + command_ += " --name=" + name; + return this; + } + + public Region withType(string type) + { + command_ += " --type=" + type; + return this; + } + } + + public Region region() + { + return new Region(gfsh_); + } + + private Gfsh gfsh_; + } + public Create create() + { + return new Create(this); + } + + public class Shutdown : Command + { + public Shutdown(Gfsh gfsh) : base(gfsh, "shutdown") { } + + public Shutdown withIncludeLocators(bool includeLocators) + { + command_ += " --include-locators="; + command_ += includeLocators ? "true" : "false"; + return this; + } + } + + public Shutdown shutdown() + { + return new Shutdown(this); + } + + public class Connect : Command + { + public Connect(Gfsh gfsh) : base(gfsh, "connect") { } + + public Connect withJmxManager(string jmxManagerAddress, int jmxManagerPort) + { + command_ += " --jmx-manager=" + jmxManagerAddress + "[" + jmxManagerPort.ToString() + "]"; + return this; + } + + public Connect withUseSsl(bool enable) + { + command_ += " --use-ssl=" + (enable ? "true" : "false"); + return this; + } + + public Connect withKeyStore(string keyStore) + { + command_ += " --key-store=" + keyStore; + return this; + } + + public Connect withKeyStorePassword(string keyStorePassword) + { + command_ += " --key-store-password=" + keyStorePassword; + return this; + } + + public Connect withTrustStore(string trustStore) + { + command_ += " --trust-store=" + trustStore; + return this; + } + + public Connect withTrustStorePassword(string trustStorePassword) + { + command_ += " --trust-store-password=" + trustStorePassword; + return this; + } + } + + public Connect connect() + { + return new Connect(this); + } + + public class ConfigurePdx : Command + { + public ConfigurePdx(Gfsh gfsh) : base(gfsh, "configure pdx") { } + + public ConfigurePdx withReadSerialized(bool readSerialized) + { + command_ += " --read-serialized="; + command_ += readSerialized ? "true" : "false"; + return this; + } + } + + public ConfigurePdx configurePdx() + { + return new ConfigurePdx(this); + } + + public class Deploy : Command + { + public Deploy(Gfsh gfsh) : base(gfsh, "deploy") { } + + public Deploy withJar(string fullPathToJar) + { + command_ += " --jar=" + fullPathToJar; + return this; + } + + public Deploy withDir(string fullPathToDir) + { + command_ += " --dir=" + fullPathToDir; + return this; + } + + public Deploy withGroup(string groupName) + { + command_ += " --group=" + groupName; + return this; + } + } + + public Deploy deploy() + { + return new Deploy(this); + } + + public class ExecuteFunction : Command + { + public ExecuteFunction(Gfsh gfsh) : base(gfsh, "execute function") { } + + public ExecuteFunction withId(string functionId) + { + command_ += " --id=" + functionId; + return this; + } + + public ExecuteFunction withMember(string memberName) + { + command_ += " --member=" + memberName; + return this; + } + } + + public ExecuteFunction executeFunction() + { + return new ExecuteFunction(this); + } + + private static int FreeTcpPort() + { + var tcpListner = new TcpListener(IPAddress.Loopback, 0); + tcpListner.Start(); + var port = ((IPEndPoint)tcpListner.LocalEndpoint).Port; + tcpListner.Stop(); + return port; + } + + public abstract int execute(string cmd); + } +} diff --git a/netcore/shared/GfshExecute.cs b/netcore/shared/GfshExecute.cs new file mode 100644 index 0000000..6171783 --- /dev/null +++ b/netcore/shared/GfshExecute.cs @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Collections.Generic; +using Xunit.Abstractions; + +namespace Apache.Geode.Client.IntegrationTests +{ + public class GfshExecute : Gfsh + { + private String connectionCommand_ = null; + private ITestOutputHelper output; + + public GfshExecute(ITestOutputHelper output) + { + this.output = output; + } + + private void ExtractConnectionCommand(String command) + { + if (command.StartsWith("connect")) + { + connectionCommand_ = command; + } + else if (command.StartsWith("start locator")) + { + if (command.Contains("--connect=false")) + { + return; + } + + var jmxManagerHost = "localhost"; + var jmxManagerPort = "1099"; + + var jmxManagerHostRegex = new Regex(@"\bbind-address=([^\s])\b"); + var jmxManagerHostMatch = jmxManagerHostRegex.Match(command); + + if (jmxManagerHostMatch.Success) + { + jmxManagerHost = jmxManagerHostMatch.Groups[1].Value; + } + + var jmxManagerPortRegex = new Regex(@"\bjmx-manager-port=(\d+)\b"); + var jmxManagerPortMatch = jmxManagerPortRegex.Match(command); + if (jmxManagerPortMatch.Success) + { + jmxManagerPort = jmxManagerPortMatch.Groups[1].Value; + } + + connectionCommand_ = new Connect(this).withJmxManager(jmxManagerHost, int.Parse(jmxManagerPort)).ToString(); + } + + } + + public override int execute(string cmd) + { + + var commands = new List<string>(); + + if (null != connectionCommand_) + { + commands.Add("-e"); + commands.Add(connectionCommand_); + } + + commands.Add("-e"); + commands.Add(cmd); + + // TODO escape commands + var fullCmd = "\"" + string.Join("\" \"", commands) + "\""; + + using var gfsh = new Process + { + StartInfo = + { + FileName = Config.GeodeGfsh, + Arguments = fullCmd, + WindowStyle = ProcessWindowStyle.Hidden, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = false + } + }; + + gfsh.OutputDataReceived += (sender, args) => + { + if (args.Data != null) + { + WriteLine("GfshExecute: " + args.Data); + } + }; + + gfsh.ErrorDataReceived += (sender, args) => + { + if (args.Data != null) + { + WriteLine("GfshExecute: ERROR: " + args.Data); + } + }; + + gfsh.Start(); + gfsh.BeginOutputReadLine(); + gfsh.BeginErrorReadLine(); + if (gfsh.WaitForExit(60000)) + { + WriteLine("GeodeServer Start: gfsh.HasExited = {0}, gfsh.ExitCode = {1}", + gfsh.HasExited, + gfsh.ExitCode); + } + else + { + WriteLine("GeodeServer Start: gfsh failed to exit, force killing."); + KillAndIgnore(gfsh); + } + CancelErrorReadAndIgnore(gfsh); + CancelOutputReadAndIgnore(gfsh); + + ExtractConnectionCommand(cmd); + + return gfsh.ExitCode; + } + + private static void CancelOutputReadAndIgnore(Process gfsh) + { + try + { + gfsh.CancelOutputRead(); + } + catch + { + // ignored + } + } + + private static void CancelErrorReadAndIgnore(Process gfsh) + { + try + { + gfsh.CancelErrorRead(); + } + catch + { + // ignored + } + } + + private static void KillAndIgnore(Process gfsh) + { + try + { + gfsh.Kill(); + } + catch + { + // ignored + } + } + + private void WriteLine(string format, params object[] args) + { + if (null == output) + { + Debug.WriteLine(format, args); + } + else + { + output.WriteLine(format, args); + } + } + + private void WriteLine(string message) + { + if (null == output) + { + Debug.WriteLine(message); + } + else + { + output.WriteLine(message); + } + } + } +} diff --git a/netcore/shared/TestBase.cs b/netcore/shared/TestBase.cs new file mode 100644 index 0000000..20c8875 --- /dev/null +++ b/netcore/shared/TestBase.cs @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; +using System.Reflection; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Apache.Geode.Client.IntegrationTests { + [Trait("Category", "Integration")] + public class TestBase + { + protected ITest currentTest; + protected ITestOutputHelper output; + + public TestBase(ITestOutputHelper testOutputHelper) + { + var helper = (TestOutputHelper)testOutputHelper; + + ITest test = (ITest)helper.GetType().GetField("test", BindingFlags.NonPublic | BindingFlags.Instance) + .GetValue(helper); + + currentTest = test; + output = testOutputHelper; + } + + public void CleanTestCaseDirectory(string directory) + { + if (Directory.Exists(directory)) + { + Directory.Delete(directory, true); + } + } + + public string CreateTestCaseDirectoryName() + { + return currentTest.TestCase.TestMethod.Method.Name; + } + } +}