IGNITE-2662 .NET Core and cross-platform (Linux) support
authorPavel Tupitsyn <ptupitsyn@apache.org>
Thu, 23 Nov 2017 12:19:28 +0000 (15:19 +0300)
committerPavel Tupitsyn <ptupitsyn@apache.org>
Thu, 23 Nov 2017 12:19:28 +0000 (15:19 +0300)
This closes #3061

81 files changed:
.gitignore
modules/platforms/dotnet/Apache.Ignite.AspNet/Apache.Ignite.AspNet.nuspec
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.sln [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.sln.DotSettings [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Cache/CacheTest.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/IgnitionStartTest.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/Person.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestBase.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestFixtureSetUp.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestFixtureTearDown.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestRunner.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestUtils.DotNetCore.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/README.txt [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/app.config [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/dotnet-test-windows.bat [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/dotnet-test-wsl.bat [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/nuget.config [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests.NuGet/Apache.Ignite.Core.Tests.NuGet.csproj
modules/platforms/dotnet/Apache.Ignite.Core.Tests.NuGet/Apache.Ignite.Core.Tests.NuGet.sln.DotSettings
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
modules/platforms/dotnet/Apache.Ignite.Core.Tests/AssertExtensions.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/AdvancedSerializationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/CallbacksTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/BinaryConfigurationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistenceTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTestSimpleName.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTestSimpleName.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Base.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Strings.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTestSimpleName.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CacheTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/ClientCacheConfigurationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CreateCacheTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/ScanQueryTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.JavaTask.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/DataStructures/AtomicLongTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/DataStructures/AtomicReferenceTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/DataStructures/AtomicSequenceTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Log/CustomLoggerTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/MessagingTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/ProjectFilesTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServicesTest.cs
modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Common.cs [moved from modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs with 69% similarity]
modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.nuspec
modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/MemoryPolicyConfiguration.cs
modules/platforms/dotnet/Apache.Ignite.Core/Configuration/DataRegionConfiguration.cs
modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Classpath.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/IgniteConfigurationXmlSerializer.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/IgniteHome.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteUtils.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/MemoryInfo.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core/Impl/NativeMethods.cs [deleted file]
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Shell.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/DllLoader.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Jni/Env.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Jni/EnvDelegates.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Jni/Jvm.cs
modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Os.cs [new file with mode: 0644]
modules/platforms/dotnet/Apache.Ignite.Core/NuGet/Install.ps1
modules/platforms/dotnet/Apache.Ignite.Core/NuGet/PostBuild.ps1
modules/platforms/dotnet/Apache.Ignite.Core/NuGet/Uninstall.ps1
modules/platforms/dotnet/Apache.Ignite.EntityFramework/Apache.Ignite.EntityFramework.nuspec
modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.nuspec
modules/platforms/dotnet/Apache.Ignite.Log4Net/Apache.Ignite.Log4Net.nuspec
modules/platforms/dotnet/Apache.Ignite.NLog/Apache.Ignite.NLog.nuspec
modules/platforms/dotnet/Apache.Ignite.ndproj
modules/platforms/dotnet/build.ps1

index 18146f8..e5739a5 100644 (file)
@@ -28,6 +28,7 @@ git-patch-prop-local.sh
 /modules/platforms/**/*.VC.db
 **/dotnet/libs/
 *.classname*
+*.exe
 
 #Visual Studio files
 *.[Oo]bj
index 7891614..1b480b9 100644 (file)
@@ -51,4 +51,8 @@ More info: https://apacheignite-net.readme.io/
             <dependency id="Apache.Ignite" version="[$version$]" />
         </dependencies>    
     </metadata>
+    <files>
+           <file src="bin\$configuration$\Apache.Ignite.AspNet.dll" target="lib\net40" />
+               <file src="bin\$configuration$\Apache.Ignite.AspNet.xml" target="lib\net40" />
+    </files>
 </package>
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj
new file mode 100644 (file)
index 0000000..9a6e57c
--- /dev/null
@@ -0,0 +1,136 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.0</TargetFramework>
+
+    <IsPackable>false</IsPackable>
+
+    <StartupObject>Apache.Ignite.Core.Tests.DotNetCore.Common.TestRunner</StartupObject>
+
+    <ApplicationIcon />
+
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Include="..\Apache.Ignite.Core.Tests\AssertExtensions.cs" Link="Common\AssertExtensions.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\BinaryConfigurationTest.cs" Link="Binary\BinaryConfigurationTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Binary\BinaryDateTimeTest.cs" Link="Binary\BinaryDateTimeTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Binary\JavaBinaryInteropTest.cs" Link="Binary\JavaBinaryInteropTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Binary\Serializable\AdvancedSerializationTest.cs" Link="Binary\Serializable\AdvancedSerializationTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Binary\Serializable\CallbacksTest.cs" Link="Binary\Serializable\CallbacksTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Binary\Serializable\GenericCollectionsTest.cs" Link="Binary\Serializable\GenericCollectionsTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Binary\Serializable\SqlDmlTest.cs" Link="Binary\Serializable\SqlDmlTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\AddArgCacheEntryProcessor.cs" Link="Cache\AddArgCacheEntryProcessor.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\BinarizableAddArgCacheEntryProcessor.cs" Link="Cache\BinarizableAddArgCacheEntryProcessor.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\BinarizableTestException.cs" Link="Cache\BinarizableTestException.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\CacheAbstractTest.cs" Link="Cache\CacheAbstractTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\CacheAbstractTransactionalTest.cs" Link="Cache\CacheAbstractTransactionalTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\CachePartitionedTest.cs" Link="Cache\CachePartitionedTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\CacheTestAsyncWrapper.cs" Link="Cache\CacheTestAsyncWrapper.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\CacheTestKey.cs" Link="Cache\CacheTestKey.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\DataRegionMetricsTest.cs" Link="Cache\DataRegionMetricsTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\NonSerializableCacheEntryProcessor.cs" Link="Cache\NonSerializableCacheEntryProcessor.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\NonSerializableException.cs" Link="Cache\NonSerializableException.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\PersistenceTest.cs" Link="Cache\PersistenceTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\CacheDmlQueriesTest.cs" Link="Cache\Query\CacheDmlQueriesTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\CacheDmlQueriesTestSimpleName.cs" Link="Cache\Query\CacheDmlQueriesTestSimpleName.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\CacheQueriesCodeConfigurationTest.cs" Link="Cache\Query\CacheQueriesCodeConfigurationTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\CacheQueriesTest.cs" Link="Cache\Query\CacheQueriesTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\CacheQueriesTestSimpleName.cs" Link="Cache\Query\CacheQueriesTestSimpleName.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Aggregates.cs" Link="Cache\Query\Linq\CacheLinqTest.Aggregates.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Base.cs" Link="Cache\Query\Linq\CacheLinqTest.Base.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.CompiledQuery.cs" Link="Cache\Query\Linq\CacheLinqTest.CompiledQuery.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Contains.cs" Link="Cache\Query\Linq\CacheLinqTest.Contains.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Custom.cs" Link="Cache\Query\Linq\CacheLinqTest.Custom.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.DateTime.cs" Link="Cache\Query\Linq\CacheLinqTest.DateTime.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Functions.cs" Link="Cache\Query\Linq\CacheLinqTest.Functions.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Introspection.cs" Link="Cache\Query\Linq\CacheLinqTest.Introspection.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Join.cs" Link="Cache\Query\Linq\CacheLinqTest.Join.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Join.LocalCollection.cs" Link="Cache\Query\Linq\CacheLinqTest.Join.LocalCollection.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Misc.cs" Link="Cache\Query\Linq\CacheLinqTest.Misc.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Numerics.cs" Link="Cache\Query\Linq\CacheLinqTest.Numerics.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTest.Strings.cs" Link="Cache\Query\Linq\CacheLinqTest.Strings.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTestSimpleName.cs" Link="Cache\Query\Linq\CacheLinqTestSimpleName.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\Query\Linq\CacheLinqTestSqlEscapeAll.cs" Link="Cache\Query\Linq\CacheLinqTestSqlEscapeAll.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Cache\TestReferenceObject.cs" Link="Cache\TestReferenceObject.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\Cache\CacheTest.cs" Link="ThinClient\Cache\CacheTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\Cache\EmptyObject.cs" Link="ThinClient\Cache\EmptyObject.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\Cache\Person.cs" Link="ThinClient\Cache\Person.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\Cache\ScanQueryTest.cs" Link="ThinClient\Cache\ScanQueryTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\Cache\SqlQueryTest.cs" Link="ThinClient\Cache\SqlQueryTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\ClientConnectionTest.cs" Link="ThinClient\ClientConnectionTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\ClientTestBase.cs" Link="ThinClient\ClientTestBase.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Client\IgniteClientConfigurationTest.cs" Link="ThinClient\IgniteClientConfigurationTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Compute\ComputeApiTest.cs" Link="Compute\ComputeApiTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\DataStructures\AtomicLongTest.cs" Link="DataStructures\AtomicLongTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\DataStructures\AtomicReferenceTest.cs" Link="DataStructures\AtomicReferenceTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\DataStructures\AtomicSequenceTest.cs" Link="DataStructures\AtomicSequenceTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\EventsTestLocalListeners.cs" Link="Common\EventsTestLocalListeners.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\IgniteTestBase.cs" Link="Common\IgniteTestBase.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Log\CustomLoggerTest.cs" Link="Log\CustomLoggerTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\MessagingTest.cs" Link="Common\MessagingTest.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\Query\BinarizablePerson.cs" Link="Cache\Query\BinarizablePerson.cs" />
+    <Compile Include="..\Apache.Ignite.Core.Tests\TestUtils.Common.cs" Link="Common\TestUtils.Common.cs" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Include="..\Apache.Ignite.Core.Tests\Config\cache-binarizables.xml" Link="Config\cache-binarizables.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Apache.Ignite.Core.Tests\Config\cache-query.xml" Link="Config\cache-query.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Apache.Ignite.Core.Tests\Config\Compute\compute-grid1.xml" Link="Config\Compute\compute-grid1.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Apache.Ignite.Core.Tests\Config\Compute\compute-grid2.xml" Link="Config\Compute\compute-grid2.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Apache.Ignite.Core.Tests\Config\Compute\compute-grid3.xml" Link="Config\Compute\compute-grid3.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Apache.Ignite.Core.Tests\Config\native-client-test-cache.xml" Link="Config\native-client-test-cache.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\Apache.Ignite.Core.Tests\Config\spring-test.xml" Link="Config\spring-test.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Apache.Ignite" Version="0.0.1-test" />
+    <PackageReference Include="Apache.Ignite.Linq" Version="0.0.1-test" />
+    <PackageReference Include="Apache.Ignite.Schema" Version="0.0.1-test" />
+    <PackageReference Include="Apache.Ignite.NLog" Version="0.0.1-test" />
+    <PackageReference Include="Apache.Ignite.log4net" Version="0.0.1-test" />
+    <PackageReference Include="log4net" Version="2.0.5" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
+    <PackageReference Include="NLog" Version="4.4.12" />
+    <PackageReference Include="NUnit" Version="3.8.1" />
+    <PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
+    <PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Folder Include="Binary\Serializable\" />
+    <Folder Include="Cache\Query\Linq\" />
+    <Folder Include="Cache\Query\" />
+    <Folder Include="Compute\" />
+    <Folder Include="Config\Compute\" />
+    <Folder Include="Log\" />
+    <Folder Include="DataStructures\" />
+    <Folder Include="ThinClient\Cache\" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Include="Common\TestUtils.DotNetCore.cs" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Update="app.config">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+
+</Project>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.sln b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.sln
new file mode 100644 (file)
index 0000000..4aac7e1
--- /dev/null
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27004.2006
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Ignite.Core.Tests.DotNetCore", "Apache.Ignite.Core.Tests.DotNetCore.csproj", "{470E5BC1-61DC-4B42-90B6-9269B476C070}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{70803854-079D-4BA7-8A46-21A13D8AF9D6}"
+       ProjectSection(SolutionItems) = preProject
+               NuGet.config = NuGet.config
+               README.txt = README.txt
+       EndProjectSection
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {470E5BC1-61DC-4B42-90B6-9269B476C070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {470E5BC1-61DC-4B42-90B6-9269B476C070}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {470E5BC1-61DC-4B42-90B6-9269B476C070}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {470E5BC1-61DC-4B42-90B6-9269B476C070}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {7BD29E51-C041-4E66-8DC4-8F8B6B917864}
+       EndGlobalSection
+EndGlobal
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.sln.DotSettings b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.sln.DotSettings
new file mode 100644 (file)
index 0000000..06f463a
--- /dev/null
@@ -0,0 +1,13 @@
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+       <s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp70</s:String>
+       <s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=silent/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="silent"&gt;&lt;CSReorderTypeMembers&gt;True&lt;/CSReorderTypeMembers&gt;&lt;CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="False" AddMissingParentheses="False" ArrangeBraces="False" ArrangeAttributes="False" ArrangeArgumentsStyle="False" /&gt;&lt;RemoveCodeRedundancies&gt;True&lt;/RemoveCodeRedundancies&gt;&lt;CSArrangeQualifiers&gt;True&lt;/CSArrangeQualifiers&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;/Profile&gt;</s:String>
+       <s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">silent</s:String>
+       <s:String x:Key="/Default/CodeStyle/CodeFormatting/XmlDocFormatter/IndentSubtags/@EntryValue">DoNotTouch</s:String>
+       <s:String x:Key="/Default/CodeStyle/CodeFormatting/XmlDocFormatter/IndentTagContent/@EntryValue">DoNotTouch</s:String>
+       <s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
+       <s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean>
+       <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">DO_NOT_SHOW</s:String>
+       <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean>
+       <s:Boolean x:Key="/Default/Environment/UnitTesting/ShadowCopy/@EntryValue">False</s:Boolean>
+       <s:Boolean x:Key="/Default/Environment/UnitTesting/WrapLongLinesInUnitTestSessionOutput/@EntryValue">False</s:Boolean>
+</wpf:ResourceDictionary>
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Cache/CacheTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Cache/CacheTest.cs
new file mode 100644 (file)
index 0000000..701c839
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.DotNetCore.Cache
+{
+    using System.Threading.Tasks;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Tests.DotNetCore.Common;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Cache tests.
+    /// </summary>
+    public class CacheTest : TestBase
+    {
+        /// <summary>
+        /// Tests the put / get functionality.
+        /// </summary>
+        [Test]
+        public void TestPutGet()
+        {
+            async Task PutGetAsync(ICache<int, Person> cache)
+            {
+                await cache.PutAsync(2, new Person("Bar", 2));
+                var res = await cache.GetAsync(2);
+                Assert.AreEqual(2, res.Id);
+            }
+
+            using (var ignite = Start())
+            {
+                var cache = ignite.CreateCache<int, Person>("persons");
+
+                // Sync.
+                cache[1] = new Person("Foo", 1);
+                Assert.AreEqual("Foo", cache[1].Name);
+
+                // Async.
+                PutGetAsync(cache).Wait();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/IgnitionStartTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/IgnitionStartTest.cs
new file mode 100644 (file)
index 0000000..e442cd6
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.DotNetCore.Common
+{
+    using System;
+    using System.IO;
+    using System.Linq;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Configuration;
+    using Apache.Ignite.Core.Discovery.Tcp;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests Ignite startup.
+    /// </summary>
+    public class IgnitionStartTest : TestBase
+    {
+        /// <summary>
+        /// Tests that Ignite starts with default configuration.
+        /// </summary>
+        [Test]
+        public void TestIgniteStartsWithDefaultConfig()
+        {
+            var ignite = Start();
+            Assert.IsNotNull(ignite);
+            Assert.AreEqual(ignite, Ignition.GetIgnite());
+
+            // Second node.
+            var ignite2 = Start("ignite-2");
+            Assert.AreEqual(2, Ignition.GetAll().Count);
+
+            // Stop node.
+            Ignition.Stop(ignite.Name, true);
+            Assert.AreEqual(ignite2, Ignition.GetIgnite());
+
+            // Stop all.
+            Ignition.StopAll(true);
+            Assert.AreEqual(0, Ignition.GetAll().Count);
+        }
+
+        /// <summary>
+        /// Tests the ignite starts from application configuration.
+        /// </summary>
+        [Test]
+        public void TestIgniteStartsFromAppConfig()
+        {
+            // 1) MsTest does not pick up the config file, so we have to provide it manually.
+            // 2) Note that System.Configuration.ConfigurationManager NuGet package has to be installed.
+            var configPath = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "app.config");
+
+            using (var ignite = Ignition.StartFromApplicationConfiguration("igniteConfiguration", configPath))
+            {
+                var cache = ignite.GetCache<int, int>(ignite.GetCacheNames().Single());
+
+                Assert.AreEqual("cacheFromConfig", cache.Name);
+                Assert.AreEqual(CacheMode.Replicated, cache.GetConfiguration().CacheMode);
+            }
+        }
+
+        /// <summary>
+        /// Tests that Ignite starts from Spring XML.
+        /// </summary>
+        [Test]
+        public void TestIgniteStartsFromSpringXml()
+        {
+            // When Spring XML is used, .NET overrides Spring.
+            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                DataStorageConfiguration = null,
+                SpringConfigUrl = @"Config\spring-test.xml",
+                NetworkSendRetryDelay = TimeSpan.FromSeconds(45),
+                MetricsHistorySize = 57
+            };
+
+            using (var ignite = Ignition.Start(cfg))
+            {
+                var resCfg = ignite.GetConfiguration();
+
+                Assert.AreEqual(45, resCfg.NetworkSendRetryDelay.TotalSeconds);  // .NET overrides XML
+                Assert.AreEqual(2999, resCfg.NetworkTimeout.TotalMilliseconds);  // Not set in .NET -> comes from XML
+                Assert.AreEqual(57, resCfg.MetricsHistorySize);  // Only set in .NET
+
+                var disco = resCfg.DiscoverySpi as TcpDiscoverySpi;
+                Assert.IsNotNull(disco);
+                Assert.AreEqual(TimeSpan.FromMilliseconds(300), disco.SocketTimeout);
+
+                // DataStorage defaults.
+                var dsCfg = new DataStorageConfiguration
+                {
+                    DefaultDataRegionConfiguration = new DataRegionConfiguration
+                    {
+                        Name = "default"
+                    }
+                };
+                AssertExtensions.ReflectionEqual(dsCfg, resCfg.DataStorageConfiguration);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/Person.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/Person.cs
new file mode 100644 (file)
index 0000000..933ed26
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.DotNetCore.Common
+{
+    /// <summary>
+    /// Test person.
+    /// </summary>
+    public class Person
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Person"/> class.
+        /// </summary>
+        public Person(string name, int id)
+        {
+            Name = name;
+            Id = id;
+        }
+
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the identifier.
+        /// </summary>
+        public int Id { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestBase.cs
new file mode 100644 (file)
index 0000000..4e77c0d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.DotNetCore.Common
+{
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Base test class.
+    /// </summary>
+    public class TestBase
+    {
+        /// <summary>
+        /// Fixture cleanup.
+        /// </summary>
+        [OneTimeTearDown]
+        public static void ClassCleanup()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Starts Ignite.
+        /// </summary>
+        public IIgnite Start(string name = null)
+        {
+            return Ignition.Start(TestUtils.GetTestConfiguration(name));
+        }
+    }
+}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestFixtureSetUp.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestFixtureSetUp.cs
new file mode 100644 (file)
index 0000000..0000637
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+// ReSharper disable once CheckNamespace
+namespace Apache.Ignite.Core.Tests
+{
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Provides backwards compatibility for tests linked from Apache.Ignite.Core.Tests.
+    /// </summary>
+    public class TestFixtureSetUp : OneTimeSetUpAttribute
+    {
+        // No-op.
+    }
+}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestFixtureTearDown.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestFixtureTearDown.cs
new file mode 100644 (file)
index 0000000..9b2ba5e
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+// ReSharper disable once CheckNamespace
+namespace Apache.Ignite.Core.Tests
+{
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Provides backwards compatibility for tests linked from Apache.Ignite.Core.Tests.
+    /// </summary>
+    public class TestFixtureTearDown : OneTimeTearDownAttribute
+    {
+        // No-op.
+    }
+}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestRunner.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestRunner.cs
new file mode 100644 (file)
index 0000000..1b0d45c
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.DotNetCore.Common
+{
+    /// <summary>
+    /// Test runner.
+    /// </summary>
+    internal class TestRunner
+    {
+        /// <summary>
+        /// Console entry point.
+        /// </summary>
+        private static void Main(string[] args)
+        {
+            new IgnitionStartTest().TestIgniteStartsFromAppConfig();
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestUtils.DotNetCore.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Common/TestUtils.DotNetCore.cs
new file mode 100644 (file)
index 0000000..0f51593
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests
+{
+    using System;
+    using System.Collections.Generic;
+    using System.IO;
+    using System.Linq;
+
+    public static partial class TestUtils
+    {
+        /** */
+        private static readonly IList<string> JvmOpts =
+            new List<string>
+            {
+                "-Duser.timezone=UTC"
+
+                // Uncomment to debug Java
+                //"-Xdebug",
+                //"-Xnoagent",
+                //"-Djava.compiler=NONE",
+                //"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
+            };
+
+        /// <summary>
+        /// Gets the default code-based test configuration.
+        /// </summary>
+        public static IgniteConfiguration GetTestConfiguration(string name = null)
+        {
+            return new IgniteConfiguration
+            {
+                DiscoverySpi = GetStaticDiscovery(),
+                Localhost = "127.0.0.1",
+                JvmOptions = JvmOpts,
+                IgniteInstanceName = name
+            };
+        }
+
+        /// <summary>
+        /// Creates a uniquely named, empty temporary directory on disk and returns the full path of that directory.
+        /// </summary>
+        /// <returns>The full path of the temporary directory.</returns>
+        internal static string GetTempDirectoryName()
+        {
+            var baseDir = Path.Combine(Path.GetTempPath(), "IgniteTemp_");
+
+            while (true)
+            {
+                try
+                {
+                    return Directory.CreateDirectory(baseDir + Path.GetRandomFileName()).FullName;
+                }
+                catch (IOException)
+                {
+                    // Expected
+                }
+                catch (UnauthorizedAccessException)
+                {
+                    // Expected
+                }
+            }
+        }
+    }
+}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/README.txt b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/README.txt
new file mode 100644 (file)
index 0000000..e24ab34
--- /dev/null
@@ -0,0 +1,16 @@
+Apache Ignite .NET Core tests (cross-platform)
+==============================================
+
+Main Apache.Ignite.sln solution targets .NET 4.0 & VS 2010: we care for backwards compatibility.
+However, this does not prevent us from supporting .NET Standard 2.0 and .NET Core 2.0,
+because of ".NET Framework compatibility mode", which allows referencing any libraries
+from .NET Core 2.0 projects.
+
+Therefore we can't include .NET Core tests in manin solution, and we rely on pre-built
+NuGet packages for cross-platform tests.
+
+How to run:
+1) Build Ignite.NET (only on Windows):  build -version 0.0.1-test
+   Special 0.0.1-test version override is used so that we don't have to change package reference in csproj file on each release.
+2) Clear NuGet caches: dotnet nuget locals all --clear
+3) Build and run cross-platform tests (any OS): dotnet test
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/app.config b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/app.config
new file mode 100644 (file)
index 0000000..f750305
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<!--
+  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.
+-->
+
+<configuration>
+
+  <configSections>
+    <section name="igniteConfiguration" type="Apache.Ignite.Core.IgniteConfigurationSection, Apache.Ignite.Core" />
+  </configSections>
+
+  <runtime>
+    <gcServer enabled="true" />
+  </runtime>
+
+  <igniteConfiguration xmlns="http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection"
+                       localhost="127.0.0.1">
+    <cacheConfiguration>
+      <cacheConfiguration name="cacheFromConfig" cacheMode="Replicated" />
+    </cacheConfiguration>
+
+    <discoverySpi type="TcpDiscoverySpi">
+      <ipFinder type="TcpDiscoveryMulticastIpFinder">
+        <endpoints>
+          <string>127.0.0.1:47500</string>
+        </endpoints>
+      </ipFinder>
+    </discoverySpi>
+  </igniteConfiguration>
+</configuration>
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/dotnet-test-windows.bat b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/dotnet-test-windows.bat
new file mode 100644 (file)
index 0000000..25b77ff
--- /dev/null
@@ -0,0 +1,32 @@
+::
+:: 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.
+::
+
+:: Runs tests on WSL (Windows Subsystem for Linux).
+:: Ignite.NET must be built on Windows, but cross-platform tests can be run on Linux.
+
+pushd .\
+
+cd ..
+powershell -executionpolicy remotesigned -file build.ps1 -skipJava -version 0.0.1-test
+popd
+
+dotnet nuget locals all --clear
+
+echo Starting tests...
+dotnet test
+
+pause.
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/dotnet-test-wsl.bat b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/dotnet-test-wsl.bat
new file mode 100644 (file)
index 0000000..f566c17
--- /dev/null
@@ -0,0 +1,34 @@
+::
+:: 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.
+::
+
+:: Runs tests on WSL (Windows Subsystem for Linux).
+:: Ignite.NET must be built on Windows, but cross-platform tests can be run on Linux.
+
+pushd .\
+
+cd ..
+powershell -executionpolicy remotesigned -file build.ps1 -skipJava -version 0.0.1-test
+
+popd
+
+bash -c "dotnet nuget locals all --clear"
+
+echo Starting tests...
+
+bash -c "dotnet test"
+
+pause.
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/nuget.config b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/nuget.config
new file mode 100644 (file)
index 0000000..ae4c5cd
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  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.
+-->
+
+<configuration>
+
+    <packageRestore>
+        <!-- Allow NuGet to download missing packages -->
+        <add key="enabled" value="True" />
+
+        <!-- Automatically check for missing packages during build in Visual Studio -->
+        <add key="automatic" value="True" />
+    </packageRestore>
+
+    <!--
+        Used to specify the default Sources for list, install and update.
+        See: nuget.exe help list
+        See: nuget.exe help install
+        See: nuget.exe help update
+    -->
+    <packageSources>
+        <add key="Local" value="../nupkg/" />
+        <!-- <add key="NuGet official package source" value="https://nuget.org/api/v2/" /> -->
+    </packageSources>
+
+</configuration>
\ No newline at end of file
index 4452ac7..c449c03 100644 (file)
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
-    <PostBuildEvent>if not exist "$(TargetDir)Libs" md "$(TargetDir)Libs"
-xcopy /s /y "$(SolutionDir)packages\Apache.Ignite.1.8.0\Libs\*.*" "$(TargetDir)Libs"</PostBuildEvent>
+    <PostBuildEvent>if not exist "$(TargetDir)libs" md "$(TargetDir)libs"
+xcopy /s /y "$(SolutionDir)packages\Apache.Ignite.1.8.0\libs\*.*" "$(TargetDir)libs"</PostBuildEvent>
   </PropertyGroup>
   <PropertyGroup>
     <PreBuildEvent>
index 187a909..f02c942 100644 (file)
@@ -1,4 +1,6 @@
 <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
        
-       <s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>
\ No newline at end of file
+       <s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean>
+       <s:Boolean x:Key="/Default/Environment/UnitTesting/ShadowCopy/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>
+       
\ No newline at end of file
index 2d5a54b..3951b40 100644 (file)
@@ -76,6 +76,7 @@
     <Compile Include="ApiParity\ParityTest.cs" />
     <Compile Include="ApiParity\CacheConfigurationParityTest.cs" />
     <Compile Include="ApiParity\QueryEntityConfigurationParityTest.cs" />
+    <Compile Include="AssertExtensions.cs" />
     <Compile Include="Binary\BinaryBuilderSelfTestSimpleName.cs" />
     <Compile Include="Binary\BinaryDateTimeTest.cs" />
     <Compile Include="Binary\BinaryEqualityComparerTest.cs" />
     <Compile Include="Client\RawSocketTest.cs" />
     <Compile Include="Client\ClientConnectionTest.cs" />
     <Compile Include="Client\IgniteClientConfigurationTest.cs" />
+    <Compile Include="Compute\ComputeApiTest.JavaTask.cs" />
     <Compile Include="Deployment\CacheGetFunc.cs" />
     <Compile Include="Deployment\GetAddressFunc.cs" />
     <Compile Include="Deployment\PeerAssemblyLoadingAllApisTest.cs" />
     <Compile Include="Binary\Serializable\AdvancedSerializationTest.cs" />
     <Compile Include="IgniteStartStopTest.cs" />
     <Compile Include="Services\ServicesTestFullFooter.cs" />
-    <Compile Include="TestUtils.cs" />
+    <Compile Include="TestUtils.Common.cs" />
     <Compile Include="Memory\InteropMemoryTest.cs" />
     <Compile Include="Binary\BinaryBuilderSelfTest.cs" />
     <Compile Include="Binary\BinarySelfTest.cs" />
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </None>
     <None Include="packages.config" />
+    <Compile Include="TestUtils.Windows.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup Condition="'$(Platform)' != 'AnyCPU'">
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/AssertExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/AssertExtensions.cs
new file mode 100644 (file)
index 0000000..c82b9f7
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// NUnit assert extensions.
+    /// </summary>
+    internal static class AssertExtensions
+    {
+        /// <summary>
+        /// Asserts equality with reflection recursively.
+        /// </summary>
+        public static void ReflectionEqual(object x, object y, string propertyPath = null,
+            HashSet<string> ignoredProperties = null)
+        {
+            if (x == null && y == null)
+            {
+                return;
+            }
+
+            Assert.IsNotNull(x, propertyPath);
+            Assert.IsNotNull(y, propertyPath);
+
+            var type = x.GetType();
+
+            if (type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(type))
+            {
+                var xCol = ((IEnumerable)x).OfType<object>().ToList();
+                var yCol = ((IEnumerable)y).OfType<object>().ToList();
+
+                Assert.AreEqual(xCol.Count, yCol.Count, propertyPath);
+
+                for (var i = 0; i < xCol.Count; i++)
+                {
+                    ReflectionEqual(xCol[i], yCol[i], propertyPath, ignoredProperties);
+                }
+
+                return;
+            }
+
+            Assert.AreEqual(type, y.GetType());
+
+            propertyPath = propertyPath ?? type.Name;
+
+            if (type.IsValueType || type == typeof(string) || type.IsSubclassOf(typeof(Type)))
+            {
+                Assert.AreEqual(x, y, propertyPath);
+                return;
+            }
+
+            var props = type.GetProperties().Where(p => p.GetIndexParameters().Length == 0);
+
+            foreach (var propInfo in props)
+            {
+                if (ignoredProperties != null && ignoredProperties.Contains(propInfo.Name))
+                {
+                    continue;
+                }
+
+                var propName = propertyPath + "." + propInfo.Name;
+
+                var xVal = propInfo.GetValue(x, null);
+                var yVal = propInfo.GetValue(y, null);
+
+                ReflectionEqual(xVal, yVal, propName, ignoredProperties);
+            }
+        }
+    }
+}
index dc208d0..4a10922 100644 (file)
@@ -96,6 +96,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
             Assert.AreEqual(expectedRes, jobResult.InnerXml);
         }
 
+#if !NETCOREAPP2_0  // AppDomains are not supported in .NET Core
         /// <summary>
         /// Tests custom serialization binder.
         /// </summary>
@@ -147,6 +148,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
 
             return typeBuilder.CreateType();
         }
+#endif
 
         /// <summary>
         /// Tests the DataTable serialization.
index a014205..e3d4c51 100644 (file)
@@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
     using System;
     using System.Collections.Generic;
     using System.Linq;
+    using System.Reflection;
     using System.Runtime.Serialization;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Impl.Binary;
@@ -194,8 +195,12 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
         [Test]
         public void TestIncorrectMethodSignature()
         {
-            var ex = Assert.Throws<TypeLoadException>(
-                    () => TestUtils.SerializeDeserialize(new InvalidCallbackSignature()));
+            var ex = Assert.Catch(() => TestUtils.SerializeDeserialize(new InvalidCallbackSignature()));
+            
+            var tex = ex as TargetInvocationException;
+            ex = tex != null ? tex.InnerException : ex;
+
+            Assert.IsNotNull(ex);
 
             var t = typeof(InvalidCallbackSignature);
 
index 8495a30..4b77dbe 100644 (file)
@@ -55,7 +55,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
             {
                 BinaryConfiguration = new BinaryConfiguration(typeof(SimpleSerializable))
                 {
-                    NameMapper = BinaryBasicNameMapper.SimpleNameInstance
+                    NameMapper = new BinaryBasicNameMapper { IsSimpleName = true }
                 }
             };
 
@@ -163,6 +163,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
             Assert.AreEqual("Value was either too large or too small for a UInt32.", ex.Message);
         }
 
+#if !NETCOREAPP2_0  // Console redirect issues on .NET Core
         /// <summary>
         /// Tests the log warning.
         /// </summary>
@@ -180,6 +181,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
 
             Assert.IsTrue(_outSb.ToString().Contains(expected));
         }
+#endif
 
         /// <summary>
         /// Serializable with Java-compatible fields.
index 972b078..4113d4b 100644 (file)
@@ -71,7 +71,7 @@ namespace Apache.Ignite.Core.Tests
 
             var grid = Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration())
             {
-                SpringConfigUrl = "config\\cache-binarizables.xml",
+                SpringConfigUrl = "Config\\cache-binarizables.xml",
                 BinaryConfiguration = binaryConfiguration
             });
 
@@ -132,7 +132,7 @@ namespace Apache.Ignite.Core.Tests
             Assert.IsNotNull(ex.InnerException);
             Assert.IsTrue(ex.InnerException.Message.StartsWith(
                 "Open generic types (Type.IsGenericTypeDefinition == true) are not allowed in BinaryConfiguration: " +
-                "System.Collections.Generic.List`1, mscorlib"));
+                "System.Collections.Generic.List`1"));
 
             // Pass open generic type name.
             cfg.BinaryConfiguration = new BinaryConfiguration {Types = new[] {typeof(IList<>).AssemblyQualifiedName}};
@@ -142,7 +142,7 @@ namespace Apache.Ignite.Core.Tests
             Assert.IsNotNull(ex.InnerException);
             Assert.IsTrue(ex.InnerException.Message.StartsWith(
                 "Open generic types (Type.IsGenericTypeDefinition == true) are not allowed in BinaryConfiguration: " +
-                "System.Collections.Generic.IList`1, mscorlib"));
+                "System.Collections.Generic.IList`1"));
 
             // Pass interface.
             cfg.BinaryConfiguration = new BinaryConfiguration(typeof(ICollection));
@@ -152,7 +152,7 @@ namespace Apache.Ignite.Core.Tests
             Assert.IsNotNull(ex.InnerException);
             Assert.IsTrue(ex.InnerException.Message.StartsWith(
                 "Abstract types and interfaces are not allowed in BinaryConfiguration: " +
-                "System.Collections.ICollection, mscorlib"));
+                "System.Collections.ICollection"));
         }
 
         /// <summary>
index 39a18fe..d54363a 100644 (file)
@@ -30,8 +30,9 @@ namespace Apache.Ignite.Core.Tests.Cache
     using Apache.Ignite.Core.Cache.Expiry;
     using Apache.Ignite.Core.Cluster;
     using Apache.Ignite.Core.Common;
+#if !NETCOREAPP2_0
     using Apache.Ignite.Core.Impl.Cache;
-    using Apache.Ignite.Core.Impl.Cache.Expiry;
+#endif
     using Apache.Ignite.Core.Tests.Query;
     using Apache.Ignite.Core.Transactions;
     using NUnit.Framework;
@@ -48,8 +49,6 @@ namespace Apache.Ignite.Core.Tests.Cache
         [TestFixtureSetUp]
         public void StartGrids()
         {
-            TestUtils.KillProcesses();
-
             IgniteConfiguration cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
             {
                 BinaryConfiguration = new BinaryConfiguration(
@@ -58,7 +57,7 @@ namespace Apache.Ignite.Core.Tests.Cache
                     typeof(TestReferenceObject),
                     typeof(BinarizableAddArgCacheEntryProcessor),
                     typeof(BinarizableTestException)),
-                SpringConfigUrl = "config\\native-client-test-cache.xml"
+                SpringConfigUrl = "Config\\native-client-test-cache.xml"
             };
 
             for (int i = 0; i < GridCount(); i++)
@@ -1304,6 +1303,8 @@ namespace Apache.Ignite.Core.Tests.Cache
             {
                 ICacheEntry<int, int> entry = e.Current;
 
+                Assert.IsNotNull(entry);
+
                 Assert.IsTrue(keys.Contains(entry.Key), "Unexpected entry: " + entry);
 
                 Assert.AreEqual(entry.Key + 1, entry.Value);
@@ -2198,6 +2199,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             }
         }
 
+#if !NETCOREAPP2_0
         /// <summary>
         /// Test skip-store semantics.
         /// </summary>
@@ -2224,6 +2226,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             // Ensure other flags are preserved.
             Assert.IsTrue(((CacheImpl<int, int>) cache.WithKeepBinary<int, int>().WithSkipStore()).IsKeepBinary);
         }
+#endif
 
         [Test]
         public void TestRebalance()
@@ -2550,5 +2553,26 @@ namespace Apache.Ignite.Core.Tests.Cache
 
             public Container Inner;
         }
+
+        private class ExpiryPolicyFactory : IFactory<IExpiryPolicy>
+        {
+            /** */
+            private readonly IExpiryPolicy _expiryPolicy;
+
+            /// <summary>
+            /// Initializes a new instance of the <see cref="ExpiryPolicyFactory"/> class.
+            /// </summary>
+            /// <param name="expiryPolicy">The expiry policy.</param>
+            public ExpiryPolicyFactory(IExpiryPolicy expiryPolicy)
+            {
+                _expiryPolicy = expiryPolicy;
+            }
+
+            /** <inheritdoc /> */
+            public IExpiryPolicy CreateInstance()
+            {
+                return _expiryPolicy;
+            }
+        }
     }
 }
index 63f5cd8..256c245 100644 (file)
@@ -130,8 +130,8 @@ namespace Apache.Ignite.Core.Tests.Cache
             var springConfig = _ignite.GetCache<int, int>(SpringCacheName).GetConfiguration();
 
             var ignoredProps = new[] {"AffinityFunction"};
-
-            TestUtils.AssertReflectionEqual(springConfig, new CacheConfiguration(SpringCacheName),
+            
+            AssertExtensions.ReflectionEqual(springConfig, new CacheConfiguration(SpringCacheName),
                 ignoredProperties: new HashSet<string>(ignoredProps));
             
             AssertConfigIsDefault(springConfig);
@@ -352,7 +352,7 @@ namespace Apache.Ignite.Core.Tests.Cache
                     y.PluginConfigurations.Select(p => p.GetType()));
             }
 
-            TestUtils.AssertReflectionEqual(x.KeyConfiguration, y.KeyConfiguration);
+            AssertExtensions.ReflectionEqual(x.KeyConfiguration, y.KeyConfiguration);
 
             Assert.AreEqual(x.OnheapCacheEnabled, y.OnheapCacheEnabled);
             Assert.AreEqual(x.StoreConcurrentLoadAllThreshold, y.StoreConcurrentLoadAllThreshold);
index b2e4d05..e2c5cef 100644 (file)
@@ -22,7 +22,6 @@ namespace Apache.Ignite.Core.Tests.Cache
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Configuration;
-    using Apache.Ignite.Core.Impl;
     using NUnit.Framework;
     using DataPageEvictionMode = Apache.Ignite.Core.Configuration.DataPageEvictionMode;
 
@@ -32,7 +31,7 @@ namespace Apache.Ignite.Core.Tests.Cache
     public class PersistenceTest
     {
         /** Temp dir for WAL. */
-        private readonly string _tempDir = IgniteUtils.GetTempDirectoryName();
+        private readonly string _tempDir = TestUtils.GetTempDirectoryName();
 
         /// <summary>
         /// Tears down the test.
index 172cb90..741dff0 100644 (file)
@@ -24,7 +24,6 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Cache.Query;
     using Apache.Ignite.Core.Common;
-    using Apache.Ignite.Core.Impl.Binary;
     using NUnit.Framework;
 
     /// <summary>
@@ -55,7 +54,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         /// </summary>
         protected virtual IBinaryNameMapper GetNameMapper()
         {
-            return BinaryBasicNameMapper.FullNameInstance;
+            return new BinaryBasicNameMapper {IsSimpleName = false};
         }
 
         /// <summary>
@@ -378,10 +377,9 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             Assert.AreEqual(key, cache.Single().Key);
 
             // Compare keys in binary form.
-            var binKey = cache.Ignite.GetBinary().ToBinary<BinaryObject>(key);
-            var binKeyRes = cache.WithKeepBinary<BinaryObject, string>().Single().Key;
+            var binKey = cache.Ignite.GetBinary().ToBinary<IBinaryObject>(key);
+            var binKeyRes = cache.WithKeepBinary<IBinaryObject, string>().Single().Key;
 
-            Assert.AreEqual(binKey.Header, binKeyRes.Header);
             Assert.AreEqual(binKey, binKeyRes);
 
             // Get by key to verify identity.
index 467d78f..159df94 100644 (file)
@@ -29,7 +29,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         /** <inheritdoc /> */
         protected override IBinaryNameMapper GetNameMapper()
         {
-            return BinaryBasicNameMapper.SimpleNameInstance;
+            return new BinaryBasicNameMapper {IsSimpleName = true};
         }
     }
 }
\ No newline at end of file
index 89185d4..8134b3d 100644 (file)
@@ -45,7 +45,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         private const string CacheName = "cache";
 
         /** Path to XML configuration. */
-        private const string CfgPath = "config\\cache-query.xml";
+        private const string CfgPath = "Config\\cache-query.xml";
 
         /** Maximum amount of items in cache. */
         private const int MaxItemCnt = 100;
@@ -75,7 +75,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         /// </summary>
         protected virtual IBinaryNameMapper GetNameMapper()
         {
-            return BinaryBasicNameMapper.FullNameInstance;
+            return new BinaryBasicNameMapper {IsSimpleName = false};
         }
 
         /// <summary>
index c8924bb..1f6a578 100644 (file)
@@ -29,7 +29,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         /** <inheritdoc /> */
         protected override IBinaryNameMapper GetNameMapper()
         {
-            return BinaryBasicNameMapper.SimpleNameInstance;
+            return new BinaryBasicNameMapper { IsSimpleName = true };
         }
     }
 }
\ No newline at end of file
index 9132de7..d70a7a4 100644 (file)
@@ -134,7 +134,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
         /// </summary>
         protected virtual IBinaryNameMapper GetNameMapper()
         {
-            return BinaryBasicNameMapper.FullNameInstance;
+            return new BinaryBasicNameMapper {IsSimpleName = false};
         }
 
         /// <summary>
index 35996b0..cb89a5b 100644 (file)
@@ -65,6 +65,8 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
             CheckFunc(x => x.Substring(4, 5), strings);
 
             CheckFunc(x => x.Trim(), strings);
+
+#if !NETCOREAPP2_0  // Trim is not supported on .NET Core
             CheckFunc(x => x.Trim('P'), strings);
             var toTrim = new[] { 'P' };
             CheckFunc(x => x.Trim(toTrim), strings);
@@ -81,6 +83,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
             Assert.Throws<NotSupportedException>(() => CheckFunc(x => x.Trim(toTrimFails), strings));
             Assert.Throws<NotSupportedException>(() => CheckFunc(x => x.TrimStart(toTrimFails), strings));
             Assert.Throws<NotSupportedException>(() => CheckFunc(x => x.TrimEnd(toTrimFails), strings));
+#endif
 
             CheckFunc(x => Regex.Replace(x, @"son.\d", "kele!"), strings);
             CheckFunc(x => Regex.Replace(x, @"son.\d", "kele!", RegexOptions.None), strings);
index 1665a64..57e0c81 100644 (file)
@@ -29,7 +29,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
         /** <inheritdoc /> */
         protected override IBinaryNameMapper GetNameMapper()
         {
-            return BinaryBasicNameMapper.SimpleNameInstance;
+            return new BinaryBasicNameMapper {IsSimpleName = true};
         }
     }
 }
\ No newline at end of file
index cfdce73..106f448 100644 (file)
@@ -25,7 +25,6 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Client;
-    using Apache.Ignite.Core.Impl.Client;
     using NUnit.Framework;
 
     /// <summary>
@@ -841,7 +840,9 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
                 var ex = Assert.Throws<IgniteClientException>(() => cache.Put(1, 1));
 
                 Assert.AreEqual("Cache doesn't exist: foobar", ex.Message);
-                Assert.AreEqual((int) ClientStatus.CacheDoesNotExist, ex.ErrorCode);
+#if !NETCOREAPP2_0
+                Assert.AreEqual((int) Impl.Client.ClientStatus.CacheDoesNotExist, ex.ErrorCode);
+#endif
             }
         }
 
index 381f924..41770b8 100644 (file)
@@ -185,7 +185,7 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
                 }
             }
 
-            TestUtils.AssertReflectionEqual(cfg, cfg2);
+            AssertExtensions.ReflectionEqual(cfg, cfg2);
         }
 
         /// <summary>
index c92fbac..5e2ccf4 100644 (file)
@@ -81,7 +81,7 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
         {
             // No template: default configuration.
             var cache = Client.CreateCache<int, int>("foobar");
-            TestUtils.AssertReflectionEqual(new CacheClientConfiguration("foobar"), cache.GetConfiguration());
+            AssertExtensions.ReflectionEqual(new CacheClientConfiguration("foobar"), cache.GetConfiguration());
 
             // Create when exists.
             var ex = Assert.Throws<IgniteClientException>(() => Client.CreateCache<int, int>(cache.Name));
@@ -105,7 +105,7 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
         {
             // No template: default configuration.
             var cache = Client.GetOrCreateCache<int, int>("foobar");
-            TestUtils.AssertReflectionEqual(new CacheClientConfiguration { Name = "foobar"}, cache.GetConfiguration());
+            AssertExtensions.ReflectionEqual(new CacheClientConfiguration { Name = "foobar"}, cache.GetConfiguration());
             cache[1] = 1;
 
             // Create when exists.
@@ -134,7 +134,7 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
             // Default config.
             var cfg = new CacheClientConfiguration("a");
             var cache = Client.CreateCache<int, int>(cfg);
-            TestUtils.AssertReflectionEqual(cfg, cache.GetConfiguration());
+            AssertExtensions.ReflectionEqual(cfg, cache.GetConfiguration());
 
             // Create when exists.
             var ex = Assert.Throws<IgniteClientException>(() => Client.CreateCache<int, int>(cfg));
@@ -158,7 +158,7 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
             // Default configur.
             var cfg = new CacheClientConfiguration("a");
             var cache = Client.GetOrCreateCache<int, int>(cfg);
-            TestUtils.AssertReflectionEqual(cfg, cache.GetConfiguration());
+            AssertExtensions.ReflectionEqual(cfg, cache.GetConfiguration());
             cache[1] = 1;
 
             // Create when exists.
index 17a2b3f..0660a20 100644 (file)
@@ -26,7 +26,6 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
     using Apache.Ignite.Core.Cache.Query;
     using Apache.Ignite.Core.Client;
     using Apache.Ignite.Core.Configuration;
-    using Apache.Ignite.Core.Impl.Client;
     using NUnit.Framework;
 
     /// <summary>
@@ -121,9 +120,10 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
                 var clientCache = client.GetCache<int, Person>(CacheName);
 
                 // One result.
-                var single = clientCache.Query(new ScanQuery<int, Person>(new PersonFilter(x => x.Id == 3))).Single();
+                var single = clientCache.Query(new ScanQuery<int, Person>(new PersonKeyFilter(3))).Single();
                 Assert.AreEqual(3, single.Key);
 
+#if !NETCOREAPP2_0   // Serializing delegates is not supported on this platform.
                 // Multiple results.
                 var res = clientCache.Query(new ScanQuery<int, Person>(new PersonFilter(x => x.Name.Length == 1)))
                     .ToList();
@@ -132,9 +132,11 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
                 // No results.
                 res = clientCache.Query(new ScanQuery<int, Person>(new PersonFilter(x => x == null))).ToList();
                 Assert.AreEqual(0, res.Count);
+#endif
             }
         }
 
+#if !NETCOREAPP2_0   // Serializing delegates and exceptions is not supported on this platform.
         /// <summary>
         /// Tests the exception in filter.
         /// </summary>
@@ -156,6 +158,7 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
                 Assert.AreEqual("foo", ex.Message);
             }
         }
+#endif
 
         /// <summary>
         /// Tests multiple cursors with the same client.
@@ -179,7 +182,9 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
                 // MaxCursors = 3
                 var ex = Assert.Throws<IgniteClientException>(() => clientCache.Query(qry));
                 Assert.AreEqual("Too many open cursors", ex.Message.Substring(0, 21));
-                Assert.AreEqual((int) ClientStatus.TooManyCursors, ex.ErrorCode);
+#if !NETCOREAPP2_0
+                Assert.AreEqual((int) Impl.Client.ClientStatus.TooManyCursors, ex.ErrorCode);
+#endif
 
                 var count = 0;
 
@@ -261,5 +266,28 @@ namespace Apache.Ignite.Core.Tests.Client.Cache
                 return _filter(entry.Value);
             }
         }
+
+        /// <summary>
+        /// Person filter.
+        /// </summary>
+        private class PersonKeyFilter : ICacheEntryFilter<int, Person>
+        {
+            /** Key. */
+            private readonly int _key;
+
+            /// <summary>
+            /// Initializes a new instance of the <see cref="PersonFilter"/> class.
+            /// </summary>
+            public PersonKeyFilter(int key)
+            {
+                _key = key;
+            }
+
+            /** <inheritdoc /> */
+            public bool Invoke(ICacheEntry<int, Person> entry)
+            {
+                return entry.Key == _key;
+            }
+        }
     }
 }
index 66aa844..d965b72 100644 (file)
@@ -23,7 +23,6 @@ namespace Apache.Ignite.Core.Tests.Client
     using System.Net.Sockets;
     using Apache.Ignite.Core.Client;
     using Apache.Ignite.Core.Configuration;
-    using Apache.Ignite.Core.Impl.Client;
     using NUnit.Framework;
 
     /// <summary>
@@ -108,6 +107,7 @@ namespace Apache.Ignite.Core.Tests.Client
             Assert.Throws<ArgumentNullException>(() => Ignition.StartClient(new IgniteClientConfiguration()));
         }
 
+#if !NETCOREAPP2_0
         /// <summary>
         /// Tests the incorrect protocol version error.
         /// </summary>
@@ -118,15 +118,17 @@ namespace Apache.Ignite.Core.Tests.Client
             using (Ignition.Start(TestUtils.GetTestConfiguration()))
             {
                 // ReSharper disable once ObjectCreationAsStatement
-                var ex = Assert.Throws<IgniteClientException>(() => new ClientSocket(GetClientConfiguration(),
-                    new ClientProtocolVersion(-1, -1, -1)));
+                var ex = Assert.Throws<IgniteClientException>(() =>
+                    new Impl.Client.ClientSocket(GetClientConfiguration(),
+                    new Impl.Client.ClientProtocolVersion(-1, -1, -1)));
 
-                Assert.AreEqual((int) ClientStatus.Fail, ex.ErrorCode);
+                Assert.AreEqual((int) Impl.Client.ClientStatus.Fail, ex.ErrorCode);
 
                 Assert.AreEqual("Client handhsake failed: 'Unsupported version.'. " +
                                 "Client version: -1.-1.-1. Server version: 1.0.0", ex.Message);
             }
         }
+#endif
 
         /// <summary>
         /// Tests that connector can be disabled.
@@ -148,7 +150,7 @@ namespace Apache.Ignite.Core.Tests.Client
             {
                 var ex = Assert.Throws<AggregateException>(() => Ignition.StartClient(clientCfg));
                 Assert.AreEqual("Failed to establish Ignite thin client connection, " +
-                                "examine inner exceptions for details.", ex.Message);
+                                "examine inner exceptions for details.", ex.Message.Substring(0, 88));
             }
         }
 
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.JavaTask.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.JavaTask.cs
new file mode 100644 (file)
index 0000000..1f5c3a3
--- /dev/null
@@ -0,0 +1,582 @@
+/*
+ * 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.
+ */
+
+// ReSharper disable SpecifyACultureInStringConversionExplicitly
+namespace Apache.Ignite.Core.Tests.Compute
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Impl.Binary;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Compute tests with Java tasks.
+    /// </summary>
+    public partial class ComputeApiTest
+    {
+        /** Echo task name. */
+        public const string EchoTask = "org.apache.ignite.platform.PlatformComputeEchoTask";
+
+        /** Binary argument task name. */
+        public const string BinaryArgTask = "org.apache.ignite.platform.PlatformComputeBinarizableArgTask";
+
+        /** Broadcast task name. */
+        public const string BroadcastTask = "org.apache.ignite.platform.PlatformComputeBroadcastTask";
+
+        /** Broadcast task name. */
+        private const string DecimalTask = "org.apache.ignite.platform.PlatformComputeDecimalTask";
+
+        /** Echo type: null. */
+        private const int EchoTypeNull = 0;
+
+        /** Echo type: byte. */
+        private const int EchoTypeByte = 1;
+
+        /** Echo type: bool. */
+        private const int EchoTypeBool = 2;
+
+        /** Echo type: short. */
+        private const int EchoTypeShort = 3;
+
+        /** Echo type: char. */
+        private const int EchoTypeChar = 4;
+
+        /** Echo type: int. */
+        private const int EchoTypeInt = 5;
+
+        /** Echo type: long. */
+        private const int EchoTypeLong = 6;
+
+        /** Echo type: float. */
+        private const int EchoTypeFloat = 7;
+
+        /** Echo type: double. */
+        private const int EchoTypeDouble = 8;
+
+        /** Echo type: array. */
+        private const int EchoTypeArray = 9;
+
+        /** Echo type: collection. */
+        private const int EchoTypeCollection = 10;
+
+        /** Echo type: map. */
+        private const int EchoTypeMap = 11;
+
+        /** Echo type: binarizable. */
+        public const int EchoTypeBinarizable = 12;
+
+        /** Echo type: binary (Java only). */
+        private const int EchoTypeBinarizableJava = 13;
+
+        /** Type: object array. */
+        private const int EchoTypeObjArray = 14;
+
+        /** Type: binary object array. */
+        private const int EchoTypeBinarizableArray = 15;
+
+        /** Type: enum. */
+        private const int EchoTypeEnum = 16;
+
+        /** Type: enum array. */
+        private const int EchoTypeEnumArray = 17;
+
+        /** Type: enum field. */
+        private const int EchoTypeEnumField = 18;
+
+        /** Type: affinity key. */
+        public const int EchoTypeAffinityKey = 19;
+
+        /** Type: enum from cache. */
+        private const int EchoTypeEnumFromCache = 20;
+
+        /** Type: enum array from cache. */
+        private const int EchoTypeEnumArrayFromCache = 21;
+
+        /** Echo type: IgniteUuid. */
+        private const int EchoTypeIgniteUuid = 22;
+
+        /** Echo type: binary enum (created with builder). */
+        private const int EchoTypeBinaryEnum = 23;
+
+        /// <summary>
+        /// Test echo with decimals.
+        /// </summary>
+        [Test]
+        public void TestEchoDecimal()
+        {
+            decimal val;
+
+            Assert.AreEqual(val = decimal.Zero, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = new decimal(0, 0, 1, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, 1, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, 1, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, 1, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, 1, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, 1, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = new decimal(0, 1, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 1, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 1, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 1, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 1, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, 1, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = new decimal(1, 0, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 0, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 0, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 0, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 0, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 0, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = new decimal(1, 1, 1, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 1, 1, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 1, 1, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 1, 1, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 1, 1, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = new decimal(1, 1, 1, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = decimal.Parse("65536"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-65536"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("65536") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-65536") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("65536") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-65536") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = decimal.Parse("4294967296"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-4294967296"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("4294967296") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-4294967296") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("4294967296") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-4294967296") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = decimal.Parse("281474976710656"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-281474976710656"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("281474976710656") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-281474976710656") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("281474976710656") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-281474976710656") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = decimal.Parse("18446744073709551616"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-18446744073709551616"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("18446744073709551616") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-18446744073709551616") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("18446744073709551616") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-18446744073709551616") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = decimal.Parse("1208925819614629174706176"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-1208925819614629174706176"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("1208925819614629174706176") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-1208925819614629174706176") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("1208925819614629174706176") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-1208925819614629174706176") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = decimal.MaxValue, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.MinValue, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.MaxValue - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.MinValue + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            Assert.AreEqual(val = decimal.Parse("11,12"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+            Assert.AreEqual(val = decimal.Parse("-11,12"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
+
+            // Test echo with overflow.
+            var ex = Assert.Throws<BinaryObjectException>(() => _grid1.GetCompute()
+                .ExecuteJavaTask<object>(DecimalTask, new object[] { null, decimal.MaxValue.ToString() + 1 }));
+
+            Assert.AreEqual("Decimal magnitude overflow (must be less than 96 bits): 104", ex.Message);
+
+            // Negative scale. 1E+1 parses to "1 scale -1" on Java side.
+            ex = Assert.Throws<BinaryObjectException>(() => _grid1.GetCompute()
+                .ExecuteJavaTask<object>(DecimalTask, new object[] { null, "1E+1" }));
+
+            Assert.AreEqual("Decimal value scale overflow (must be between 0 and 28): -1", ex.Message);
+        }
+
+        /// <summary>
+        /// Test echo task returning null.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskNull()
+        {
+            Assert.IsNull(_grid1.GetCompute().ExecuteJavaTask<object>(EchoTask, EchoTypeNull));
+        }
+
+        /// <summary>
+        /// Test echo task returning various primitives.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskPrimitives()
+        {
+            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<byte>(EchoTask, EchoTypeByte));
+            Assert.AreEqual(true, _grid1.GetCompute().ExecuteJavaTask<bool>(EchoTask, EchoTypeBool));
+            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<short>(EchoTask, EchoTypeShort));
+            Assert.AreEqual((char)1, _grid1.GetCompute().ExecuteJavaTask<char>(EchoTask, EchoTypeChar));
+            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<int>(EchoTask, EchoTypeInt));
+            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<long>(EchoTask, EchoTypeLong));
+            Assert.AreEqual((float)1, _grid1.GetCompute().ExecuteJavaTask<float>(EchoTask, EchoTypeFloat));
+            Assert.AreEqual((double)1, _grid1.GetCompute().ExecuteJavaTask<double>(EchoTask, EchoTypeDouble));
+        }
+
+        /// <summary>
+        /// Test echo task returning compound types.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskCompound()
+        {
+            int[] res1 = _grid1.GetCompute().ExecuteJavaTask<int[]>(EchoTask, EchoTypeArray);
+
+            Assert.AreEqual(1, res1.Length);
+            Assert.AreEqual(1, res1[0]);
+
+            var res2 = _grid1.GetCompute().ExecuteJavaTask<IList>(EchoTask, EchoTypeCollection);
+
+            Assert.AreEqual(1, res2.Count);
+            Assert.AreEqual(1, res2[0]);
+
+            var res3 = _grid1.GetCompute().ExecuteJavaTask<IDictionary>(EchoTask, EchoTypeMap);
+
+            Assert.AreEqual(1, res3.Count);
+            Assert.AreEqual(1, res3[1]);
+        }
+
+        /// <summary>
+        /// Test echo task returning binary object.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskBinarizable()
+        {
+            var values = new[] { int.MinValue, int.MaxValue, 0, 1, -1, byte.MaxValue, byte.MinValue };
+            var cache = _grid1.GetCache<int, int>(DefaultCacheName);
+            var compute = _grid1.GetCompute();
+
+            foreach (var val in values)
+            {
+                cache[EchoTypeBinarizable] = val;
+
+                var res = compute.ExecuteJavaTask<PlatformComputeBinarizable>(EchoTask, EchoTypeBinarizable);
+                Assert.AreEqual(val, res.Field);
+
+                // Binary mode.
+                var binRes = compute.WithKeepBinary().ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinarizable);
+
+                Assert.AreEqual(val, binRes.GetField<long>("Field"));
+
+#if !NETCOREAPP2_0
+                var dotNetBin = _grid1.GetBinary().ToBinary<BinaryObject>(res);
+
+                Assert.AreEqual(dotNetBin.Header.HashCode, ((BinaryObject)binRes).Header.HashCode);
+
+                Func<BinaryObject, byte[]> getData = bo => bo.Data.Skip(bo.Offset).Take(bo.Header.Length).ToArray();
+                Assert.AreEqual(getData(dotNetBin), getData((BinaryObject)binRes));
+#endif
+            }
+        }
+
+        /// <summary>
+        /// Test echo task returning binary object with no corresponding class definition.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskBinarizableNoClass()
+        {
+            ICompute compute = _grid1.GetCompute();
+
+            compute.WithKeepBinary();
+
+            IBinaryObject res = compute.ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinarizableJava);
+
+            Assert.AreEqual(1, res.GetField<int>("field"));
+
+            // This call must fail because "keepBinary" flag is reset.
+            var ex = Assert.Throws<BinaryObjectException>(() =>
+            {
+                compute.ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinarizableJava);
+            });
+
+            Assert.AreEqual("Unknown pair [platformId=1, typeId=2009791293]", ex.Message);
+        }
+
+        /// <summary>
+        /// Tests the echo task returning object array.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskObjectArray()
+        {
+            var res = _grid1.GetCompute().ExecuteJavaTask<string[]>(EchoTask, EchoTypeObjArray);
+
+            Assert.AreEqual(new[] { "foo", "bar", "baz" }, res);
+        }
+
+        /// <summary>
+        /// Tests the echo task returning binary array.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskBinarizableArray()
+        {
+            var res = _grid1.GetCompute().ExecuteJavaTask<object[]>(EchoTask, EchoTypeBinarizableArray);
+
+            Assert.AreEqual(3, res.Length);
+
+            for (var i = 0; i < res.Length; i++)
+                Assert.AreEqual(i + 1, ((PlatformComputeBinarizable)res[i]).Field);
+        }
+
+        /// <summary>
+        /// Tests the echo task returning enum.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskEnum()
+        {
+            var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnum);
+
+            Assert.AreEqual(PlatformComputeEnum.Bar, res);
+        }
+
+        /// <summary>
+        /// Tests the echo task returning enum.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskBinaryEnum()
+        {
+            var res = _grid1.GetCompute().WithKeepBinary()
+                .ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinaryEnum);
+
+            Assert.AreEqual("JavaFoo", res.EnumName);
+            Assert.AreEqual(1, res.EnumValue);
+
+            var binType = res.GetBinaryType();
+
+            Assert.IsTrue(binType.IsEnum);
+            Assert.AreEqual("JavaDynEnum", binType.TypeName);
+
+            var vals = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+            Assert.AreEqual(new[] { 1, 2 }, vals.Select(x => x.EnumValue));
+            Assert.AreEqual(new[] { "JavaFoo", "JavaBar" }, vals.Select(x => x.EnumName));
+        }
+
+        /// <summary>
+        /// Tests the echo task returning enum.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskEnumFromCache()
+        {
+            var cache = _grid1.GetCache<int, PlatformComputeEnum>(DefaultCacheName);
+
+            foreach (PlatformComputeEnum val in Enum.GetValues(typeof(PlatformComputeEnum)))
+            {
+                cache[EchoTypeEnumFromCache] = val;
+
+                var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnumFromCache);
+
+                Assert.AreEqual(val, res);
+            }
+        }
+
+        /// <summary>
+        /// Tests the echo task returning enum.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskEnumArray()
+        {
+            var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum[]>(EchoTask, EchoTypeEnumArray);
+
+            Assert.AreEqual(new[]
+            {
+                PlatformComputeEnum.Bar,
+                PlatformComputeEnum.Baz,
+                PlatformComputeEnum.Foo
+            }, res);
+        }
+
+        /// <summary>
+        /// Tests the echo task returning enum.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskEnumArrayFromCache()
+        {
+            var cache = _grid1.GetCache<int, PlatformComputeEnum[]>(DefaultCacheName);
+
+            foreach (var val in new[]
+            {
+                new[] {PlatformComputeEnum.Bar, PlatformComputeEnum.Baz, PlatformComputeEnum.Foo },
+                new[] {PlatformComputeEnum.Foo, PlatformComputeEnum.Baz},
+                new[] {PlatformComputeEnum.Bar}
+            })
+            {
+                cache[EchoTypeEnumArrayFromCache] = val;
+
+                var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum[]>(
+                    EchoTask, EchoTypeEnumArrayFromCache);
+
+                Assert.AreEqual(val, res);
+            }
+        }
+
+        /// <summary>
+        /// Tests the echo task reading enum from a binary object field.
+        /// Ensures that Java can understand enums written by .NET.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskEnumField()
+        {
+            var enumVal = PlatformComputeEnum.Baz;
+
+            _grid1.GetCache<int, InteropComputeEnumFieldTest>(DefaultCacheName)
+                .Put(EchoTypeEnumField, new InteropComputeEnumFieldTest { InteropEnum = enumVal });
+
+            var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnumField);
+
+            var enumMeta = _grid1.GetBinary().GetBinaryType(typeof(PlatformComputeEnum));
+
+            Assert.IsTrue(enumMeta.IsEnum);
+            Assert.AreEqual(enumMeta.TypeName, typeof(PlatformComputeEnum).Name);
+            Assert.AreEqual(0, enumMeta.Fields.Count);
+
+            Assert.AreEqual(enumVal, res);
+        }
+
+        /// <summary>
+        /// Tests that IgniteGuid in .NET maps to IgniteUuid in Java.
+        /// </summary>
+        [Test]
+        public void TestEchoTaskIgniteUuid()
+        {
+            var guid = Guid.NewGuid();
+
+            _grid1.GetCache<int, object>(DefaultCacheName)[EchoTypeIgniteUuid] = new IgniteGuid(guid, 25);
+
+            var res = _grid1.GetCompute().ExecuteJavaTask<IgniteGuid>(EchoTask, EchoTypeIgniteUuid);
+
+            Assert.AreEqual(guid, res.GlobalId);
+            Assert.AreEqual(25, res.LocalId);
+        }
+
+        /// <summary>
+        /// Test for binary argument in Java.
+        /// </summary>
+        [Test]
+        public void TestBinarizableArgTask()
+        {
+            ICompute compute = _grid1.GetCompute();
+
+            compute.WithKeepBinary();
+
+            PlatformComputeNetBinarizable arg = new PlatformComputeNetBinarizable { Field = 100 };
+
+            int res = compute.ExecuteJavaTask<int>(BinaryArgTask, arg);
+
+            Assert.AreEqual(arg.Field, res);
+        }
+
+        /// <summary>
+        /// Test running broadcast task.
+        /// </summary>
+        [Test]
+        public void TestBroadcastTask([Values(false, true)] bool isAsync)
+        {
+            var execTask =
+                isAsync
+                    ? (Func<ICompute, List<Guid>>)(
+                        c => c.ExecuteJavaTaskAsync<ICollection>(BroadcastTask, null).Result.OfType<Guid>().ToList())
+                    : c => c.ExecuteJavaTask<ICollection>(BroadcastTask, null).OfType<Guid>().ToList();
+
+            var res = execTask(_grid1.GetCompute());
+
+            Assert.AreEqual(2, res.Count);
+            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
+            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(1)).GetNodes().Count);
+
+            var prj = _grid1.GetCluster().ForPredicate(node => res.Take(2).Contains(node.Id));
+
+            Assert.AreEqual(2, prj.GetNodes().Count);
+
+            var filteredRes = execTask(prj.GetCompute());
+
+            Assert.AreEqual(2, filteredRes.Count);
+            Assert.IsTrue(filteredRes.Contains(res.ElementAt(0)));
+            Assert.IsTrue(filteredRes.Contains(res.ElementAt(1)));
+        }
+
+        /// <summary>
+        /// Test "withNoFailover" feature.
+        /// </summary>
+        [Test]
+        public void TestWithNoFailover()
+        {
+            var res = _grid1.GetCompute().WithNoFailover().ExecuteJavaTask<ICollection>(BroadcastTask, null)
+                .OfType<Guid>().ToList();
+
+            Assert.AreEqual(2, res.Count);
+            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
+            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(1)).GetNodes().Count);
+        }
+
+        /// <summary>
+        /// Test "withTimeout" feature.
+        /// </summary>
+        [Test]
+        public void TestWithTimeout()
+        {
+            var res = _grid1.GetCompute().WithTimeout(1000).ExecuteJavaTask<ICollection>(BroadcastTask, null)
+                .OfType<Guid>().ToList();
+
+            Assert.AreEqual(2, res.Count);
+            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
+            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(1)).GetNodes().Count);
+        }
+    }
+}
index 80d8716..6c4c00a 100644 (file)
  * limitations under the License.
  */
 
-// ReSharper disable SpecifyACultureInStringConversionExplicitly
 // ReSharper disable UnusedAutoPropertyAccessor.Global
 namespace Apache.Ignite.Core.Tests.Compute
 {
     using System;
-    using System.Collections;
     using System.Collections.Concurrent;
     using System.Collections.Generic;
     using System.Linq;
     using System.Threading;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cluster;
-    using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Compute;
     using Apache.Ignite.Core.Events;
-    using Apache.Ignite.Core.Impl;
-    using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Resource;
     using NUnit.Framework;
 
     /// <summary>
     /// Tests for compute.
     /// </summary>
-    public class ComputeApiTest
+    public partial class ComputeApiTest
     {
-        /** Echo task name. */
-        public const string EchoTask = "org.apache.ignite.platform.PlatformComputeEchoTask";
-
-        /** Binary argument task name. */
-        public const string BinaryArgTask = "org.apache.ignite.platform.PlatformComputeBinarizableArgTask";
-
-        /** Broadcast task name. */
-        public const string BroadcastTask = "org.apache.ignite.platform.PlatformComputeBroadcastTask";
-
-        /** Broadcast task name. */
-        private const string DecimalTask = "org.apache.ignite.platform.PlatformComputeDecimalTask";
-
         /** Java binary class name. */
         private const string JavaBinaryCls = "PlatformComputeJavaBinarizable";
 
-        /** Echo type: null. */
-        private const int EchoTypeNull = 0;
-
-        /** Echo type: byte. */
-        private const int EchoTypeByte = 1;
-
-        /** Echo type: bool. */
-        private const int EchoTypeBool = 2;
-
-        /** Echo type: short. */
-        private const int EchoTypeShort = 3;
-
-        /** Echo type: char. */
-        private const int EchoTypeChar = 4;
-
-        /** Echo type: int. */
-        private const int EchoTypeInt = 5;
-
-        /** Echo type: long. */
-        private const int EchoTypeLong = 6;
-
-        /** Echo type: float. */
-        private const int EchoTypeFloat = 7;
-
-        /** Echo type: double. */
-        private const int EchoTypeDouble = 8;
-
-        /** Echo type: array. */
-        private const int EchoTypeArray = 9;
-
-        /** Echo type: collection. */
-        private const int EchoTypeCollection = 10;
-
-        /** Echo type: map. */
-        private const int EchoTypeMap = 11;
-
-        /** Echo type: binarizable. */
-        public const int EchoTypeBinarizable = 12;
-
-        /** Echo type: binary (Java only). */
-        private const int EchoTypeBinarizableJava = 13;
-
-        /** Type: object array. */
-        private const int EchoTypeObjArray = 14;
-
-        /** Type: binary object array. */
-        private const int EchoTypeBinarizableArray = 15;
-
-        /** Type: enum. */
-        private const int EchoTypeEnum = 16;
-
-        /** Type: enum array. */
-        private const int EchoTypeEnumArray = 17;
-
-        /** Type: enum field. */
-        private const int EchoTypeEnumField = 18;
-
-        /** Type: affinity key. */
-        public const int EchoTypeAffinityKey = 19;
-
-        /** Type: enum from cache. */
-        private const int EchoTypeEnumFromCache = 20;
-
-        /** Type: enum array from cache. */
-        private const int EchoTypeEnumArrayFromCache = 21;
-                
-        /** Echo type: IgniteUuid. */
-        private const int EchoTypeIgniteUuid = 22;
-
-        /** Echo type: binary enum (created with builder). */
-        private const int EchoTypeBinaryEnum = 23;
-
         /** */
         private const string DefaultCacheName = "default";
 
@@ -145,8 +56,6 @@ namespace Apache.Ignite.Core.Tests.Compute
         [TestFixtureSetUp]
         public void InitClient()
         {
-            TestUtils.KillProcesses();
-
             var configs = GetConfigs();
 
             _grid1 = Ignition.Start(Configuration(configs.Item1));
@@ -165,9 +74,9 @@ namespace Apache.Ignite.Core.Tests.Compute
         protected virtual Tuple<string, string, string> GetConfigs()
         {
             return Tuple.Create(
-                "config\\compute\\compute-grid1.xml",
-                "config\\compute\\compute-grid2.xml",
-                "config\\compute\\compute-grid3.xml");
+                "Config\\Compute\\compute-grid1.xml",
+                "Config\\Compute\\compute-grid2.xml",
+                "Config\\Compute\\compute-grid3.xml");
         }
 
         /// <summary>
@@ -699,437 +608,7 @@ namespace Apache.Ignite.Core.Tests.Compute
             }
         }
 
-        /// <summary>
-        /// Test echo with decimals.
-        /// </summary>
-        [Test]
-        public void TestEchoDecimal()
-        {
-            decimal val;
-
-            Assert.AreEqual(val = decimal.Zero, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = new decimal(0, 0, 1, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, 1, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, 1, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, 1, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, 1, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, 1, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MinValue, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 0, int.MaxValue, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = new decimal(0, 1, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 1, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 1, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 1, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 1, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, 1, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MinValue, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(0, int.MaxValue, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = new decimal(1, 0, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 0, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 0, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 0, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 0, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 0, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MinValue, 0, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(int.MaxValue, 0, 0, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = new decimal(1, 1, 1, false, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 1, 1, true, 0), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 1, 1, false, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 1, 1, true, 0) - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 1, 1, false, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = new decimal(1, 1, 1, true, 0) + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = decimal.Parse("65536"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-65536"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("65536") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-65536") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("65536") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-65536") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = decimal.Parse("4294967296"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-4294967296"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("4294967296") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-4294967296") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("4294967296") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-4294967296") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = decimal.Parse("281474976710656"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-281474976710656"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("281474976710656") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-281474976710656") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("281474976710656") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-281474976710656") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = decimal.Parse("18446744073709551616"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-18446744073709551616"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("18446744073709551616") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-18446744073709551616") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("18446744073709551616") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-18446744073709551616") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = decimal.Parse("1208925819614629174706176"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-1208925819614629174706176"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("1208925819614629174706176") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-1208925819614629174706176") - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("1208925819614629174706176") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-1208925819614629174706176") + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = decimal.MaxValue, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.MinValue, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.MaxValue - 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.MinValue + 1, _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            Assert.AreEqual(val = decimal.Parse("11,12"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-            Assert.AreEqual(val = decimal.Parse("-11,12"), _grid1.GetCompute().ExecuteJavaTask<object>(DecimalTask, new object[] { val, val.ToString() }));
-
-            // Test echo with overflow.
-            var ex = Assert.Throws<BinaryObjectException>(() => _grid1.GetCompute()
-                .ExecuteJavaTask<object>(DecimalTask, new object[] {null, decimal.MaxValue.ToString() + 1}));
-
-            Assert.AreEqual("Decimal magnitude overflow (must be less than 96 bits): 104", ex.Message);
-
-            // Negative scale. 1E+1 parses to "1 scale -1" on Java side.
-            ex = Assert.Throws<BinaryObjectException>(() => _grid1.GetCompute()
-                .ExecuteJavaTask<object>(DecimalTask, new object[] {null, "1E+1"}));
-
-            Assert.AreEqual("Decimal value scale overflow (must be between 0 and 28): -1", ex.Message);
-        }
-
-        /// <summary>
-        /// Test echo task returning null.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskNull()
-        {
-            Assert.IsNull(_grid1.GetCompute().ExecuteJavaTask<object>(EchoTask, EchoTypeNull));
-        }
-
-        /// <summary>
-        /// Test echo task returning various primitives.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskPrimitives()
-        {
-            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<byte>(EchoTask, EchoTypeByte));
-            Assert.AreEqual(true, _grid1.GetCompute().ExecuteJavaTask<bool>(EchoTask, EchoTypeBool));
-            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<short>(EchoTask, EchoTypeShort));
-            Assert.AreEqual((char)1, _grid1.GetCompute().ExecuteJavaTask<char>(EchoTask, EchoTypeChar));
-            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<int>(EchoTask, EchoTypeInt));
-            Assert.AreEqual(1, _grid1.GetCompute().ExecuteJavaTask<long>(EchoTask, EchoTypeLong));
-            Assert.AreEqual((float)1, _grid1.GetCompute().ExecuteJavaTask<float>(EchoTask, EchoTypeFloat));
-            Assert.AreEqual((double)1, _grid1.GetCompute().ExecuteJavaTask<double>(EchoTask, EchoTypeDouble));
-        }
-
-        /// <summary>
-        /// Test echo task returning compound types.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskCompound()
-        {
-            int[] res1 = _grid1.GetCompute().ExecuteJavaTask<int[]>(EchoTask, EchoTypeArray);
-
-            Assert.AreEqual(1, res1.Length);
-            Assert.AreEqual(1, res1[0]);
-
-            var res2 = _grid1.GetCompute().ExecuteJavaTask<IList>(EchoTask, EchoTypeCollection);
-
-            Assert.AreEqual(1, res2.Count);
-            Assert.AreEqual(1, res2[0]);
-
-            var res3 = _grid1.GetCompute().ExecuteJavaTask<IDictionary>(EchoTask, EchoTypeMap);
-
-            Assert.AreEqual(1, res3.Count);
-            Assert.AreEqual(1, res3[1]);
-        }
-
-        /// <summary>
-        /// Test echo task returning binary object.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskBinarizable()
-        {
-            var values = new[] {int.MinValue, int.MaxValue, 0, 1, -1, byte.MaxValue, byte.MinValue};
-            var cache = _grid1.GetCache<int, int>(DefaultCacheName);
-            var compute = _grid1.GetCompute();
-
-            foreach (var val in values)
-            {
-                cache[EchoTypeBinarizable] = val;
-
-                var res = compute.ExecuteJavaTask<PlatformComputeBinarizable>(EchoTask, EchoTypeBinarizable);
-                Assert.AreEqual(val, res.Field);
-
-                // Binary mode.
-                var binRes = compute.WithKeepBinary().ExecuteJavaTask<BinaryObject>(EchoTask, EchoTypeBinarizable);
-
-                Assert.AreEqual(val, binRes.GetField<long>("Field"));
-
-                var dotNetBin = _grid1.GetBinary().ToBinary<BinaryObject>(res);
-
-                Assert.AreEqual(dotNetBin.Header.HashCode, binRes.Header.HashCode);
-
-                Func<BinaryObject, byte[]> getData = bo => bo.Data.Skip(bo.Offset).Take(bo.Header.Length).ToArray();
-                Assert.AreEqual(getData(dotNetBin), getData(binRes));
-            }
-        }
-
-        /// <summary>
-        /// Test echo task returning binary object with no corresponding class definition.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskBinarizableNoClass()
-        {
-            ICompute compute = _grid1.GetCompute();
-
-            compute.WithKeepBinary();
-
-            IBinaryObject res = compute.ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinarizableJava);
-
-            Assert.AreEqual(1, res.GetField<int>("field"));
-
-            // This call must fail because "keepBinary" flag is reset.
-            var ex = Assert.Throws<BinaryObjectException>(() =>
-            {
-                compute.ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinarizableJava);
-            });
-
-            Assert.AreEqual("Unknown pair [platformId=1, typeId=2009791293]", ex.Message);
-        }
-
-        /// <summary>
-        /// Tests the echo task returning object array.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskObjectArray()
-        {
-            var res = _grid1.GetCompute().ExecuteJavaTask<string[]>(EchoTask, EchoTypeObjArray);
-            
-            Assert.AreEqual(new[] {"foo", "bar", "baz"}, res);
-        }
-
-        /// <summary>
-        /// Tests the echo task returning binary array.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskBinarizableArray()
-        {
-            var res = _grid1.GetCompute().ExecuteJavaTask<object[]>(EchoTask, EchoTypeBinarizableArray);
-            
-            Assert.AreEqual(3, res.Length);
-
-            for (var i = 0; i < res.Length; i++)
-                Assert.AreEqual(i + 1, ((PlatformComputeBinarizable) res[i]).Field);
-        }
-
-        /// <summary>
-        /// Tests the echo task returning enum.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskEnum()
-        {
-            var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnum);
-
-            Assert.AreEqual(PlatformComputeEnum.Bar, res);
-        }
-
-        /// <summary>
-        /// Tests the echo task returning enum.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskBinaryEnum()
-        {
-            var res = _grid1.GetCompute().WithKeepBinary()
-                .ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinaryEnum);
-
-            Assert.AreEqual("JavaFoo", res.EnumName);
-            Assert.AreEqual(1, res.EnumValue);
-
-            var binType = res.GetBinaryType();
-
-            Assert.IsTrue(binType.IsEnum);
-            Assert.AreEqual("JavaDynEnum", binType.TypeName);
-
-            var vals = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
-            Assert.AreEqual(new[] {1, 2}, vals.Select(x => x.EnumValue));
-            Assert.AreEqual(new[] {"JavaFoo", "JavaBar"}, vals.Select(x => x.EnumName));
-        }
-
-        /// <summary>
-        /// Tests the echo task returning enum.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskEnumFromCache()
-        {
-            var cache = _grid1.GetCache<int, PlatformComputeEnum>(DefaultCacheName);
-
-            foreach (PlatformComputeEnum val in Enum.GetValues(typeof(PlatformComputeEnum)))
-            {
-                cache[EchoTypeEnumFromCache] = val;
-
-                var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnumFromCache);
-
-                Assert.AreEqual(val, res);
-            }
-        }
-
-        /// <summary>
-        /// Tests the echo task returning enum.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskEnumArray()
-        {
-            var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum[]>(EchoTask, EchoTypeEnumArray);
-
-            Assert.AreEqual(new[]
-            {
-                PlatformComputeEnum.Bar,
-                PlatformComputeEnum.Baz,
-                PlatformComputeEnum.Foo
-            }, res);
-        }
-
-        /// <summary>
-        /// Tests the echo task returning enum.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskEnumArrayFromCache()
-        {
-            var cache = _grid1.GetCache<int, PlatformComputeEnum[]>(DefaultCacheName);
-
-            foreach (var val in new[]
-            {
-                new[] {PlatformComputeEnum.Bar, PlatformComputeEnum.Baz, PlatformComputeEnum.Foo },
-                new[] {PlatformComputeEnum.Foo, PlatformComputeEnum.Baz},
-                new[] {PlatformComputeEnum.Bar}
-            })
-            {
-                cache[EchoTypeEnumArrayFromCache] = val;
-
-                var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum[]>(
-                    EchoTask, EchoTypeEnumArrayFromCache);
-
-                Assert.AreEqual(val, res);
-            }
-        }
-
-        /// <summary>
-        /// Tests the echo task reading enum from a binary object field.
-        /// Ensures that Java can understand enums written by .NET.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskEnumField()
-        {
-            var enumVal = PlatformComputeEnum.Baz;
-
-            _grid1.GetCache<int, InteropComputeEnumFieldTest>(DefaultCacheName)
-                .Put(EchoTypeEnumField, new InteropComputeEnumFieldTest {InteropEnum = enumVal});
-
-            var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnumField);
-
-            var enumMeta = _grid1.GetBinary().GetBinaryType(typeof (PlatformComputeEnum));
-
-            Assert.IsTrue(enumMeta.IsEnum);
-            Assert.AreEqual(enumMeta.TypeName, typeof(PlatformComputeEnum).Name);
-            Assert.AreEqual(0, enumMeta.Fields.Count);
-
-            Assert.AreEqual(enumVal, res);
-        }
-
-        /// <summary>
-        /// Tests that IgniteGuid in .NET maps to IgniteUuid in Java.
-        /// </summary>
-        [Test]
-        public void TestEchoTaskIgniteUuid()
-        {
-            var guid = Guid.NewGuid();
-
-            _grid1.GetCache<int, object>(DefaultCacheName)[EchoTypeIgniteUuid] = new IgniteGuid(guid, 25);
-
-            var res = _grid1.GetCompute().ExecuteJavaTask<IgniteGuid>(EchoTask, EchoTypeIgniteUuid);
-
-            Assert.AreEqual(guid, res.GlobalId);
-            Assert.AreEqual(25, res.LocalId);
-        }
-
-        /// <summary>
-        /// Test for binary argument in Java.
-        /// </summary>
-        [Test]
-        public void TestBinarizableArgTask()
-        {
-            ICompute compute = _grid1.GetCompute();
-
-            compute.WithKeepBinary();
 
-            PlatformComputeNetBinarizable arg = new PlatformComputeNetBinarizable {Field = 100};
-
-            int res = compute.ExecuteJavaTask<int>(BinaryArgTask, arg);
-
-            Assert.AreEqual(arg.Field, res);
-        }
-
-        /// <summary>
-        /// Test running broadcast task.
-        /// </summary>
-        [Test]
-        public void TestBroadcastTask([Values(false, true)] bool isAsync)
-        {
-            var execTask =
-                isAsync
-                    ? (Func<ICompute, List<Guid>>) (
-                        c => c.ExecuteJavaTaskAsync<ICollection>(BroadcastTask, null).Result.OfType<Guid>().ToList())
-                    : c => c.ExecuteJavaTask<ICollection>(BroadcastTask, null).OfType<Guid>().ToList();
-
-            var res = execTask(_grid1.GetCompute());
-
-            Assert.AreEqual(2, res.Count);
-            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
-            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(1)).GetNodes().Count);
-
-            var prj = _grid1.GetCluster().ForPredicate(node => res.Take(2).Contains(node.Id));
-
-            Assert.AreEqual(2, prj.GetNodes().Count);
-
-            var filteredRes = execTask(prj.GetCompute());
-
-            Assert.AreEqual(2, filteredRes.Count);
-            Assert.IsTrue(filteredRes.Contains(res.ElementAt(0)));
-            Assert.IsTrue(filteredRes.Contains(res.ElementAt(1)));
-        }
 
         /// <summary>
         /// Tests the action broadcast.
@@ -1259,34 +738,6 @@ namespace Apache.Ignite.Core.Tests.Compute
         }
 
         /// <summary>
-        /// Test "withNoFailover" feature.
-        /// </summary>
-        [Test]
-        public void TestWithNoFailover()
-        {
-            var res = _grid1.GetCompute().WithNoFailover().ExecuteJavaTask<ICollection>(BroadcastTask, null)
-                .OfType<Guid>().ToList();
-
-            Assert.AreEqual(2, res.Count);
-            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
-            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(1)).GetNodes().Count);
-        }
-
-        /// <summary>
-        /// Test "withTimeout" feature.
-        /// </summary>
-        [Test]
-        public void TestWithTimeout()
-        {
-            var res = _grid1.GetCompute().WithTimeout(1000).ExecuteJavaTask<ICollection>(BroadcastTask, null)
-                .OfType<Guid>().ToList();
-
-            Assert.AreEqual(2, res.Count);
-            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
-            Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(1)).GetNodes().Count);
-        }
-
-        /// <summary>
         /// Test simple dotNet task execution.
         /// </summary>
         [Test]
@@ -1333,23 +784,31 @@ namespace Apache.Ignite.Core.Tests.Compute
                 _grid1.GetCluster().ForRemotes().GetCompute().Broadcast(new ExceptionalComputeAction()));
 
             Assert.IsNotNull(ex.InnerException);
+#if NETCOREAPP2_0
+            // Exceptions can't be serialized on .NET Core
+            Assert.AreEqual("Operation is not supported on this platform.",
+                ex.InnerException.Message);
+#else
             Assert.AreEqual("Compute job has failed on remote node, examine InnerException for details.",
                 ex.InnerException.Message);
             Assert.IsNotNull(ex.InnerException.InnerException);
             Assert.AreEqual(ExceptionalComputeAction.ErrorText, ex.InnerException.InnerException.Message);
+#endif
         }
 
+#if !NETCOREAPP2_0
         /// <summary>
         /// Tests the footer setting.
         /// </summary>
         [Test]
         public void TestFooterSetting()
         {
-            Assert.AreEqual(CompactFooter, ((Ignite)_grid1).Marshaller.CompactFooter);
+            Assert.AreEqual(CompactFooter, ((Impl.Ignite) _grid1).Marshaller.CompactFooter);
 
             foreach (var g in new[] {_grid1, _grid2, _grid3})
                 Assert.AreEqual(CompactFooter, g.GetConfiguration().BinaryConfiguration.CompactFooter);
         }
+#endif
 
         /// <summary>
         /// Create configuration.
@@ -1369,7 +828,7 @@ namespace Apache.Ignite.Core.Tests.Compute
                         new BinaryTypeConfiguration(typeof(PlatformComputeEnum)),
                         new BinaryTypeConfiguration(typeof(InteropComputeEnumFieldTest))
                     },
-                    NameMapper = BinaryBasicNameMapper.SimpleNameInstance
+                    NameMapper = new BinaryBasicNameMapper { IsSimpleName = true }
                 },
                 SpringConfigUrl = path
             };
@@ -1492,7 +951,7 @@ namespace Apache.Ignite.Core.Tests.Compute
     class ComputeAction : IComputeAction
     {
         [InstanceResource]
-        #pragma warning disable 649
+#pragma warning disable 649
         private IIgnite _grid;
 
         public static ConcurrentBag<Guid> Invokes = new ConcurrentBag<Guid>();
index fd9849c..4550a18 100644 (file)
@@ -31,7 +31,7 @@ namespace Apache.Ignite.Core.Tests.DataStructures
         /// <summary>
         /// Initializes a new instance of the <see cref="AtomicLongTest"/> class.
         /// </summary>
-        public AtomicLongTest() : base("config\\compute\\compute-grid1.xml")
+        public AtomicLongTest() : base("Config\\Compute\\compute-grid1.xml")
         {
             // No-op.
         }
index 751b291..0b16785 100644 (file)
@@ -33,7 +33,7 @@ namespace Apache.Ignite.Core.Tests.DataStructures
         /// <summary>
         /// Initializes a new instance of the <see cref="AtomicReferenceTest"/> class.
         /// </summary>
-        public AtomicReferenceTest() : base("config\\compute\\compute-grid1.xml")
+        public AtomicReferenceTest() : base("Config\\Compute\\compute-grid1.xml")
         {
             // No-op.
         }
index 472dee2..7633021 100644 (file)
@@ -31,7 +31,7 @@ namespace Apache.Ignite.Core.Tests.DataStructures
         /// <summary>
         /// Initializes a new instance of the <see cref="AtomicSequenceTest"/> class.
         /// </summary>
-        public AtomicSequenceTest() : base("config\\compute\\compute-grid1.xml")
+        public AtomicSequenceTest() : base("Config\\Compute\\compute-grid1.xml")
         {
             // No-op.
         }
index 27e55f3..1376d64 100644 (file)
@@ -515,15 +515,15 @@ namespace Apache.Ignite.Core.Tests
         {
             // Empty section.
             var cfg = IgniteConfiguration.FromXml("<x />");
-            TestUtils.AssertReflectionEqual(new IgniteConfiguration(), cfg);
+            AssertExtensions.ReflectionEqual(new IgniteConfiguration(), cfg);
 
             // Empty section with XML header.
             cfg = IgniteConfiguration.FromXml("<?xml version=\"1.0\" encoding=\"utf-16\"?><x />");
-            TestUtils.AssertReflectionEqual(new IgniteConfiguration(), cfg);
+            AssertExtensions.ReflectionEqual(new IgniteConfiguration(), cfg);
 
             // Simple test.
             cfg = IgniteConfiguration.FromXml(@"<igCfg igniteInstanceName=""myGrid"" clientMode=""true"" />");
-            TestUtils.AssertReflectionEqual(new IgniteConfiguration {IgniteInstanceName = "myGrid", ClientMode = true}, cfg);
+            AssertExtensions.ReflectionEqual(new IgniteConfiguration {IgniteInstanceName = "myGrid", ClientMode = true}, cfg);
 
             // Invalid xml.
             var ex = Assert.Throws<ConfigurationErrorsException>(() =>
@@ -538,7 +538,7 @@ namespace Apache.Ignite.Core.Tests
             {
                 cfg = IgniteConfiguration.FromXml(xmlReader);
             }
-            TestUtils.AssertReflectionEqual(new IgniteConfiguration { IgniteInstanceName = "myGrid", ClientMode = true }, cfg);
+            AssertExtensions.ReflectionEqual(new IgniteConfiguration { IgniteInstanceName = "myGrid", ClientMode = true }, cfg);
         }
 
         /// <summary>
@@ -590,7 +590,7 @@ namespace Apache.Ignite.Core.Tests
         {
             var resCfg = SerializeDeserialize(cfg);
 
-            TestUtils.AssertReflectionEqual(cfg, resCfg);
+            AssertExtensions.ReflectionEqual(cfg, resCfg);
         }
 
         /// <summary>
index 98c3f11..1d51c27 100644 (file)
@@ -151,7 +151,7 @@ namespace Apache.Ignite.Core.Tests
                 Assert.AreEqual(cfg.WorkDirectory.Trim('\\'), resCfg.WorkDirectory.Trim('\\'));
                 Assert.AreEqual(cfg.JvmClasspath, resCfg.JvmClasspath);
                 Assert.AreEqual(cfg.JvmOptions, resCfg.JvmOptions);
-                Assert.IsTrue(File.Exists(resCfg.JvmDllPath));
+                Assert.AreEqual(cfg.JvmDllPath, resCfg.JvmDllPath);
                 Assert.AreEqual(cfg.Localhost, resCfg.Localhost);
                 Assert.AreEqual(cfg.IsDaemon, resCfg.IsDaemon);
                 Assert.AreEqual(IgniteConfiguration.DefaultIsLateAffinityAssignment, resCfg.IsLateAffinityAssignment);
@@ -238,7 +238,7 @@ namespace Apache.Ignite.Core.Tests
                 Assert.AreEqual(sql.TcpNoDelay, resSql.TcpNoDelay);
                 Assert.AreEqual(sql.ThreadPoolSize, resSql.ThreadPoolSize);
 
-                TestUtils.AssertReflectionEqual(cfg.DataStorageConfiguration, resCfg.DataStorageConfiguration);
+                AssertExtensions.ReflectionEqual(cfg.DataStorageConfiguration, resCfg.DataStorageConfiguration);
             }
         }
 
@@ -496,6 +496,7 @@ namespace Apache.Ignite.Core.Tests
             Assert.AreEqual(IgniteConfiguration.DefaultIsActiveOnStart, cfg.IsActiveOnStart);
             Assert.AreEqual(IgniteConfiguration.DefaultClientConnectorConfigurationEnabled, 
                 cfg.ClientConnectorConfigurationEnabled);
+            Assert.AreEqual(IgniteConfiguration.DefaultRedirectJavaConsoleOutput, cfg.RedirectJavaConsoleOutput);
 
             // Thread pools.
             Assert.AreEqual(IgniteConfiguration.DefaultManagementThreadPoolSize, cfg.ManagementThreadPoolSize);
index cb70f1e..4542eaa 100644 (file)
@@ -118,6 +118,7 @@ namespace Apache.Ignite.Core.Tests.Log
             Assert.IsInstanceOf<ArithmeticException>(err.Exception);
         }
 
+#if !NETCOREAPP2_0  // Exception serialization is not supported in .NET Core
         /// <summary>
         /// Tests that .NET exception propagates through Java to the log.
         /// </summary>
@@ -139,9 +140,11 @@ namespace Apache.Ignite.Core.Tests.Log
 
                 var errFromJava = TestLogger.Entries.Single(x => x.Exception != null);
                 Assert.IsNotNull(errFromJava.Exception.InnerException);
-                Assert.AreEqual("Error in func.", ((ArithmeticException) errFromJava.Exception.InnerException).Message);
+                Assert.AreEqual("Error in func.", 
+                    ((ArithmeticException) errFromJava.Exception.InnerException).Message);
             }
         }
+#endif
 
         /// <summary>
         /// Tests the <see cref="QueryEntity"/> validation.
index f4660b1..e644e31 100644 (file)
@@ -635,7 +635,7 @@ namespace Apache.Ignite.Core.Tests
         /// <returns>New instance of message listener.</returns>
         public static IMessageListener<string> GetListener()
         {
-            return new MessageListener<string>(Listen);
+            return new RemoteListener();
         }
 
         /// <summary>
@@ -651,27 +651,29 @@ namespace Apache.Ignite.Core.Tests
         }
 
         /// <summary>
-        /// Listen method.
+        /// Remote listener.
         /// </summary>
-        /// <param name="id">Originating node ID.</param>
-        /// <param name="msg">Message.</param>
-        private static bool Listen(Guid id, string msg)
+        private class RemoteListener : IMessageListener<string>
         {
-            try
+            /** <inheritdoc /> */
+            public bool Invoke(Guid nodeId, string message)
             {
-                LastNodeIds.Push(id);
-                ReceivedMessages.Push(msg);
+                try
+                {
+                    LastNodeIds.Push(nodeId);
+                    ReceivedMessages.Push(message);
 
-                ReceivedEvent.Signal();
+                    ReceivedEvent.Signal();
 
-                return ListenResult;
-            }
-            catch (Exception ex)
-            {
-                // When executed on remote nodes, these exceptions will not go to sender, 
-                // so we have to accumulate them.
-                Failures.Push(string.Format("Exception in Listen (msg: {0}, id: {1}): {2}", msg, id, ex));
-                throw;
+                    return ListenResult;
+                }
+                catch (Exception ex)
+                {
+                    // When executed on remote nodes, these exceptions will not go to sender, 
+                    // so we have to accumulate them.
+                    Failures.Push(string.Format("Exception in Listen (msg: {0}, id: {1}): {2}", message, nodeId, ex));
+                    throw;
+                }
             }
         }
     }
index dff7ed7..5415378 100644 (file)
@@ -36,9 +36,10 @@ namespace Apache.Ignite.Core.Tests
         [Test]
         public void TestCsprojToolsVersion()
         {
-            var projFiles = GetDotNetSourceDir().GetFiles("*.csproj", SearchOption.AllDirectories);
+            var projFiles = GetDotNetSourceDir().GetFiles("*.csproj", SearchOption.AllDirectories)
+                .Where(x => !x.Name.Contains("DotNetCore")).ToArray();
+            
             Assert.GreaterOrEqual(projFiles.Length, 7);
-
             CheckFiles(projFiles, x => !x.Contains("ToolsVersion=\"4.0\""), "Invalid csproj files: ");
         }
 
@@ -109,9 +110,10 @@ namespace Apache.Ignite.Core.Tests
         [Test]
         public void TestSlnToolsVersion()
         {
-            var slnFiles = GetDotNetSourceDir().GetFiles("*.sln", SearchOption.AllDirectories);
-            Assert.GreaterOrEqual(slnFiles.Length, 2);
+            var slnFiles = GetDotNetSourceDir().GetFiles("*.sln", SearchOption.AllDirectories)
+                .Where(x => !x.Name.Contains("DotNetCore")).ToArray();
 
+            Assert.GreaterOrEqual(slnFiles.Length, 2);
             CheckFiles(slnFiles, x => !x.Contains("# Visual Studio 2010") ||
                                       !x.Contains("Microsoft Visual Studio Solution File, Format Version 11.00"),
                 "Invalid sln files: ");
index 04f968c..e2b3a09 100644 (file)
@@ -26,7 +26,7 @@ namespace Apache.Ignite.Core.Tests.Services
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cluster;
     using Apache.Ignite.Core.Common;
-    using Apache.Ignite.Core.Impl;
+    //using Apache.Ignite.Core.Impl;
     using Apache.Ignite.Core.Resource;
     using Apache.Ignite.Core.Services;
     using Apache.Ignite.Core.Tests.Compute;
@@ -671,7 +671,9 @@ namespace Apache.Ignite.Core.Tests.Services
         {
             foreach (var grid in Grids)
             {
-                Assert.AreEqual(CompactFooter, ((Ignite)grid).Marshaller.CompactFooter);
+#if !NETCOREAPP2_0
+                Assert.AreEqual(CompactFooter, ((Impl.Ignite) grid).Marshaller.CompactFooter);
+#endif
                 Assert.AreEqual(CompactFooter, grid.GetConfiguration().BinaryConfiguration.CompactFooter);
             }
         }
 namespace Apache.Ignite.Core.Tests
 {
     using System;
-    using System.Collections;
     using System.Collections.Concurrent;
     using System.Collections.Generic;
-    using System.Diagnostics;
-    using System.Diagnostics.CodeAnalysis;
     using System.Linq;
     using System.Threading;
     using Apache.Ignite.Core.Cluster;
-    using Apache.Ignite.Core.Configuration;
     using Apache.Ignite.Core.Discovery.Tcp;
     using Apache.Ignite.Core.Discovery.Tcp.Static;
+#if !NETCOREAPP2_0
     using Apache.Ignite.Core.Impl;
     using Apache.Ignite.Core.Impl.Binary;
-    using Apache.Ignite.Core.Impl.Common;
-    using Apache.Ignite.Core.Tests.Process;
+#endif
     using NUnit.Framework;
 
     /// <summary>
     /// Test utility methods.
     /// </summary>
-    public static class TestUtils
+    public static partial class TestUtils
     {
         /** Indicates long running and/or memory/cpu intensive test. */
         public const string CategoryIntensive = "LONG_TEST";
@@ -68,7 +64,8 @@ namespace Apache.Ignite.Core.Tests
                 "-Xmx99m",
                 "-ea",
                 "-DIGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE=1000",
-                "-DIGNITE_QUIET=true"
+                "-DIGNITE_QUIET=true",
+                "-Duser.timezone=UTC"
             };
 
         /** */
@@ -86,14 +83,6 @@ namespace Apache.Ignite.Core.Tests
         private static int _seed = Environment.TickCount;
 
         /// <summary>
-        /// Kill Ignite processes.
-        /// </summary>
-        public static void KillProcesses()
-        {
-            IgniteProcess.KillAll();
-        }
-
-        /// <summary>
         ///
         /// </summary>
         public static Random Random
@@ -121,15 +110,6 @@ namespace Apache.Ignite.Core.Tests
         /// <summary>
         ///
         /// </summary>
-        /// <returns></returns>
-        public static string CreateTestClasspath()
-        {
-            return Classpath.CreateClasspath(forceTestClasspath: true);
-        }
-
-        /// <summary>
-        ///
-        /// </summary>
         /// <param name="action"></param>
         /// <param name="threadNum"></param>
         public static void RunMultiThreaded(Action action, int threadNum)
@@ -250,51 +230,7 @@ namespace Apache.Ignite.Core.Tests
             return false;
         }
 
-        /// <summary>
-        /// Asserts that the handle registry is empty.
-        /// </summary>
-        /// <param name="timeout">Timeout, in milliseconds.</param>
-        /// <param name="grids">Grids to check.</param>
-        public static void AssertHandleRegistryIsEmpty(int timeout, params IIgnite[] grids)
-        {
-            foreach (var g in grids)
-                AssertHandleRegistryHasItems(g, 0, timeout);
-        }
-
-        /// <summary>
-        /// Asserts that the handle registry has specified number of entries.
-        /// </summary>
-        /// <param name="timeout">Timeout, in milliseconds.</param>
-        /// <param name="expectedCount">Expected item count.</param>
-        /// <param name="grids">Grids to check.</param>
-        public static void AssertHandleRegistryHasItems(int timeout, int expectedCount, params IIgnite[] grids)
-        {
-            foreach (var g in grids)
-                AssertHandleRegistryHasItems(g, expectedCount, timeout);
-        }
-
-        /// <summary>
-        /// Asserts that the handle registry has specified number of entries.
-        /// </summary>
-        /// <param name="grid">The grid to check.</param>
-        /// <param name="expectedCount">Expected item count.</param>
-        /// <param name="timeout">Timeout, in milliseconds.</param>
-        public static void AssertHandleRegistryHasItems(IIgnite grid, int expectedCount, int timeout)
-        {
-            var handleRegistry = ((Ignite)grid).HandleRegistry;
 
-            expectedCount++;  // Skip default lifecycle bean
-
-            if (WaitForCondition(() => handleRegistry.Count == expectedCount, timeout))
-                return;
-
-            var items = handleRegistry.GetItems().Where(x => !(x.Value is LifecycleHandlerHolder)).ToList();
-
-            if (items.Any())
-                Assert.Fail("HandleRegistry is not empty in grid '{0}' (expected {1}, actual {2}):\n '{3}'", 
-                    grid.Name, expectedCount, handleRegistry.Count,
-                    items.Select(x => x.ToString()).Aggregate((x, y) => x + "\n" + y));
-        }
 
         /// <summary>
         /// Waits for condition, polling in busy wait loop.
@@ -336,77 +272,6 @@ namespace Apache.Ignite.Core.Tests
         }
 
         /// <summary>
-        /// Gets the default code-based test configuration.
-        /// </summary>
-        public static IgniteConfiguration GetTestConfiguration(bool? jvmDebug = null, string name = null)
-        {
-            return new IgniteConfiguration
-            {
-                DiscoverySpi = GetStaticDiscovery(),
-                Localhost = "127.0.0.1",
-                JvmOptions = TestJavaOptions(jvmDebug),
-                JvmClasspath = CreateTestClasspath(),
-                IgniteInstanceName = name,
-                DataStorageConfiguration = new DataStorageConfiguration
-                {
-                    DefaultDataRegionConfiguration = new DataRegionConfiguration
-                    {
-                        Name = DataStorageConfiguration.DefaultDataRegionName,
-                        InitialSize = 128 * 1024 * 1024,
-                        MaxSize = Environment.Is64BitProcess
-                            ? DataRegionConfiguration.DefaultMaxSize
-                            : 256 * 1024 * 1024
-                    }
-                }
-            };
-        }
-
-        /// <summary>
-        /// Runs the test in new process.
-        /// </summary>
-        [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
-        public static void RunTestInNewProcess(string fixtureName, string testName)
-        {
-            var procStart = new ProcessStartInfo
-            {
-                FileName = typeof(TestUtils).Assembly.Location,
-                Arguments = fixtureName + " " + testName,
-                CreateNoWindow = true,
-                UseShellExecute = false,
-                RedirectStandardOutput = true,
-                RedirectStandardError = true
-            };
-
-            var proc = System.Diagnostics.Process.Start(procStart);
-            Assert.IsNotNull(proc);
-
-            try
-            {
-                IgniteProcess.AttachProcessConsoleReader(proc);
-
-                Assert.IsTrue(proc.WaitForExit(19000));
-                Assert.AreEqual(0, proc.ExitCode);
-            }
-            finally
-            {
-                if (!proc.HasExited)
-                {
-                    proc.Kill();
-                }
-            }
-        }
-
-        /// <summary>
-        /// Serializes and deserializes back an object.
-        /// </summary>
-        public static T SerializeDeserialize<T>(T obj)
-        {
-            var marsh = new Marshaller(null) {CompactFooter = false};
-
-            return marsh.Unmarshal<T>(marsh.Marshal(obj));
-        }
-
-        /// <summary>
         /// Gets the primary keys.
         /// </summary>
         public static IEnumerable<int> GetPrimaryKeys(IIgnite ignite, string cacheName,
@@ -427,62 +292,78 @@ namespace Apache.Ignite.Core.Tests
         }
 
         /// <summary>
-        /// Asserts equality with reflection.
+        /// Asserts that the handle registry is empty.
         /// </summary>
-        public static void AssertReflectionEqual(object x, object y, string propertyPath = null,
-            HashSet<string> ignoredProperties = null)
+        /// <param name="timeout">Timeout, in milliseconds.</param>
+        /// <param name="grids">Grids to check.</param>
+        public static void AssertHandleRegistryIsEmpty(int timeout, params IIgnite[] grids)
         {
-            if (x == null && y == null)
-            {
-                return;
-            }
-
-            Assert.IsNotNull(x, propertyPath);
-            Assert.IsNotNull(y, propertyPath);
-
-            var type = x.GetType();
+            foreach (var g in grids)
+                AssertHandleRegistryHasItems(g, 0, timeout);
+        }
 
-            if (type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(type))
-            {
-                var xCol = ((IEnumerable)x).OfType<object>().ToList();
-                var yCol = ((IEnumerable)y).OfType<object>().ToList();
+        /// <summary>
+        /// Asserts that the handle registry has specified number of entries.
+        /// </summary>
+        /// <param name="timeout">Timeout, in milliseconds.</param>
+        /// <param name="expectedCount">Expected item count.</param>
+        /// <param name="grids">Grids to check.</param>
+        public static void AssertHandleRegistryHasItems(int timeout, int expectedCount, params IIgnite[] grids)
+        {
+            foreach (var g in grids)
+                AssertHandleRegistryHasItems(g, expectedCount, timeout);
+        }
 
-                Assert.AreEqual(xCol.Count, yCol.Count, propertyPath);
+        /// <summary>
+        /// Asserts that the handle registry has specified number of entries.
+        /// </summary>
+        /// <param name="grid">The grid to check.</param>
+        /// <param name="expectedCount">Expected item count.</param>
+        /// <param name="timeout">Timeout, in milliseconds.</param>
+        public static void AssertHandleRegistryHasItems(IIgnite grid, int expectedCount, int timeout)
+        {
+#if !NETCOREAPP2_0
+            var handleRegistry = ((Ignite)grid).HandleRegistry;
 
-                for (var i = 0; i < xCol.Count; i++)
-                {
-                    AssertReflectionEqual(xCol[i], yCol[i], propertyPath, ignoredProperties);
-                }
+            expectedCount++;  // Skip default lifecycle bean
 
+            if (WaitForCondition(() => handleRegistry.Count == expectedCount, timeout))
                 return;
-            }
-
-            Assert.AreEqual(type, y.GetType());
 
-            propertyPath = propertyPath ?? type.Name;
+            var items = handleRegistry.GetItems().Where(x => !(x.Value is LifecycleHandlerHolder)).ToList();
 
-            if (type.IsValueType || type == typeof(string) || type.IsSubclassOf(typeof(Type)))
+            if (items.Any())
             {
-                Assert.AreEqual(x, y, propertyPath);
-                return;
+                Assert.Fail("HandleRegistry is not empty in grid '{0}' (expected {1}, actual {2}):\n '{3}'",
+                    grid.Name, expectedCount, handleRegistry.Count,
+                    items.Select(x => x.ToString()).Aggregate((x, y) => x + "\n" + y));
             }
+#endif
+        }
 
-            var props = type.GetProperties().Where(p => p.GetIndexParameters().Length == 0);
+        /// <summary>
+        /// Serializes and deserializes back an object.
+        /// </summary>
+        public static T SerializeDeserialize<T>(T obj)
+        {
+#if NETCOREAPP2_0
+            var marshType = typeof(IIgnite).Assembly.GetType("Apache.Ignite.Core.Impl.Binary.Marshaller");
+            var marsh = Activator.CreateInstance(marshType, new object[] { null, null });
+            marshType.GetProperty("CompactFooter").SetValue(marsh, false);
 
-            foreach (var propInfo in props)
-            {
-                if (ignoredProperties != null && ignoredProperties.Contains(propInfo.Name))
-                {
-                    continue;
-                }
+            var bytes = marshType.GetMethod("Marshal").MakeGenericMethod(typeof(object))
+                .Invoke(marsh, new object[] { obj });
 
-                var propName = propertyPath + "." + propInfo.Name;
+            var res = marshType.GetMethods().Single(mi =>
+                    mi.Name == "Unmarshal" && mi.GetParameters().First().ParameterType == typeof(byte[]))
+                .MakeGenericMethod(typeof(object)).Invoke(marsh, new[] { bytes, 0 });
 
-                var xVal = propInfo.GetValue(x, null);
-                var yVal = propInfo.GetValue(y, null);
+            return (T)res;
+#else
+            var marsh = new Marshaller(null) { CompactFooter = false };
 
-                AssertReflectionEqual(xVal, yVal, propName, ignoredProperties);
-            }
+            return marsh.Unmarshal<T>(marsh.Marshal(obj));
+#endif
         }
     }
 }
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs
new file mode 100644 (file)
index 0000000..14b58f2
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests
+{
+    using System;
+    using System.Diagnostics;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using Apache.Ignite.Core.Configuration;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Binary;
+    using Apache.Ignite.Core.Impl.Common;
+    using Apache.Ignite.Core.Tests.Process;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Test utility methods - Windows-specific part (full framework).
+    /// </summary>
+    public static partial class TestUtils
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <returns></returns>
+        public static string CreateTestClasspath()
+        {
+            return Classpath.CreateClasspath(forceTestClasspath: true);
+        }
+
+        /// <summary>
+        /// Gets the name of the temporary directory.
+        /// </summary>
+        public static string GetTempDirectoryName()
+        {
+            return IgniteUtils.GetTempDirectoryName();
+        }
+
+        /// <summary>
+        /// Kill Ignite processes.
+        /// </summary>
+        public static void KillProcesses()
+        {
+            IgniteProcess.KillAll();
+        }
+
+        /// <summary>
+        /// Gets the default code-based test configuration.
+        /// </summary>
+        public static IgniteConfiguration GetTestConfiguration(bool? jvmDebug = null, string name = null)
+        {
+            return new IgniteConfiguration
+            {
+                DiscoverySpi = GetStaticDiscovery(),
+                Localhost = "127.0.0.1",
+                JvmOptions = TestJavaOptions(jvmDebug),
+                JvmClasspath = CreateTestClasspath(),
+                IgniteInstanceName = name,
+                DataStorageConfiguration = new DataStorageConfiguration
+                {
+                    DefaultDataRegionConfiguration = new DataRegionConfiguration
+                    {
+                        Name = DataStorageConfiguration.DefaultDataRegionName,
+                        InitialSize = 128 * 1024 * 1024,
+                        MaxSize = Environment.Is64BitProcess
+                            ? DataRegionConfiguration.DefaultMaxSize
+                            : 256 * 1024 * 1024
+                    }
+                }
+            };
+        }
+
+        /// <summary>
+        /// Runs the test in new process.
+        /// </summary>
+        [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
+        public static void RunTestInNewProcess(string fixtureName, string testName)
+        {
+            var procStart = new ProcessStartInfo
+            {
+                FileName = typeof(TestUtils).Assembly.Location,
+                Arguments = fixtureName + " " + testName,
+                CreateNoWindow = true,
+                UseShellExecute = false,
+                RedirectStandardOutput = true,
+                RedirectStandardError = true
+            };
+
+            var proc = System.Diagnostics.Process.Start(procStart);
+            Assert.IsNotNull(proc);
+
+            try
+            {
+                IgniteProcess.AttachProcessConsoleReader(proc);
+
+                Assert.IsTrue(proc.WaitForExit(19000));
+                Assert.AreEqual(0, proc.ExitCode);
+            }
+            finally
+            {
+                if (!proc.HasExited)
+                {
+                    proc.Kill();
+                }
+            }
+        }
+    }
+}
index 21738a2..6deaa9b 100644 (file)
     <Compile Include="Impl\IPlatformTargetInternal.cs" />
     <Compile Include="Impl\DataRegionMetrics.cs" />
     <Compile Include="Impl\PersistentStore\PersistentStoreMetrics.cs" />
+    <Compile Include="Impl\Shell.cs" />
+    <Compile Include="Impl\Unmanaged\DllLoader.cs" />
     <Compile Include="Impl\Unmanaged\Jni\AppDomains.cs" />
     <Compile Include="Impl\Unmanaged\Jni\CallbackDelegates.cs" />
     <Compile Include="Impl\Unmanaged\Jni\Callbacks.cs" />
     <Compile Include="Impl\Unmanaged\Jni\JniResult.cs" />
     <Compile Include="Impl\Unmanaged\Jni\Jvm.cs" />
     <Compile Include="Impl\Unmanaged\Jni\JvmDelegates.cs" />
+    <Compile Include="Impl\Unmanaged\Os.cs" />
     <Compile Include="PersistentStore\CheckpointWriteOrder.cs" />
     <Compile Include="PersistentStore\IPersistentStoreMetrics.cs" />
     <Compile Include="PersistentStore\Package-Info.cs" />
     <Compile Include="Impl\Memory\PlatformUnpooledMemory.cs" />
     <Compile Include="Impl\Messaging\MessageListenerHolder.cs" />
     <Compile Include="Impl\Messaging\Messaging.cs" />
-    <Compile Include="Impl\NativeMethods.cs" />
+    <Compile Include="Impl\MemoryInfo.cs" />
     <Compile Include="Impl\Binary\IO\IBinaryStream.cs" />
     <Compile Include="Impl\Binary\IO\BinaryHeapStream.cs" />
     <Compile Include="Impl\Binary\IBinaryTypeDescriptor.cs" />
index 9049526..88bf095 100644 (file)
@@ -41,6 +41,7 @@ Creating NuGet package:
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <description>
 Apache Ignite In-Memory Data Fabric is a high-performance, integrated and distributed in-memory platform for computing and transacting on large-scale data sets in real-time, orders of magnitude faster than possible with traditional disk-based or flash technologies.
+Supports .NET 4+ and .NET Core 2.0+.
             
 More info: https://apacheignite-net.readme.io/
         </description>
@@ -54,6 +55,10 @@ More info: https://apacheignite-net.readme.io/
         <file src="NuGet\Uninstall.ps1" target="tools" />
         <file src="NuGet\PostBuild.ps1" target="tools" />
 
+               <!-- Binaries -->
+        <file src="bin\$configuration$\Apache.Ignite.Core.dll" target="lib\net40" />
+               <file src="bin\$configuration$\Apache.Ignite.Core.xml" target="lib\net40" />
+               
         <!-- Include Apache.Ignite.exe -->
         <file src="..\Apache.Ignite\bin\$configuration$\Apache.Ignite.exe" target="lib\net40" />
         <file src="..\Apache.Ignite\bin\$configuration$\Apache.Ignite.exe.config" target="lib\net40" />
@@ -62,7 +67,7 @@ More info: https://apacheignite-net.readme.io/
             Library files (jars) should not be included in project, so that NuGet package restore works properly.
             We keep jars in NuGet dir and copy them over in PostBuild event.
         -->
-        <file src="..\bin\Libs\*.jar" target="Libs" />
+        <file src="..\bin\libs\*.jar" target="libs" />
     
         <!-- LINQPad samples -->
         <file src="NuGet\LINQPad\*.*" target="linqpad-samples" />
index e204ee7..0eedd48 100644 (file)
@@ -50,7 +50,8 @@ namespace Apache.Ignite.Core.Cache.Configuration
         /// <summary>
         /// The default maximum size, equals to 20% of total RAM.
         /// </summary>
-        public static readonly long DefaultMaxSize = (long) ((long) NativeMethods.GetTotalPhysicalMemory() * 0.2);
+        public static readonly long DefaultMaxSize =
+            (long) ((long) MemoryInfo.GetTotalPhysicalMemory(2048L * 1024 * 1024) * 0.2);
 
         /// <summary>
         /// The default sub intervals.
index d20ce49..6fce7ad 100644 (file)
@@ -59,7 +59,8 @@ namespace Apache.Ignite.Core.Configuration
         /// <summary>
         /// The default maximum size, equals to 20% of total RAM.
         /// </summary>
-        public static readonly long DefaultMaxSize = (long)((long)NativeMethods.GetTotalPhysicalMemory() * 0.2);
+        public static readonly long DefaultMaxSize =
+            (long)((long)MemoryInfo.GetTotalPhysicalMemory(2048L * 1024 * 1024) * 0.2);
 
         /// <summary>
         /// The default sub intervals.
index f8c42e5..29b8519 100644 (file)
@@ -733,11 +733,6 @@ namespace Apache.Ignite.Core
 
             JvmInitialMemoryMb = (int) (binaryReader.ReadLong()/1024/2014);
             JvmMaxMemoryMb = (int) (binaryReader.ReadLong()/1024/2014);
-
-            // Local data (not from reader)
-            JvmDllPath = Process.GetCurrentProcess().Modules.OfType<ProcessModule>()
-                .Single(x => string.Equals(x.ModuleName, IgniteUtils.FileJvmDll, StringComparison.OrdinalIgnoreCase))
-                .FileName;
         }
 
         /// <summary>
@@ -756,6 +751,7 @@ namespace Apache.Ignite.Core
             IgniteHome = cfg.IgniteHome;
             JvmClasspath = cfg.JvmClasspath;
             JvmOptions = cfg.JvmOptions;
+            JvmDllPath = cfg.JvmDllPath;
             Assemblies = cfg.Assemblies;
             SuppressWarnings = cfg.SuppressWarnings;
             LifecycleHandlers = cfg.LifecycleHandlers;
index 6fa7918..38b17a1 100644 (file)
@@ -278,7 +278,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Safely gets all assembly types.
         /// </summary>
-        private static IEnumerable<Type> GetAssemblyTypesSafe(Assembly asm)
+        public static IEnumerable<Type> GetAssemblyTypesSafe(Assembly asm)
         {
             try
             {
index 2065e41..86e70a6 100644 (file)
 namespace Apache.Ignite.Core.Impl.Common
 {
     using System;
+    using System.Diagnostics.CodeAnalysis;
     using System.Text;
     using System.IO;
+    using Apache.Ignite.Core.Impl.Unmanaged;
     using Apache.Ignite.Core.Log;
 
     /// <summary>
@@ -33,6 +35,10 @@ namespace Apache.Ignite.Core.Impl.Common
         /** Classpath prefix. */
         private const string ClasspathPrefix = "-Djava.class.path=";
 
+        /** Classpath separator. */
+        [SuppressMessage("Microsoft.Performance", "CA1802:UseLiteralsWhereAppropriate")]
+        private static readonly string ClasspathSeparator = Os.IsWindows ? ";" : ":";
+
         /// <summary>
         /// Creates classpath from the given configuration, or default classpath if given config is null.
         /// </summary>
@@ -52,8 +58,8 @@ namespace Apache.Ignite.Core.Impl.Common
             {
                 cpStr.Append(cfg.JvmClasspath);
 
-                if (!cfg.JvmClasspath.EndsWith(";"))
-                    cpStr.Append(';');
+                if (!cfg.JvmClasspath.EndsWith(ClasspathSeparator))
+                    cpStr.Append(ClasspathSeparator);
             }
 
             var ggHome = IgniteHome.Resolve(cfg, log);
@@ -64,7 +70,10 @@ namespace Apache.Ignite.Core.Impl.Common
             if (log != null)
                 log.Debug("Classpath resolved to: " + cpStr);
 
-            return ClasspathPrefix + cpStr;
+            var res = cpStr.ToString();
+            res = res.StartsWith(ClasspathPrefix) ? res : ClasspathPrefix + res;
+
+            return res;
         }
 
         /// <summary>
@@ -79,12 +88,12 @@ namespace Apache.Ignite.Core.Impl.Common
             // Append test directories (if needed) first, because otherwise build *.jar will be picked first.
             if (forceTestClasspath || "true".Equals(Environment.GetEnvironmentVariable(EnvIgniteNativeTestClasspath)))
             {
-                AppendTestClasses(ggHome + "\\examples", cpStr);
-                AppendTestClasses(ggHome + "\\modules", cpStr);
-                AppendTestClasses(ggHome + "\\modules\\extdata\\platform", cpStr);
+                AppendTestClasses(Path.Combine(ggHome, "examples"), cpStr);
+                AppendTestClasses(Path.Combine(ggHome, "modules"), cpStr);
+                AppendTestClasses(Path.Combine(ggHome, "modules", "extdata", "platform"), cpStr);
             }
 
-            string ggLibs = ggHome + "\\libs";
+            string ggLibs = Path.Combine(ggHome, "libs");
 
             AppendJars(ggLibs, cpStr);
 
@@ -124,14 +133,23 @@ namespace Apache.Ignite.Core.Impl.Common
             if (path.EndsWith("rest-http", StringComparison.OrdinalIgnoreCase))
                 return;
 
-            if (Directory.Exists(path + "\\target\\classes"))
-                cp.Append(path + "\\target\\classes;");
+            var dir = Path.Combine(path, "target", "classes");
+            if (Directory.Exists(dir))
+            {
+                cp.Append(dir).Append(ClasspathSeparator);
+            }
 
-            if (Directory.Exists(path + "\\target\\test-classes"))
-                cp.Append(path + "\\target\\test-classes;");
+            dir = Path.Combine(path, "target", "test-classes");
+            if (Directory.Exists(dir))
+            {
+                cp.Append(dir).Append(ClasspathSeparator);
+            }
 
-            if (Directory.Exists(path + "\\target\\libs"))
-                AppendJars(path + "\\target\\libs", cp);
+            dir = Path.Combine(path, "target", "libs");
+            if (Directory.Exists(dir))
+            {
+                AppendJars(dir, cp);
+            }
         }
 
         /// <summary>
@@ -143,10 +161,9 @@ namespace Apache.Ignite.Core.Impl.Common
         {
             if (Directory.Exists(path))
             {
-                foreach (string jar in Directory.EnumerateFiles(path, "*.jar"))
+                foreach (var jar in Directory.EnumerateFiles(path, "*.jar"))
                 {
-                    cpStr.Append(jar);
-                    cpStr.Append(';');
+                    cpStr.Append(jar).Append(ClasspathSeparator);
                 }
             }
         }
index be1a7f1..9a65a24 100644 (file)
@@ -403,7 +403,7 @@ namespace Apache.Ignite.Core.Impl.Common
         /// </summary>
         private static List<Type> GetConcreteDerivedTypes(Type type)
         {
-            return typeof(IIgnite).Assembly.GetTypes()
+            return TypeResolver.GetAssemblyTypesSafe(typeof(IIgnite).Assembly)
                 .Where(t => t.IsClass && !t.IsAbstract && type.IsAssignableFrom(t)).ToList();
         }
 
index 3d4ad4d..47065bc 100644 (file)
@@ -114,9 +114,11 @@ namespace Apache.Ignite.Core.Impl.Common
                        (dir.EnumerateDirectories().Count(x => x.Name == "examples" || x.Name == "bin") == 2 &&
                         dir.EnumerateDirectories().Count(x => x.Name == "modules" || x.Name == "platforms") == 1)
                        || // NuGet home
-                       (dir.EnumerateDirectories().Any(x => x.Name == "Libs") &&
+                       (dir.EnumerateDirectories().Any(x => x.Name == "libs") &&
                         (dir.EnumerateFiles("Apache.Ignite.Core.dll").Any() ||
                          dir.EnumerateFiles("Apache.Ignite.*.nupkg").Any() ||
+                         dir.EnumerateFiles("apache.ignite.*.nupkg").Any() ||  // Lowercase on Linux
+                         dir.EnumerateFiles("apache.ignite.nuspec").Any() ||  // Lowercase on Linux
                          dir.EnumerateFiles("Apache.Ignite.nuspec").Any()));
             }
             catch (IOException)
index 38eda1b..022a5ed 100644 (file)
@@ -19,8 +19,6 @@ namespace Apache.Ignite.Core.Impl
 {
     using System;
     using System.Collections.Generic;
-    using System.ComponentModel;
-    using System.Diagnostics.CodeAnalysis;
     using System.Globalization;
     using System.IO;
     using System.Linq;
@@ -33,6 +31,7 @@ namespace Apache.Ignite.Core.Impl
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Cluster;
     using Apache.Ignite.Core.Impl.Common;
+    using Apache.Ignite.Core.Impl.Unmanaged;
     using Apache.Ignite.Core.Log;
     using Microsoft.Win32;
     using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader;
@@ -46,17 +45,28 @@ namespace Apache.Ignite.Core.Impl
         private const string EnvJavaHome = "JAVA_HOME";
 
         /** Lookup paths. */
-        private static readonly string[] JvmDllLookupPaths =
-        {
-            // JRE paths
-            @"bin\server",
-            @"bin\client",
-
-            // JDK paths
-            @"jre\bin\server",
-            @"jre\bin\client",
-            @"jre\bin\default"
-        };
+        private static readonly string[] JvmDllLookupPaths = Os.IsWindows
+            ? new[]
+            {
+                // JRE paths
+                @"bin\server",
+                @"bin\client",
+
+                // JDK paths
+                @"jre\bin\server",
+                @"jre\bin\client",
+                @"jre\bin\default"
+            }
+            : new[]
+            {
+                // JRE paths
+                "lib/amd64/server",
+                "lib/amd64/client",
+
+                // JDK paths
+                "jre/lib/amd64/server",
+                "jre/lib/amd64/client"
+            };
 
         /** Registry lookup paths. */
         private static readonly string[] JreRegistryKeys =
@@ -65,8 +75,8 @@ namespace Apache.Ignite.Core.Impl
             @"Software\Wow6432Node\JavaSoft\Java Runtime Environment"
         };
 
-        /** File: jvm.dll. */
-        internal const string FileJvmDll = "jvm.dll";
+        /** Jvm dll file name. */
+        internal static readonly string FileJvmDll = Os.IsWindows ? "jvm.dll" : "libjvm.so";
 
         /** Prefix for temp directory names. */
         private const string DirIgniteTmp = "Ignite_";
@@ -195,15 +205,15 @@ namespace Apache.Ignite.Core.Impl
             {
                 log.Debug("Trying to load JVM dll from [option={0}, path={1}]...", dllPath.Key, dllPath.Value);
 
-                var errCode = LoadDll(dllPath.Value, FileJvmDll);
-                if (errCode == 0)
+                var errInfo = LoadDll(dllPath.Value, FileJvmDll);
+                if (errInfo == null)
                 {
                     log.Debug("jvm.dll successfully loaded from [option={0}, path={1}]", dllPath.Key, dllPath.Value);
                     return;
                 }
 
                 var message = string.Format(CultureInfo.InvariantCulture, "[option={0}, path={1}, error={2}]",
-                                                  dllPath.Key, dllPath.Value, FormatWin32Error(errCode));
+                                                  dllPath.Key, dllPath.Value, errInfo);
                 messages.Add(message);
 
                 log.Debug("Failed to load jvm.dll: " + message);
@@ -228,62 +238,32 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /// <summary>
-        /// Formats the Win32 error.
-        /// </summary>
-        [ExcludeFromCodeCoverage]
-        private static string FormatWin32Error(int errorCode)
-        {
-            if (errorCode == NativeMethods.ERROR_BAD_EXE_FORMAT)
-            {
-                var mode = Environment.Is64BitProcess ? "x64" : "x86";
-
-                return string.Format("DLL could not be loaded (193: ERROR_BAD_EXE_FORMAT). " +
-                                     "This is often caused by x64/x86 mismatch. " +
-                                     "Current process runs in {0} mode, and DLL is not {0}.", mode);
-            }
-
-            if (errorCode == NativeMethods.ERROR_MOD_NOT_FOUND)
-            {
-                return "DLL could not be loaded (126: ERROR_MOD_NOT_FOUND). " +
-                       "This can be caused by missing dependencies. ";
-            }
-
-            return string.Format("{0}: {1}", errorCode, new Win32Exception(errorCode).Message);
-        }
-
-        /// <summary>
         /// Try loading DLLs first using file path, then using it's simple name.
         /// </summary>
         /// <param name="filePath"></param>
         /// <param name="simpleName"></param>
-        /// <returns>Zero in case of success, error code in case of failure.</returns>
-        private static int LoadDll(string filePath, string simpleName)
+        /// <returns>Null in case of success, error info in case of failure.</returns>
+        private static string LoadDll(string filePath, string simpleName)
         {
-            int res = 0;
-
-            IntPtr ptr;
+            string res = null;
 
             if (filePath != null)
             {
-                ptr = NativeMethods.LoadLibrary(filePath);
+                res = DllLoader.Load(filePath);
 
-                if (ptr == IntPtr.Zero)
-                    res = Marshal.GetLastWin32Error();
-                else
-                    return res;
+                if (res == null)
+                {
+                    return null;  // Success.
+                }
             }
 
             // Failed to load using file path, fallback to simple name.
-            ptr = NativeMethods.LoadLibrary(simpleName);
+            var res2 = DllLoader.Load(simpleName);
 
-            if (ptr == IntPtr.Zero)
+            if (res2 == null)
             {
-                // Preserve the first error code, if any.
-                if (res == 0)
-                    res = Marshal.GetLastWin32Error();
+                return null;  // Success.
             }
-            else
-                res = 0;
 
             return res;
         }
@@ -294,16 +274,37 @@ namespace Apache.Ignite.Core.Impl
         private static IEnumerable<KeyValuePair<string, string>> GetJvmDllPaths(string configJvmDllPath)
         {
             if (!string.IsNullOrEmpty(configJvmDllPath))
+            {
                 yield return new KeyValuePair<string, string>("IgniteConfiguration.JvmDllPath", configJvmDllPath);
+            }
 
             var javaHomeDir = Environment.GetEnvironmentVariable(EnvJavaHome);
 
             if (!string.IsNullOrEmpty(javaHomeDir))
+            {
                 foreach (var path in JvmDllLookupPaths)
+                {
                     yield return
                         new KeyValuePair<string, string>(EnvJavaHome, Path.Combine(javaHomeDir, path, FileJvmDll));
+                }
+            }
+
+            foreach (var keyValuePair in GetJvmDllPathsFromRegistry().Concat(GetJvmDllPathsFromSymlink()))
+            {
+                yield return keyValuePair;
+            }
+        }
+
+        /// <summary>
+        /// Gets Jvm dll paths from Windows registry.
+        /// </summary>
+        private static IEnumerable<KeyValuePair<string, string>> GetJvmDllPathsFromRegistry()
+        {
+            if (!Os.IsWindows)
+            {
+                yield break;
+            }
 
-            // Get paths from the Windows Registry
             foreach (var regPath in JreRegistryKeys)
             {
                 using (var jSubKey = Registry.LocalMachine.OpenSubKey(regPath))
@@ -331,6 +332,50 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /// <summary>
+        /// Gets the Jvm dll paths from symlink.
+        /// </summary>
+        private static IEnumerable<KeyValuePair<string, string>> GetJvmDllPathsFromSymlink()
+        {
+            if (Os.IsWindows)
+            {
+                yield break;
+            }
+
+            const string javaExec = "/usr/bin/java";
+            if (!File.Exists(javaExec))
+            {
+                yield break;
+            }
+
+            var file = Shell.BashExecute("readlink -f /usr/bin/java");
+            // /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
+
+            var dir = Path.GetDirectoryName(file);
+            // /usr/lib/jvm/java-8-openjdk-amd64/jre/bin
+
+            if (dir == null)
+            {
+                yield break;
+            }
+
+            var libFolder = Path.GetFullPath(Path.Combine(dir, "../lib/"));
+            if (!Directory.Exists(libFolder))
+            {
+                yield break;
+            }
+
+            // Predefined path: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so
+            yield return new KeyValuePair<string, string>(javaExec,
+                Path.Combine(libFolder, "amd64", "server", FileJvmDll));
+
+            // Last resort - custom paths:
+            foreach (var f in Directory.GetFiles(libFolder, FileJvmDll, SearchOption.AllDirectories))
+            {
+                yield return new KeyValuePair<string, string>(javaExec, f);
+            }
+        }
+
+        /// <summary>
         /// Creates a uniquely named, empty temporary directory on disk and returns the full path of that directory.
         /// </summary>
         /// <returns>The full path of the temporary directory.</returns>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/MemoryInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/MemoryInfo.cs
new file mode 100644 (file)
index 0000000..7cfd019
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl
+{
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+    using System.Linq;
+    using System.Runtime.InteropServices;
+    using System.Text.RegularExpressions;
+    using Apache.Ignite.Core.Impl.Unmanaged;
+
+    /// <summary>
+    /// Memory info.
+    /// </summary>
+    internal static class MemoryInfo
+    {
+        /// <summary>
+        /// Gets the total physical memory.
+        /// </summary>
+        public static ulong GetTotalPhysicalMemory(ulong defaultValue)
+        {
+            if (Os.IsWindows)
+            {
+                return NativeMethodsWindows.GlobalMemoryStatusExTotalPhys();
+            }
+
+            const string memInfo = "/proc/meminfo";
+
+            if (File.Exists(memInfo))
+            {
+                var kbytes = File.ReadAllLines(memInfo).Select(x => Regex.Match(x, @"MemTotal:\s+([0-9]+) kB"))
+                    .Where(x => x.Success)
+                    .Select(x => x.Groups[1].Value).FirstOrDefault();
+
+                if (kbytes != null)
+                {
+                    return ulong.Parse(kbytes) * 1024;
+                }
+            }
+
+            return defaultValue;
+        }
+
+        /// <summary>
+        /// Native methods.
+        /// </summary>
+        private static class NativeMethodsWindows
+        {
+            /// <summary>
+            /// Gets the total physical memory.
+            /// </summary>
+            internal static ulong GlobalMemoryStatusExTotalPhys()
+            {
+                var status = new MEMORYSTATUSEX();
+                status.Init();
+
+                GlobalMemoryStatusEx(ref status);
+
+                return status.ullTotalPhys;
+            }
+
+            /// <summary>
+            /// Globals the memory status.
+            /// </summary>
+            [return: MarshalAs(UnmanagedType.Bool)]
+            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            private static extern bool GlobalMemoryStatusEx([In, Out] ref MEMORYSTATUSEX lpBuffer);
+
+            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+            // ReSharper disable InconsistentNaming
+            // ReSharper disable MemberCanBePrivate.Local
+            private struct MEMORYSTATUSEX
+            {
+                public uint dwLength;
+                public readonly uint dwMemoryLoad;
+                public readonly ulong ullTotalPhys;
+                public readonly ulong ullAvailPhys;
+                public readonly ulong ullTotalPageFile;
+                public readonly ulong ullAvailPageFile;
+                public readonly ulong ullTotalVirtual;
+                public readonly ulong ullAvailVirtual;
+                public readonly ulong ullAvailExtendedVirtual;
+
+                /// <summary>
+                /// Initializes a new instance of the <see cref="MEMORYSTATUSEX"/> struct.
+                /// </summary>
+                public void Init()
+                {
+                    dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/NativeMethods.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/NativeMethods.cs
deleted file mode 100644 (file)
index 0004772..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.
- */
-
-namespace Apache.Ignite.Core.Impl
-{
-    using System;
-    using System.Runtime.InteropServices;
-
-    /// <summary>
-    /// Native methods.
-    /// </summary>
-    internal static class NativeMethods
-    {
-        /// <summary>
-        /// ERROR_BAD_EXE_FORMAT constant.
-        /// </summary>
-        // ReSharper disable once InconsistentNaming
-        public const int ERROR_BAD_EXE_FORMAT = 193;
-
-        /// <summary>
-        /// ERROR_MOD_NOT_FOUND constant.
-        /// </summary>
-        // ReSharper disable once InconsistentNaming
-        public const int ERROR_MOD_NOT_FOUND = 126;
-
-        /// <summary>
-        /// Load DLL with WinAPI.
-        /// </summary>
-        /// <param name="path">Path to dll.</param>
-        /// <returns></returns>
-        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false, 
-            ThrowOnUnmappableChar = true)]
-        internal static extern IntPtr LoadLibrary(string path);
-
-        /// <summary>
-        /// Gets the total physical memory.
-        /// </summary>
-        internal static ulong GetTotalPhysicalMemory()
-        {
-            var status = new MEMORYSTATUSEX();
-            status.Init();
-
-            GlobalMemoryStatusEx(ref status);
-
-            return status.ullTotalPhys;
-        }
-
-        /// <summary>
-        /// Globals the memory status.
-        /// </summary>
-        [return: MarshalAs(UnmanagedType.Bool)]
-        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
-        private static extern bool GlobalMemoryStatusEx([In, Out] ref MEMORYSTATUSEX lpBuffer);
-
-        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
-        // ReSharper disable InconsistentNaming
-        // ReSharper disable MemberCanBePrivate.Local
-        private struct MEMORYSTATUSEX
-        {
-            public uint dwLength;
-            public readonly uint dwMemoryLoad;
-            public readonly ulong ullTotalPhys;
-            public readonly ulong ullAvailPhys;
-            public readonly ulong ullTotalPageFile;
-            public readonly ulong ullAvailPageFile;
-            public readonly ulong ullTotalVirtual;
-            public readonly ulong ullAvailVirtual;
-            public readonly ulong ullAvailExtendedVirtual;
-
-            /// <summary>
-            /// Initializes a new instance of the <see cref="MEMORYSTATUSEX"/> struct.
-            /// </summary>
-            public void Init()
-            {
-                dwLength = (uint) Marshal.SizeOf(typeof(MEMORYSTATUSEX));
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Shell.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Shell.cs
new file mode 100644 (file)
index 0000000..e48c8fe
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl
+{
+    using System.Diagnostics;
+
+    /// <summary>
+    /// Shell utils (cmd/bash).
+    /// </summary>
+    internal static class Shell
+    {
+        /// <summary>
+        /// Executes Bash command.
+        /// </summary>
+        public static string BashExecute(string args)
+        {
+            return Execute("/bin/bash", args);
+        }
+
+        /// <summary>
+        /// Executes the command.
+        /// </summary>
+        private static string Execute(string file, string args)
+        {
+            var escapedArgs = args.Replace("\"", "\\\"");
+
+            var process = new Process
+            {
+                StartInfo = new ProcessStartInfo
+                {
+                    FileName = file,
+                    Arguments = string.Format("-c \"{0}\"", escapedArgs),
+                    RedirectStandardOutput = true,
+                    UseShellExecute = false,
+                    CreateNoWindow = true
+                }
+            };
+
+            process.Start();
+
+            var res = process.StandardOutput.ReadToEnd();
+            process.WaitForExit();
+
+            return res;
+        }
+
+    }
+}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/DllLoader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/DllLoader.cs
new file mode 100644 (file)
index 0000000..61de8e4
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.Unmanaged
+{
+    using System;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Runtime.InteropServices;
+
+    /// <summary>
+    /// Dynamically loads unmanaged DLLs with respect to current platform.
+    /// </summary>
+    internal static class DllLoader
+    {
+        /** Lazy symbol binding. */
+        private const int RtldLazy = 1;
+
+        /** Global symbol access. */
+        private const int RtldGlobal = 8;
+
+        /// <summary>
+        /// ERROR_BAD_EXE_FORMAT constant.
+        /// </summary>
+        // ReSharper disable once InconsistentNaming
+        private const int ERROR_BAD_EXE_FORMAT = 193;
+
+        /// <summary>
+        /// ERROR_MOD_NOT_FOUND constant.
+        /// </summary>
+        // ReSharper disable once InconsistentNaming
+        private const int ERROR_MOD_NOT_FOUND = 126;
+
+        /// <summary>
+        /// Loads specified DLL.
+        /// </summary>
+        /// <returns>Null when successful; error message otherwise.</returns>
+        public static string Load(string dllPath)
+        {
+            if (Os.IsWindows)
+            {
+                return NativeMethodsWindows.LoadLibrary(dllPath) == IntPtr.Zero 
+                    ? FormatWin32Error(Marshal.GetLastWin32Error()) ?? "Unknown error"
+                    : null;
+            }
+
+            if (Os.IsLinux)
+            {
+                if (Os.IsMono)
+                {
+                    return NativeMethodsMono.dlopen(dllPath, RtldGlobal | RtldLazy) == IntPtr.Zero
+                        ? GetErrorText(NativeMethodsMono.dlerror())
+                        : null;
+                }
+
+                if (Os.IsNetCore)
+                {
+                    return NativeMethodsCore.dlopen(dllPath, RtldGlobal | RtldLazy) == IntPtr.Zero
+                        ? GetErrorText(NativeMethodsCore.dlerror())
+                        : null;
+                }
+
+                return NativeMethodsLinux.dlopen(dllPath, RtldGlobal | RtldLazy) == IntPtr.Zero
+                    ? GetErrorText(NativeMethodsLinux.dlerror())
+                    : null;
+            }
+
+            throw new InvalidOperationException("Unsupported OS: " + Environment.OSVersion);
+        }
+
+        /// <summary>
+        /// Gets the error text.
+        /// </summary>
+        private static string GetErrorText(IntPtr charPtr)
+        {
+            return Marshal.PtrToStringAnsi(charPtr) ?? "Unknown error";
+        }
+
+        /// <summary>
+        /// Formats the Win32 error.
+        /// </summary>
+        [ExcludeFromCodeCoverage]
+        private static string FormatWin32Error(int errorCode)
+        {
+            if (errorCode == ERROR_BAD_EXE_FORMAT)
+            {
+                var mode = Environment.Is64BitProcess ? "x64" : "x86";
+
+                return string.Format("DLL could not be loaded (193: ERROR_BAD_EXE_FORMAT). " +
+                                     "This is often caused by x64/x86 mismatch. " +
+                                     "Current process runs in {0} mode, and DLL is not {0}.", mode);
+            }
+
+            if (errorCode == ERROR_MOD_NOT_FOUND)
+            {
+                return "DLL could not be loaded (126: ERROR_MOD_NOT_FOUND). " +
+                       "This can be caused by missing dependencies. ";
+            }
+
+            return string.Format("{0}: {1}", errorCode, new Win32Exception(errorCode).Message);
+        }
+
+        /// <summary>
+        /// Windows.
+        /// </summary>
+        private static class NativeMethodsWindows
+        {
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+                ThrowOnUnmappableChar = true)]
+            internal static extern IntPtr LoadLibrary(string filename);
+        }
+
+        /// <summary>
+        /// Linux.
+        /// </summary>
+        private static class NativeMethodsLinux
+        {
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("libdl.so", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+                ThrowOnUnmappableChar = true)]
+            internal static extern IntPtr dlopen(string filename, int flags);
+
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("libdl.so", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+                ThrowOnUnmappableChar = true)]
+            internal static extern IntPtr dlerror();
+        }
+
+        /// <summary>
+        /// libdl.so depends on libc6-dev on Linux, use Mono instead.
+        /// </summary>
+        private static class NativeMethodsMono
+        {
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("__Internal", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+                ThrowOnUnmappableChar = true)]
+            internal static extern IntPtr dlopen(string filename, int flags);
+
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("__Internal", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+                ThrowOnUnmappableChar = true)]
+            internal static extern IntPtr dlerror();
+        }
+
+        /// <summary>
+        /// libdl.so depends on libc6-dev on Linux, use libcoreclr instead.
+        /// </summary>
+        private static class NativeMethodsCore
+        {
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("libcoreclr.so", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+                ThrowOnUnmappableChar = true)]
+            internal static extern IntPtr dlopen(string filename, int flags);
+
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("libcoreclr.so", SetLastError = true, CharSet = CharSet.Ansi, BestFitMapping = false,
+                ThrowOnUnmappableChar = true)]
+            internal static extern IntPtr dlerror();
+        }
+    }
+}
\ No newline at end of file
index da790d7..93b5e69 100644 (file)
@@ -460,13 +460,18 @@ namespace Apache.Ignite.Core.Impl.Unmanaged.Jni
         /// </summary>
         private void ExceptionCheck()
         {
-            if (!_exceptionCheck(_envPtr))
+            var res = _exceptionCheck(_envPtr);
+            if (res == 0)
             {
                 return;
             }
 
             var err = _exceptionOccurred(_envPtr);
-            Debug.Assert(err != IntPtr.Zero);
+
+            if (err == IntPtr.Zero)
+            {
+                throw new IgniteException("Inconsistent JNI ExceptionCheck status.");
+            }
 
             _exceptionClear(_envPtr);
 
index a2ad499..664ef6e 100644 (file)
@@ -63,7 +63,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged.Jni
         internal delegate void ExceptionClear(IntPtr env);
 
         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
-        internal delegate bool ExceptionCheck(IntPtr env);
+        internal delegate byte ExceptionCheck(IntPtr env);
 
         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
         internal delegate IntPtr GetObjectClass(IntPtr env, IntPtr obj);
index 55331c7..ebff15b 100644 (file)
@@ -79,19 +79,19 @@ namespace Apache.Ignite.Core.Impl.Unmanaged.Jni
 
             var env = AttachCurrentThread();
             _methodId = new MethodId(env);
-            _callbacks = GetCallbacks(env, this);
+
+            // Keep AppDomain check here to avoid JITting GetCallbacksFromDefaultDomain method on .NET Core
+            // (which fails due to _AppDomain usage).
+            _callbacks = AppDomain.CurrentDomain.IsDefaultAppDomain()
+                ? new Callbacks(env, this)
+                : GetCallbacksFromDefaultDomain();
         }
 
         /// <summary>
         /// Gets the callbacks.
         /// </summary>
-        private static Callbacks GetCallbacks(Env env, Jvm jvm)
+        private static Callbacks GetCallbacksFromDefaultDomain()
         {
-            if (AppDomain.CurrentDomain.IsDefaultAppDomain())
-            {
-                return new Callbacks(env, jvm);
-            }
-
             // JVM exists once per process, and JVM callbacks exist once per process.
             // We should register callbacks ONLY from the default AppDomain (which can't be unloaded).
             // Non-default appDomains should delegate this logic to the default one.
@@ -278,21 +278,57 @@ namespace Apache.Ignite.Core.Impl.Unmanaged.Jni
             private readonly byte ignoreUnrecognized;
         }
 
+        private static class JniNativeMethods
+        {
+            internal static JniResult JNI_CreateJavaVM(out IntPtr pvm, out IntPtr penv,
+                JvmInitArgs* args)
+            {
+                return Os.IsWindows
+                    ? JniNativeMethodsWindows.JNI_CreateJavaVM(out pvm, out penv, args)
+                    : JniNativeMethodsLinux.JNI_CreateJavaVM(out pvm, out penv, args);
+            }
+
+            internal static JniResult JNI_GetCreatedJavaVMs(out IntPtr pvm, int size, out int size2)
+            {
+                return Os.IsWindows
+                    ? JniNativeMethodsWindows.JNI_GetCreatedJavaVMs(out pvm, size, out size2)
+                    : JniNativeMethodsLinux.JNI_GetCreatedJavaVMs(out pvm, size, out size2);
+            }
+        }
+
         /// <summary>
         /// DLL imports.
         /// </summary>
-        private static class JniNativeMethods
+        private static class JniNativeMethodsWindows
         {
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
             [DllImport("jvm.dll", CallingConvention = CallingConvention.StdCall)]
             internal static extern JniResult JNI_CreateJavaVM(out IntPtr pvm, out IntPtr penv,
                 JvmInitArgs* args);
 
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
             [DllImport("jvm.dll", CallingConvention = CallingConvention.StdCall)]
             internal static extern JniResult JNI_GetCreatedJavaVMs(out IntPtr pvm, int size,
                 [Out] out int size2);
         }
 
         /// <summary>
+        /// DLL imports.
+        /// </summary>
+        private static class JniNativeMethodsLinux
+        {
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("libjvm.so", CallingConvention = CallingConvention.StdCall)]
+            internal static extern JniResult JNI_CreateJavaVM(out IntPtr pvm, out IntPtr penv,
+                JvmInitArgs* args);
+
+            [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
+            [DllImport("libjvm.so", CallingConvention = CallingConvention.StdCall)]
+            internal static extern JniResult JNI_GetCreatedJavaVMs(out IntPtr pvm, int size,
+                [Out] out int size2);
+        }
+
+        /// <summary>
         /// Provides access to <see cref="Callbacks"/> instance in the default AppDomain.
         /// </summary>
         private class CallbackAccessor : MarshalByRefObject
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Os.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/Os.cs
new file mode 100644 (file)
index 0000000..22ab447
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.Unmanaged
+{
+    using System;
+
+    /// <summary>
+    /// Operating system / platform detector.
+    /// </summary>
+    internal static class Os
+    {
+        /// <summary>
+        /// Initializes the <see cref="Os"/> class.
+        /// </summary>
+        static Os()
+        {
+            var platform = Environment.OSVersion.Platform;
+
+            IsLinux = platform == PlatformID.Unix
+                      || platform == PlatformID.MacOSX
+                      || (int) Environment.OSVersion.Platform == 128;
+
+            IsWindows = platform == PlatformID.Win32NT
+                        || platform == PlatformID.Win32S
+                        || platform == PlatformID.Win32Windows;
+
+            IsMono = Type.GetType("Mono.Runtime") != null;
+            IsNetCore = !IsMono;
+        }
+
+        /// <summary>
+        /// .NET Core.
+        /// </summary>
+        public static bool IsNetCore { get; set; }
+
+        /// <summary>
+        /// Mono.
+        /// </summary>
+        public static bool IsMono { get; private set; }
+
+        /// <summary>
+        /// Windows.
+        /// </summary>
+        public static bool IsWindows { get; private set; }
+
+        /// <summary>
+        /// Linux.
+        /// </summary>
+        public static bool IsLinux { get; private set; }
+    }
+}
index e7cdad4..19e5484 100644 (file)
@@ -33,7 +33,7 @@ $project.ConfigurationManager | % {
     $binDir = ($_.Properties | Where Name -match OutputPath).Value
 
     $binPath = Join-Path $projPath $binDir
-    $libsPath = Join-Path $binPath "Libs"
+    $libsPath = Join-Path $binPath "libs"
 
     Remove-Item -Force -Recurse -ErrorAction SilentlyContinue $libsPath
 }
index ed111d1..27e823c 100644 (file)
@@ -13,8 +13,8 @@
 $solutionDir = [System.IO.Path]::GetDirectoryName($dte.Solution.FullName) + "\"
 $path = $installPath.Replace($solutionDir, "`$(SolutionDir)")
 
-$Jars = Join-Path $path "Libs\*.*"
+$Jars = Join-Path $path "libs\*.*"
 
 $IgnitePostBuildCmd = "
-if not exist `"`$(TargetDir)Libs`" md `"`$(TargetDir)Libs`"
-xcopy /s /y `"$Jars`" `"`$(TargetDir)Libs`""
\ No newline at end of file
+if not exist `"`$(TargetDir)libs`" md `"`$(TargetDir)libs`"
+xcopy /s /y `"$Jars`" `"`$(TargetDir)libs`""
\ No newline at end of file
index 634c78e..4ec71a8 100644 (file)
@@ -29,7 +29,7 @@ $project.ConfigurationManager | % {
     $binDir = ($_.Properties | Where Name -match OutputPath).Value
 
     $binPath = Join-Path $projPath $binDir
-    $libsPath = Join-Path $binPath "Libs"
+    $libsPath = Join-Path $binPath "libs"
 
     Remove-Item -Force -Recurse -ErrorAction SilentlyContinue $libsPath
 }
\ No newline at end of file
index 477dcf8..6779589 100644 (file)
@@ -54,4 +54,8 @@ More info: https://apacheignite-net.readme.io/
             <dependency id="EntityFramework" version="[6.1.0,7.0.0)" />
         </dependencies>    
     </metadata>
+    <files>
+           <file src="bin\$configuration$\Apache.Ignite.EntityFramework.dll" target="lib\net40" />
+               <file src="bin\$configuration$\Apache.Ignite.EntityFramework.xml" target="lib\net40" />
+    </files>
 </package>
\ No newline at end of file
index c71d672..5e553c2 100644 (file)
@@ -43,6 +43,8 @@ LINQ Provider for Apache Ignite
 
 Query distributed in-memory data in a strongly-typed manner and with IDE support!
 All Ignite SQL features are supported: distributed joins, groupings, aggregates, field queries, and more.
+
+Supports .NET 4+ and .NET Core 2.0+.
             
 More info: https://apacheignite-net.readme.io/
         </description>
@@ -55,6 +57,9 @@ More info: https://apacheignite-net.readme.io/
         </dependencies>    
     </metadata>
     <files>
+           <file src="bin\$configuration$\Apache.Ignite.Linq.dll" target="lib\net40" />
+               <file src="bin\$configuration$\Apache.Ignite.Linq.xml" target="lib\net40" />
+
         <!-- LINQPad samples -->
         <file src="NuGet\LINQPad\*.*" target="linqpad-samples" />
     </files>
index a3f86c1..1ad217b 100644 (file)
@@ -47,4 +47,8 @@ Creating NuGet package:
             <dependency id="log4net" version="[2.0.0, 3.0.0)" />
         </dependencies>    
     </metadata>
+    <files>
+           <file src="bin\$configuration$\Apache.Ignite.Log4Net.dll" target="lib\net40" />
+               <file src="bin\$configuration$\Apache.Ignite.Log4Net.xml" target="lib\net40" />
+    </files>
 </package>
\ No newline at end of file
index e3a6f42..63176d4 100644 (file)
@@ -47,4 +47,8 @@ Creating NuGet package:
             <dependency id="NLog" version="[4.0.0, 5.0.0)" />
         </dependencies>    
     </metadata>
+    <files>
+           <file src="bin\$configuration$\Apache.Ignite.NLog.dll" target="lib\net40" />
+               <file src="bin\$configuration$\Apache.Ignite.NLog.xml" target="lib\net40" />
+    </files>
 </package>
\ No newline at end of file
index 34aaa4c..aa30019 100644 (file)
@@ -7218,7 +7218,7 @@ select new {
 //<HowToFix>
 // *Pascal Case* the names of matched types.
 //</HowToFix>]]></Query>
-      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods name should begin with an Upper character</Name>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods name should begin with an Upper character</Name>
 warnif count > 0 
 from m in JustMyCode.Methods where 
   !m.NameLike (@"^[A-Z]") && 
index 7ff7278..3acbe47 100644 (file)
@@ -246,10 +246,6 @@ if (!$skipNuGet) {
     # Find all nuspec files and run 'nuget pack' either directly, or on corresponding csproj files (if present)
     ls *.nuspec -Recurse  `
         | % { 
-            If (Test-Path ([io.path]::ChangeExtension($_.FullName, ".csproj"))){
-                [io.path]::ChangeExtension($_.FullName, ".csproj")
-            } Else { $_.FullName }
-        } | % { 
             & $ng pack $_ -Prop Configuration=Release -Prop Platform=AnyCPU -Version $ver -OutputDirectory $nupkgDir
 
             # check result