ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [32/37] ignite git commit: IGNITE-1513: WIP on .Net.
Date Tue, 22 Sep 2015 07:19:34 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/FailoverTaskSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/FailoverTaskSelfTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/FailoverTaskSelfTest.cs
new file mode 100644
index 0000000..e46ec64
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/FailoverTaskSelfTest.cs
@@ -0,0 +1,246 @@
+/*
+ * 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.Compute
+{
+    using System;
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Portable;
+    using Apache.Ignite.Core.Resource;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Test for task and job adapter.
+    /// </summary>
+    public class FailoverTaskSelfTest : AbstractTaskTest
+    {
+        /** */
+        static volatile string _gridName;
+
+        /** */
+        static volatile int _cnt;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public FailoverTaskSelfTest() : base(false) { }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="fork">Fork flag.</param>
+        protected FailoverTaskSelfTest(bool fork) : base(fork) { }
+
+        /// <summary>
+        /// Test for GridComputeJobFailoverException.
+        /// </summary>
+        [Test]
+        public void TestClosureFailoverException()
+        {
+            for (int i = 0; i < 20; i++)
+            {
+                int res = Grid1.GetCompute().Call(new TestClosure());
+
+                Assert.AreEqual(2, res);
+
+                Cleanup();
+            }
+        }
+
+        /// <summary>
+        /// Test for GridComputeJobFailoverException with serializable job.
+        /// </summary>
+        [Test]
+        public void TestTaskAdapterFailoverExceptionSerializable()
+        {
+            TestTaskAdapterFailoverException(true);
+        }
+
+        /// <summary>
+        /// Test for GridComputeJobFailoverException with portable job.
+        /// </summary>
+        [Test]
+        public void TestTaskAdapterFailoverExceptionPortable()
+        {
+            TestTaskAdapterFailoverException(false);
+        }
+
+        /// <summary>
+        /// Test for GridComputeJobFailoverException.
+        /// </summary>
+        private void TestTaskAdapterFailoverException(bool serializable)
+        {
+            int res = Grid1.GetCompute().Execute(new TestTask(),
+                new Tuple<bool, bool>(serializable, true));
+
+            Assert.AreEqual(2, res);
+
+            Cleanup();
+
+            res = Grid1.GetCompute().Execute(new TestTask(),
+                new Tuple<bool, bool>(serializable, false));
+
+            Assert.AreEqual(2, res);
+        }
+
+        /// <summary>
+        /// Cleanup.
+        /// </summary>
+        [TearDown]
+        public void Cleanup()
+        {
+            _cnt = 0;
+
+            _gridName = null;
+        }
+
+        /** <inheritDoc /> */
+        override protected void PortableTypeConfigurations(ICollection<PortableTypeConfiguration> portTypeCfgs)
+        {
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(TestPortableJob)));
+        }
+
+        /// <summary>
+        /// Test task.
+        /// </summary>
+        public class TestTask : ComputeTaskAdapter<Tuple<bool, bool>, int, int>
+        {
+            /** <inheritDoc /> */
+            override public IDictionary<IComputeJob<int>, IClusterNode> Map(IList<IClusterNode> subgrid, Tuple<bool, bool> arg)
+            {
+                Assert.AreEqual(3, subgrid.Count);
+
+                Tuple<bool, bool> t = arg;
+
+                bool serializable = t.Item1;
+                bool local = t.Item2;
+
+                IDictionary<IComputeJob<int>, IClusterNode> jobs = new Dictionary<IComputeJob<int>, IClusterNode>();
+
+                IComputeJob<int> job;
+
+                if (serializable)
+                    job = new TestSerializableJob();
+                else
+                    job = new TestPortableJob();
+
+                foreach (IClusterNode node in subgrid) {
+                    bool add = local ? node.IsLocal : !node.IsLocal;
+
+                    if (add)
+                    {
+                        jobs.Add(job, node);
+
+                        break;
+                    }
+                }
+
+                Assert.AreEqual(1, jobs.Count);
+
+                return jobs;
+            }
+
+            /** <inheritDoc /> */
+            override public int Reduce(IList<IComputeJobResult<int>> results)
+            {
+                Assert.AreEqual(1, results.Count);
+
+                return results[0].Data();
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [Serializable]
+        class TestClosure : IComputeFunc<int>
+        {
+            [InstanceResource]
+            private IIgnite _grid = null;
+
+            /** <inheritDoc /> */
+            public int Invoke()
+            {
+                return FailoverJob(_grid);
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [Serializable]
+        class TestSerializableJob : IComputeJob<int>
+        {
+            [InstanceResource]
+            private IIgnite _grid = null;
+
+            /** <inheritDoc /> */
+            public int Execute()
+            {
+                return FailoverJob(_grid);
+            }
+
+            /** <inheritDoc /> */
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        class TestPortableJob : IComputeJob<int>
+        {
+            [InstanceResource]
+            private IIgnite _grid = null;
+
+            /** <inheritDoc /> */
+            public int Execute()
+            {
+                return FailoverJob(_grid);
+            }
+
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        /// Throws GridComputeJobFailoverException on first call.
+        /// </summary>
+        private static int FailoverJob(IIgnite grid)
+        {
+            Assert.NotNull(grid);
+
+            _cnt++;
+
+            if (_gridName == null)
+            {
+                _gridName = grid.Name;
+
+                throw new ComputeJobFailoverException("Test error.");
+            }
+            Assert.AreNotEqual(_gridName, grid.Name);
+
+            return _cnt;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.cs
new file mode 100644
index 0000000..4ce917b
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.cs
@@ -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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Compute.Forked
+{
+    /// <summary>
+    /// Forked closure execution tests for portable objects.
+    /// </summary>
+    public class ForkedPortableClosureTaskTest : PortableClosureTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public ForkedPortableClosureTaskTest() : base(true) { }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedResourceTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedResourceTaskTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedResourceTaskTest.cs
new file mode 100644
index 0000000..84c1ba2
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedResourceTaskTest.cs
@@ -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.Compute.Forked
+{
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Forked resource task test.
+    /// </summary>
+    [Ignore("IGNITE-1381")]
+    public class ForkedResourceTaskTest : ResourceTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public ForkedResourceTaskTest() : base(true) { }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedSerializableClosureTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedSerializableClosureTaskTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedSerializableClosureTaskTest.cs
new file mode 100644
index 0000000..0324125
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedSerializableClosureTaskTest.cs
@@ -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.Compute.Forked
+{
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Forked closure execution tests for serializable objects.
+    /// </summary>
+    [Ignore("IGNITE-1381")]
+    public class ForkedSerializableClosureTaskTest : SerializableClosureTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public ForkedSerializableClosureTaskTest() : base(true) { }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.cs
new file mode 100644
index 0000000..a4cf182
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.cs
@@ -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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Compute.Forked
+{
+    /// <summary>
+    /// Forked task adapter test.
+    /// </summary>
+    public class ForkedTaskAdapterTest : TaskAdapterTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public ForkedTaskAdapterTest() : base(true) { }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs
new file mode 100644
index 0000000..62f860d
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs
@@ -0,0 +1,753 @@
+/*
+ * 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.Compute
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Resource;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests for exception handling on various task execution stages.
+    /// </summary>
+    public class IgniteExceptionTaskSelfTest : AbstractTaskTest
+    {
+        /** Error mode. */
+        public static ErrorMode Mode;
+
+        /** Observed job errors. */
+        public static readonly ICollection<Exception> JobErrs = new List<Exception>();
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public IgniteExceptionTaskSelfTest() : base(false) { }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="fork">Fork flag.</param>
+        protected IgniteExceptionTaskSelfTest(bool fork) : base(fork) { }
+
+        /// <summary>
+        /// Test error occurred during map step.
+        /// </summary>
+        [Test]
+        public void TestMapError()
+        {
+            Mode = ErrorMode.MapErr;
+
+            GoodException e = ExecuteWithError() as GoodException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.MapErr, e.Mode);
+        }
+
+        /// <summary>
+        /// Test not-marshalable error occurred during map step.
+        /// </summary>
+        [Test]
+        public void TestMapNotMarshalableError()
+        {
+            Mode = ErrorMode.MapErrNotMarshalable;
+
+            BadException e = ExecuteWithError() as BadException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.MapErrNotMarshalable, e.Mode);
+        }
+
+        /// <summary>
+        /// Test task behavior when job produced by mapper is not marshalable.
+        /// </summary>
+        [Test]
+        public void TestMapNotMarshalableJob()
+        {
+            Mode = ErrorMode.MapJobNotMarshalable;
+
+            SerializationException e = ExecuteWithError() as SerializationException;
+
+            Assert.IsNotNull(e);
+        }
+
+        /// <summary>
+        /// Test local job error.
+        /// </summary>
+        [Test]
+        public void TestLocalJobError()
+        {
+            Mode = ErrorMode.LocJobErr;
+
+            int res = Execute();
+
+            Assert.AreEqual(2, res);
+
+            Assert.AreEqual(1, JobErrs.Count);
+            Assert.IsNotNull(JobErrs.First() as GoodException);
+            Assert.AreEqual(ErrorMode.LocJobErr, ((GoodException) JobErrs.First()).Mode);
+        }
+
+        /// <summary>
+        /// Test local not-marshalable job error.
+        /// </summary>
+        [Test]
+        public void TestLocalJobErrorNotMarshalable()
+        {
+            Mode = ErrorMode.LocJobErrNotMarshalable;
+
+            int res = Execute();
+
+            Assert.AreEqual(2, res);
+
+            Assert.AreEqual(1, JobErrs.Count);
+            Assert.IsNotNull(JobErrs.First() as BadException); // Local job exception is not marshalled.
+        }
+
+        /// <summary>
+        /// Test local not-marshalable job result.
+        /// </summary>
+        [Test]
+        public void TestLocalJobResultNotMarshalable()
+        {
+            Mode = ErrorMode.LocJobResNotMarshalable;
+
+            int res = Execute();
+
+            Assert.AreEqual(3, res); // Local job result is not marshalled.
+
+            Assert.AreEqual(0, JobErrs.Count);
+        }
+
+        /// <summary>
+        /// Test remote job error.
+        /// </summary>
+        [Test]
+        public void TestRemoteJobError()
+        {
+            Mode = ErrorMode.RmtJobErr;
+
+            int res = Execute();
+
+            Assert.AreEqual(1, res);
+
+            Assert.AreEqual(2, JobErrs.Count);
+
+            Assert.IsNotNull(JobErrs.ElementAt(0) as GoodException);
+            Assert.IsNotNull(JobErrs.ElementAt(1) as GoodException);
+
+            Assert.AreEqual(ErrorMode.RmtJobErr, ((GoodException) JobErrs.ElementAt(0)).Mode);
+            Assert.AreEqual(ErrorMode.RmtJobErr, ((GoodException) JobErrs.ElementAt(1)).Mode);
+        }
+
+        /// <summary>
+        /// Test remote not-marshalable job error.
+        /// </summary>
+        [Test]
+        public void TestRemoteJobErrorNotMarshalable()
+        {
+            Mode = ErrorMode.RmtJobErrNotMarshalable;
+
+            int res = Execute();
+
+            Assert.AreEqual(1, res);
+
+            Assert.AreEqual(2, JobErrs.Count);
+
+            Assert.IsNotNull(JobErrs.ElementAt(0) as IgniteException);
+            Assert.IsNotNull(JobErrs.ElementAt(1) as IgniteException);
+        }
+
+        /// <summary>
+        /// Test local not-marshalable job result.
+        /// </summary>
+        [Test]
+        public void TestRemoteJobResultNotMarshalable()
+        {
+            Mode = ErrorMode.RmtJobResNotMarshalable;
+
+            int res = Execute();
+
+            Assert.AreEqual(1, res);
+
+            Assert.AreEqual(2, JobErrs.Count);
+
+            Assert.IsNotNull(JobErrs.ElementAt(0) as IgniteException);
+            Assert.IsNotNull(JobErrs.ElementAt(1) as IgniteException);
+        }
+
+        /// <summary>
+        /// Test local result error.
+        /// </summary>
+        [Test]
+        public void TestLocalResultError()
+        {
+            Mode = ErrorMode.LocResErr;
+
+            GoodException e = ExecuteWithError() as GoodException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.LocResErr, e.Mode);
+        }
+
+        /// <summary>
+        /// Test local result not-marshalable error.
+        /// </summary>
+        [Test]
+        public void TestLocalResultErrorNotMarshalable()
+        {
+            Mode = ErrorMode.LocResErrNotMarshalable;
+
+            BadException e = ExecuteWithError() as BadException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.LocResErrNotMarshalable, e.Mode);
+        }
+
+        /// <summary>
+        /// Test remote result error.
+        /// </summary>
+        [Test]
+        public void TestRemoteResultError()
+        {
+            Mode = ErrorMode.RmtResErr;
+
+            GoodException e = ExecuteWithError() as GoodException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.RmtResErr, e.Mode);
+        }
+
+        /// <summary>
+        /// Test remote result not-marshalable error.
+        /// </summary>
+        [Test]
+        public void TestRemoteResultErrorNotMarshalable()
+        {
+            Mode = ErrorMode.RmtResErrNotMarshalable;
+
+            BadException e = ExecuteWithError() as BadException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.RmtResErrNotMarshalable, e.Mode);
+        }
+
+        /// <summary>
+        /// Test reduce with error.
+        /// </summary>
+        [Test]
+        public void TestReduceError()
+        {
+            Mode = ErrorMode.ReduceErr;
+
+            GoodException e = ExecuteWithError() as GoodException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.ReduceErr, e.Mode);
+        }
+
+        /// <summary>
+        /// Test reduce with not-marshalable error.
+        /// </summary>
+        [Test]
+        public void TestReduceErrorNotMarshalable()
+        {
+            Mode = ErrorMode.ReduceErrNotMarshalable;
+
+            BadException e = ExecuteWithError() as BadException;
+
+            Assert.IsNotNull(e);
+
+            Assert.AreEqual(ErrorMode.ReduceErrNotMarshalable, e.Mode);
+        }
+
+        /// <summary>
+        /// Test reduce with not-marshalable result.
+        /// </summary>
+        [Test]
+        public void TestReduceResultNotMarshalable()
+        {
+            Mode = ErrorMode.ReduceResNotMarshalable;
+
+            int res = Execute();
+
+            Assert.AreEqual(3, res);
+        }
+
+        /// <summary>
+        /// Execute task successfully.
+        /// </summary>
+        /// <returns>Task result.</returns>
+        private int Execute()
+        {
+            JobErrs.Clear();
+
+            object res = Grid1.GetCompute().Execute(new Task());
+
+            return res is GoodTaskResult ? ((GoodTaskResult)res).Res : ((BadTaskResult)res).Res;
+        }
+
+        /// <summary>
+        /// Execute task with error.
+        /// </summary>
+        /// <returns>Task</returns>
+        private Exception ExecuteWithError()
+        {
+            JobErrs.Clear();
+
+            Exception err = null;
+
+            try
+            {
+                Grid1.GetCompute().Execute(new Task());
+
+                Assert.Fail();
+            }
+            catch (Exception e)
+            {
+                err = e;
+            }
+
+            return err;
+        }
+
+        /// <summary>
+        /// Error modes.
+        /// </summary>
+        public enum ErrorMode
+        {
+            /** Error during map step. */
+            MapErr,
+
+            /** Error during map step which is not marshalable. */
+            MapErrNotMarshalable,
+
+            /** Job created by mapper is not marshalable. */
+            MapJobNotMarshalable,
+
+            /** Error occurred in local job. */
+            LocJobErr,
+
+            /** Error occurred in local job and is not marshalable. */
+            LocJobErrNotMarshalable,
+
+            /** Local job result is not marshalable. */
+            LocJobResNotMarshalable,
+
+            /** Error occurred in remote job. */
+            RmtJobErr,
+
+            /** Error occurred in remote job and is not marshalable. */
+            RmtJobErrNotMarshalable,
+
+            /** Remote job result is not marshalable. */
+            RmtJobResNotMarshalable,            
+
+            /** Error occurred during local result processing. */
+            LocResErr,
+
+            /** Error occurred during local result processing and is not marshalable. */
+            LocResErrNotMarshalable,
+
+            /** Error occurred during remote result processing. */
+            RmtResErr,
+
+            /** Error occurred during remote result processing and is not marshalable. */
+            RmtResErrNotMarshalable,
+
+            /** Error during reduce step. */
+            ReduceErr,
+
+            /** Error during reduce step and is not marshalable. */
+            ReduceErrNotMarshalable,
+
+            /** Reduce result is not marshalable. */
+            ReduceResNotMarshalable
+        }
+
+        /// <summary>
+        /// Task.
+        /// </summary>
+        public class Task : IComputeTask<object, object>
+        {
+            /** Grid. */
+            [InstanceResource]
+            private IIgnite _grid = null;
+
+            /** Result. */
+            private int _res;
+
+            /** <inheritDoc /> */
+            public IDictionary<IComputeJob<object>, IClusterNode> Map(IList<IClusterNode> subgrid, object arg)
+            {
+                switch (Mode)
+                {
+                    case ErrorMode.MapErr:
+                        throw new GoodException(ErrorMode.MapErr);
+
+                    case ErrorMode.MapErrNotMarshalable:
+                        throw new BadException(ErrorMode.MapErrNotMarshalable);
+
+                    case ErrorMode.MapJobNotMarshalable:
+                    {
+                        var badJobs = new Dictionary<IComputeJob<object>, IClusterNode>();
+
+                        foreach (IClusterNode node in subgrid)
+                            badJobs.Add(new BadJob(), node);
+
+                        return badJobs;
+                    }
+                }
+
+                // Map completes sucessfully and we spread jobs to all nodes.
+                var jobs = new Dictionary<IComputeJob<object>, IClusterNode>();
+
+                foreach (IClusterNode node in subgrid)
+                    jobs.Add(new GoodJob(!_grid.GetCluster().GetLocalNode().Id.Equals(node.Id)), node);
+
+                return jobs;
+            }
+
+            /** <inheritDoc /> */
+            public ComputeJobResultPolicy Result(IComputeJobResult<object> res, IList<IComputeJobResult<object>> rcvd)
+            {
+                if (res.Exception() != null)
+                    JobErrs.Add(res.Exception());
+                else
+                {
+                    object res0 = res.Data();
+
+                    bool rmt = res0 is GoodJobResult ? ((GoodJobResult)res0).Rmt : ((BadJobResult)res0).Rmt;
+
+                    if (rmt)
+                    {
+                        switch (Mode)
+                        {
+                            case ErrorMode.RmtResErr:
+                                throw new GoodException(ErrorMode.RmtResErr);
+
+                            case ErrorMode.RmtResErrNotMarshalable:
+                                throw new BadException(ErrorMode.RmtResErrNotMarshalable);
+                        }
+                    }
+                    else
+                    {
+                        switch (Mode)
+                        {
+                            case ErrorMode.LocResErr:
+                                throw new GoodException(ErrorMode.LocResErr);
+
+                            case ErrorMode.LocResErrNotMarshalable:
+                                throw new BadException(ErrorMode.LocResErrNotMarshalable);
+                        }
+                    }
+
+                    _res += 1;
+                }
+
+                return ComputeJobResultPolicy.Wait;
+            }
+
+            /** <inheritDoc /> */
+            public object Reduce(IList<IComputeJobResult<object>> results)
+            {
+                switch (Mode)
+                {
+                    case ErrorMode.ReduceErr:
+                        throw new GoodException(ErrorMode.ReduceErr);
+
+                    case ErrorMode.ReduceErrNotMarshalable:
+                        throw new BadException(ErrorMode.ReduceErrNotMarshalable);
+
+                    case ErrorMode.ReduceResNotMarshalable:
+                        return new BadTaskResult(_res);
+                }
+
+                return new GoodTaskResult(_res);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [Serializable]
+        public class GoodJob : IComputeJob<object>
+        {
+            /** Whether the job is remote. */
+            private bool _rmt;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="rmt"></param>
+            public GoodJob(bool rmt)
+            {
+                _rmt = rmt;
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public GoodJob(SerializationInfo info, StreamingContext context)
+            {
+                _rmt = info.GetBoolean("rmt");
+            }
+
+            /** <inheritDoc /> */
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("rmt", _rmt);
+            }
+
+            /** <inheritDoc /> */
+            public object Execute()
+            {
+                if (_rmt)
+                {
+                    switch (Mode)
+                    {
+                        case ErrorMode.RmtJobErr:
+                            throw new GoodException(ErrorMode.RmtJobErr);
+
+                        case ErrorMode.RmtJobErrNotMarshalable:
+                            throw new BadException(ErrorMode.RmtJobErr);
+
+                        case ErrorMode.RmtJobResNotMarshalable:
+                            return new BadJobResult(_rmt);
+                    }
+                }
+                else
+                {
+                    switch (Mode)
+                    {
+                        case ErrorMode.LocJobErr:
+                            throw new GoodException(ErrorMode.LocJobErr);
+
+                        case ErrorMode.LocJobErrNotMarshalable:
+                            throw new BadException(ErrorMode.LocJobErr);
+
+                        case ErrorMode.LocJobResNotMarshalable:
+                            return new BadJobResult(_rmt);
+                    }
+                }
+
+                return new GoodJobResult(_rmt);
+            }
+
+            /** <inheritDoc /> */
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public class BadJob : IComputeJob<object>
+        {
+            [InstanceResource]
+
+            /** <inheritDoc /> */
+            public object Execute()
+            {
+                throw new NotImplementedException();
+            }
+
+            /** <inheritDoc /> */
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [Serializable]
+        public class GoodJobResult
+        {
+            /** */
+            public bool Rmt;
+            
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="rmt"></param>
+            public GoodJobResult(bool rmt)
+            {
+                Rmt = rmt;
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public GoodJobResult(SerializationInfo info, StreamingContext context)
+            {
+                Rmt = info.GetBoolean("rmt");
+            }
+
+            /** <inheritDoc /> */
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("rmt", Rmt);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public class BadJobResult
+        {
+            /** */
+            public bool Rmt;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="rmt"></param>
+            public BadJobResult(bool rmt)
+            {
+                Rmt = rmt;
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [Serializable]
+        public class GoodTaskResult
+        {
+            /** */
+            public int Res;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="res"></param>
+            public GoodTaskResult(int res)
+            {
+                Res = res;
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public GoodTaskResult(SerializationInfo info, StreamingContext context)
+            {
+                Res = info.GetInt32("res");
+            }
+
+            /** <inheritDoc /> */
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("res", Res);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public class BadTaskResult
+        {
+            /** */
+            public int Res;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="res"></param>
+            public BadTaskResult(int res)
+            {
+                Res = res;
+            }
+        }
+
+        /// <summary>
+        /// Marshalable exception.
+        /// </summary>
+        [Serializable]
+        public class GoodException : Exception
+        {
+            /** */
+            public ErrorMode Mode;
+            
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="mode"></param>
+            public GoodException(ErrorMode mode)
+            {
+                Mode = mode;
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public GoodException(SerializationInfo info, StreamingContext context)
+            {
+                Mode = (ErrorMode)info.GetInt32("mode");
+            }
+
+            /** <inheritDoc /> */
+            public override void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("mode", (int)Mode);
+
+                base.GetObjectData(info, context);
+            }
+        }
+
+        /// <summary>
+        /// Not marshalable exception.
+        /// </summary>
+        public class BadException : Exception
+        {
+            /** */
+            public ErrorMode Mode;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="mode"></param>
+            public BadException(ErrorMode mode)
+            {
+                Mode = mode;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableClosureTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableClosureTaskTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableClosureTaskTest.cs
new file mode 100644
index 0000000..3ca933e
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableClosureTaskTest.cs
@@ -0,0 +1,217 @@
+/*
+ * 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.Compute
+{
+    using System;
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Portable;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Closure execution tests for portable objects.
+    /// </summary>
+    public class PortableClosureTaskTest : ClosureTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public PortableClosureTaskTest() : base(false) { }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="fork">Fork flag.</param>
+        protected PortableClosureTaskTest(bool fork) : base(fork) { }
+
+        /** <inheritDoc /> */
+        protected override void PortableTypeConfigurations(ICollection<PortableTypeConfiguration> portTypeCfgs)
+        {
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableOutFunc)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableFunc)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableResult)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableException)));
+        }
+
+        /** <inheritDoc /> */
+        protected override IComputeFunc<object> OutFunc(bool err)
+        {
+            return new PortableOutFunc(err);
+        }
+
+        /** <inheritDoc /> */
+        protected override IComputeFunc<object, object> Func(bool err)
+        {
+            return new PortableFunc(err);
+        }
+
+        /** <inheritDoc /> */
+        protected override void CheckResult(object res)
+        {
+            Assert.IsTrue(res != null);
+
+            PortableResult res0 = res as PortableResult;
+
+            Assert.IsTrue(res0 != null);
+            Assert.AreEqual(1, res0.Res);
+        }
+
+        /** <inheritDoc /> */
+        protected override void CheckError(Exception err)
+        {
+            Assert.IsTrue(err != null);
+
+            PortableException err0 = err as PortableException;
+
+            Assert.IsTrue(err0 != null);
+            Assert.AreEqual(ErrMsg, err0.Msg);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        private class PortableOutFunc : IComputeFunc<object>
+        {
+            /** Error. */
+            private bool _err;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            public PortableOutFunc()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="err"></param>
+            public PortableOutFunc(bool err)
+            {
+                _err = err;
+            }
+            
+            /** <inheritDoc /> */
+            public object Invoke()
+            {
+                if (_err)
+                    throw new PortableException(ErrMsg);
+                return new PortableResult(1);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        private class PortableFunc : IComputeFunc<object, object>
+        {
+            /** Error. */
+            private bool _err;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            public PortableFunc()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="err"></param>
+            public PortableFunc(bool err)
+            {
+                _err = err;
+            }
+            
+            /** <inheritDoc /> */
+            public object Invoke(object arg)
+            {
+                if (_err)
+                    throw new PortableException(ErrMsg);
+                return new PortableResult(1);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        private class PortableException : Exception, IPortableMarshalAware
+        {
+            /** */
+            public string Msg;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            public PortableException()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="msg"></param>
+            public PortableException(string msg) : this()
+            {
+                Msg = msg;
+            }
+
+            /** <inheritDoc /> */
+            public void WritePortable(IPortableWriter writer)
+            {
+                writer.RawWriter().WriteString(Msg);
+            }
+
+            /** <inheritDoc /> */
+            public void ReadPortable(IPortableReader reader)
+            {
+                Msg = reader.RawReader().ReadString();
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        private class PortableResult
+        {
+            /** */
+            public int Res;
+
+            /// <summary>
+            /// 
+            /// </summary>
+            public PortableResult()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="res"></param>
+            public PortableResult(int res)
+            {
+                Res = res;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableTaskTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableTaskTest.cs
new file mode 100644
index 0000000..736aa61
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/PortableTaskTest.cs
@@ -0,0 +1,253 @@
+/*
+ * 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.Compute
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Portable;
+    using Apache.Ignite.Core.Resource;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Task test result.
+    /// </summary>
+    public class PortableTaskTest : AbstractTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public PortableTaskTest() : base(false) { }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="fork">Fork flag.</param>
+        protected PortableTaskTest(bool fork) : base(fork) { }
+
+        /// <summary>
+        /// Test for task result.
+        /// </summary>
+        [Test]
+        public void TestPortableObjectInTask()
+        {
+            IPortableObject taskArg = ToPortable(Grid1, new PortableTaskArgument(100));
+
+            TestTask task = new TestTask(Grid1, taskArg);
+
+            IPortableObject res = Grid1.GetCompute().Execute(task, taskArg);
+
+            Assert.NotNull(res);
+
+            Assert.AreEqual(400, res.GetField<int>("val"));
+
+            PortableTaskResult resObj = res.Deserialize<PortableTaskResult>();
+
+            Assert.AreEqual(400, resObj.Val);
+        }
+
+        private static IPortableObject ToPortable(IIgnite grid, object obj)
+        {
+            var cache = grid.GetCache<object, object>(Cache1Name).WithKeepPortable<object, object>();
+
+            cache.Put(1, obj);
+
+            return (IPortableObject) cache.Get(1);
+        }
+
+        /** <inheritDoc /> */
+        override protected void PortableTypeConfigurations(ICollection<PortableTypeConfiguration> portTypeCfgs)
+        {
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableJobArgument)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableJobResult)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableTaskArgument)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableTaskResult)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableJob)));
+        }
+
+        /// <summary>
+        /// Test task.
+        /// </summary>
+        public class TestTask : ComputeTaskAdapter<IPortableObject, IPortableObject, IPortableObject>
+        {
+            /** */
+            private readonly IIgnite _grid;
+
+            private readonly IPortableObject _taskArgField;
+
+            public TestTask(IIgnite grid, IPortableObject taskArgField)
+            {
+                _grid = grid;
+                _taskArgField = taskArgField;
+            }
+
+            /** <inheritDoc /> */
+            override public IDictionary<IComputeJob<IPortableObject>, IClusterNode> Map(IList<IClusterNode> subgrid, IPortableObject arg)
+            {
+                Assert.AreEqual(3, subgrid.Count);
+                Assert.NotNull(_grid);
+
+                IPortableObject taskArg = arg;
+
+                CheckTaskArgument(taskArg);
+
+                CheckTaskArgument(_taskArgField);
+
+                IDictionary<IComputeJob<IPortableObject>, IClusterNode> jobs = new Dictionary<IComputeJob<IPortableObject>, IClusterNode>();
+
+
+                foreach (IClusterNode node in subgrid)
+                {
+                    if (!Grid3Name.Equals(node.GetAttribute<string>("org.apache.ignite.ignite.name"))) // Grid3 does not have cache.
+                    {
+                        PortableJob job = new PortableJob();
+
+                        job.Arg = ToPortable(_grid, new PortableJobArgument(200));
+
+                        jobs.Add(job, node);
+                    }
+                }
+
+                Assert.AreEqual(2, jobs.Count);
+
+                return jobs;
+            }
+
+            private void CheckTaskArgument(IPortableObject taskArg)
+            {
+                Assert.IsNotNull(taskArg);
+
+                Assert.AreEqual(100, taskArg.GetField<int>("val"));
+
+                PortableTaskArgument taskArgObj = taskArg.Deserialize<PortableTaskArgument>();
+
+                Assert.AreEqual(100, taskArgObj.Val);
+            }
+
+            /** <inheritDoc /> */
+            override public IPortableObject Reduce(IList<IComputeJobResult<IPortableObject>> results)
+            {
+                Assert.NotNull(_grid);
+
+                Assert.AreEqual(2, results.Count);
+
+                foreach (IComputeJobResult<IPortableObject> res in results)
+                {
+                    IPortableObject jobRes = res.Data();
+
+                    Assert.NotNull(jobRes);
+
+                    Assert.AreEqual(300, jobRes.GetField<int>("val"));
+
+                    PortableJobResult jobResObj = jobRes.Deserialize<PortableJobResult>();
+
+                    Assert.AreEqual(300, jobResObj.Val);
+                }
+
+                return ToPortable(_grid, new PortableTaskResult(400));
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        class PortableJobArgument
+        {
+            /** */
+            public int Val;
+
+            public PortableJobArgument(int val)
+            {
+                Val = val;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        class PortableJobResult
+        {
+            /** */
+            public int Val;
+
+            public PortableJobResult(int val)
+            {
+                Val = val;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        class PortableTaskArgument
+        {
+            /** */
+            public int Val;
+
+            public PortableTaskArgument(int val)
+            {
+                Val = val;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        class PortableTaskResult
+        {
+            /** */
+            public int Val;
+
+            public PortableTaskResult(int val)
+            {
+                Val = val;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        class PortableJob : IComputeJob<IPortableObject>
+        {
+            [InstanceResource]
+            private IIgnite _grid = null;
+            
+            /** */
+            public IPortableObject Arg;
+
+            /** <inheritDoc /> */
+            public IPortableObject Execute()
+            {
+                Assert.IsNotNull(Arg);
+
+                Assert.AreEqual(200, Arg.GetField<int>("val"));
+
+                PortableJobArgument argObj = Arg.Deserialize<PortableJobArgument>();
+
+                Assert.AreEqual(200, argObj.Val);
+
+                return ToPortable(_grid, new PortableJobResult(300));
+            }
+
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs
new file mode 100644
index 0000000..55bb9d0
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs
@@ -0,0 +1,568 @@
+/*
+ * 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.Compute
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Resource;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Test resource injections in tasks and jobs.
+    /// </summary>
+    public class ResourceTaskTest : AbstractTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public ResourceTaskTest() : base(false) { }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="fork">Fork flag.</param>
+        protected ResourceTaskTest(bool fork) : base(fork) { }
+
+        /// <summary>
+        /// Test Ignite injection into the task.
+        /// </summary>
+        [Test]
+        public void TestTaskInjection()
+        {
+            int res = Grid1.GetCompute().Execute(new InjectionTask(), 0);
+
+            Assert.AreEqual(Grid1.GetCluster().GetNodes().Count, res);
+        }
+
+        /// <summary>
+        /// Test Ignite injection into the closure.
+        /// </summary>
+        [Test]
+        public void TestClosureInjection()
+        {
+            var res = Grid1.GetCompute().Broadcast(new InjectionClosure(), 1);
+
+            Assert.AreEqual(Grid1.GetCluster().GetNodes().Count, res.Sum());
+        }
+
+        /// <summary>
+        /// Test Ignite injection into reducer.
+        /// </summary>
+        [Test]
+        public void TestReducerInjection()
+        {
+            int res = Grid1.GetCompute().Apply(new InjectionClosure(), new List<int> { 1, 1, 1 }, new InjectionReducer());
+
+            Assert.AreEqual(Grid1.GetCluster().GetNodes().Count, res);
+        }
+
+        /// <summary>
+        /// Test no-result-cache attribute.
+        /// </summary>
+        [Test]
+        public void TestNoResultCache()
+        {
+            int res = Grid1.GetCompute().Execute(new NoResultCacheTask(), 0);
+
+            Assert.AreEqual(Grid1.GetCluster().GetNodes().Count, res);
+        }
+
+        /// <summary>
+        /// Injection task.
+        /// </summary>
+        public class InjectionTask : Injectee, IComputeTask<object, int, int>
+        {
+            /** <inheritDoc /> */
+            public IDictionary<IComputeJob<int>, IClusterNode> Map(IList<IClusterNode> subgrid, object arg)
+            {
+                CheckInjection();
+
+                return subgrid.ToDictionary(x => (IComputeJob<int>) new InjectionJob(), x => x);
+            }
+
+            /** <inheritDoc /> */
+            public ComputeJobResultPolicy Result(IComputeJobResult<int> res, IList<IComputeJobResult<int>> rcvd)
+            {
+                return ComputeJobResultPolicy.Wait;
+            }
+
+            /** <inheritDoc /> */
+            public int Reduce(IList<IComputeJobResult<int>> results)
+            {
+                return results.Sum(res => res.Data());
+            }
+        }
+
+        /// <summary>
+        /// Injection job.
+        /// </summary>
+        [Serializable]
+        public class InjectionJob : Injectee, IComputeJob<int>
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            public InjectionJob()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public InjectionJob(SerializationInfo info, StreamingContext context) : base(info, context)
+            {
+                // No-op.
+            }
+
+            /** <inheritDoc /> */
+            public int Execute()
+            {
+                CheckInjection();
+
+                return 1;
+            }
+
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        /// Injection closure.
+        /// </summary>
+        [Serializable]
+        public class InjectionClosure : IComputeFunc<int, int>
+        {
+            /** */
+            [InstanceResource]
+            private static IIgnite _staticGrid1;
+
+            /** */
+            [InstanceResource]
+            public static IIgnite StaticGrid2;
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            public static IIgnite StaticPropGrid1
+            {
+                get { return _staticGrid1; }
+                set { _staticGrid1 = value; }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            private static IIgnite StaticPropGrid2
+            {
+                get { return StaticGrid2; }
+                set { StaticGrid2 = value; }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            public static void StaticMethod1(IIgnite grid)
+            {
+                _staticGrid1 = grid;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            private static void StaticMethod2(IIgnite grid)
+            {
+                StaticGrid2 = grid;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public InjectionClosure()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public InjectionClosure(SerializationInfo info, StreamingContext context)
+            {
+                // No-op.
+            }
+
+            /** */
+            [InstanceResource]
+            private readonly IIgnite _grid1 = null;
+
+            /** */
+            [InstanceResource]
+            public IIgnite Grid2;
+
+            /** */
+            private IIgnite _mthdGrid1;
+
+            /** */
+            private IIgnite _mthdGrid2;
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            public IIgnite PropGrid1
+            {
+                get;
+                set;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            private IIgnite PropGrid2
+            {
+                get;
+                set;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            public void Method1(IIgnite grid)
+            {
+                _mthdGrid1 = grid;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            private void Method2(IIgnite grid)
+            {
+                _mthdGrid2 = grid;
+            }
+
+            /// <summary>
+            /// Check Ignite injections.
+            /// </summary>
+            protected void CheckInjection()
+            {
+                Assert.IsTrue(_staticGrid1 == null);
+                Assert.IsTrue(StaticGrid2 == null);
+
+                Assert.IsTrue(_grid1 != null);
+                Assert.IsTrue(Grid2 == _grid1);
+
+                Assert.IsTrue(PropGrid1 == _grid1);
+                Assert.IsTrue(PropGrid2 == _grid1);
+
+                Assert.IsTrue(_mthdGrid1 == _grid1);
+                Assert.IsTrue(_mthdGrid2 == _grid1);
+            }
+
+            /** <inheritDoc /> */
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                // No-op.
+            }
+
+            /** <inheritDoc /> */
+            public int Invoke(int arg)
+            {
+                CheckInjection();
+
+                return arg;
+            }
+        }
+
+        /// <summary>
+        /// Injection reducer.
+        /// </summary>
+        public class InjectionReducer : Injectee, IComputeReducer<int, int>
+        {
+            /** Collected results. */
+            private readonly ICollection<int> _ress = new List<int>();
+
+            /** <inheritDoc /> */
+            public bool Collect(int res)
+            {
+                CheckInjection();
+
+                lock (_ress)
+                {
+                    _ress.Add(res);
+                }
+
+                return true;
+            }
+
+            /** <inheritDoc /> */
+            public int Reduce()
+            {
+                CheckInjection();
+
+                lock (_ress)
+                {
+                    return _ress.Sum();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Injectee.
+        /// </summary>
+        [Serializable]
+        public class Injectee : ISerializable
+        {
+            /** */
+            [InstanceResource]
+            private static IIgnite _staticGrid1;
+
+            /** */
+            [InstanceResource]
+            public static IIgnite StaticGrid2;
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            public static IIgnite StaticPropGrid1
+            {
+                get { return _staticGrid1; }
+                set { _staticGrid1 = value; }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            private static IIgnite StaticPropGrid2
+            {
+                get { return StaticGrid2; }
+                set { StaticGrid2 = value; }
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            public static void StaticMethod1(IIgnite grid)
+            {
+                _staticGrid1 = grid;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            private static void StaticMethod2(IIgnite grid)
+            {
+                StaticGrid2 = grid;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            public Injectee()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public Injectee(SerializationInfo info, StreamingContext context)
+            {
+                // No-op.
+            }
+
+            /** */
+            [InstanceResource]
+            private readonly IIgnite _grid1 = null;
+
+            /** */
+            [InstanceResource]
+            public IIgnite Grid2;
+
+            /** */
+            private IIgnite _mthdGrid1;
+
+            /** */
+            private IIgnite _mthdGrid2;
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            public IIgnite PropGrid1
+            {
+                get;
+                set;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            [InstanceResource]
+            private IIgnite PropGrid2
+            {
+                get;
+                set;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            public void Method1(IIgnite grid)
+            {
+                _mthdGrid1 = grid;
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="grid"></param>
+            [InstanceResource]
+            private void Method2(IIgnite grid)
+            {
+                _mthdGrid2 = grid;
+            }
+
+            /// <summary>
+            /// Check Ignite injections.
+            /// </summary>
+            protected void CheckInjection()
+            {
+                Assert.IsTrue(_staticGrid1 == null);
+                Assert.IsTrue(StaticGrid2 == null);
+
+                Assert.IsTrue(_grid1 != null);
+                Assert.IsTrue(Grid2 == _grid1);
+
+                Assert.IsTrue(PropGrid1 == _grid1);
+                Assert.IsTrue(PropGrid2 == _grid1);
+
+                Assert.IsTrue(_mthdGrid1 == _grid1);
+                Assert.IsTrue(_mthdGrid2 == _grid1);
+            }
+
+            /** <inheritDoc /> */
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [ComputeTaskNoResultCache]
+        public class NoResultCacheTask : IComputeTask<int, int, int>
+        {
+            /** Sum. */
+            private int _sum;
+
+            /** <inheritDoc /> */
+            public IDictionary<IComputeJob<int>, IClusterNode> Map(IList<IClusterNode> subgrid, int arg)
+            {
+                return subgrid.ToDictionary(x => (IComputeJob<int>) new NoResultCacheJob(), x => x);
+            }
+
+            /** <inheritDoc /> */
+            public ComputeJobResultPolicy Result(IComputeJobResult<int> res, IList<IComputeJobResult<int>> rcvd)
+            {
+                Assert.IsTrue(rcvd != null);
+                Assert.IsTrue(rcvd.Count == 0);
+
+                _sum += res.Data();
+
+                return ComputeJobResultPolicy.Wait;
+            }
+
+            /** <inheritDoc /> */
+            public int Reduce(IList<IComputeJobResult<int>> results)
+            {
+                Assert.IsTrue(results != null);
+                Assert.IsTrue(results.Count == 0);
+
+                return _sum;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [Serializable]
+        public class NoResultCacheJob : IComputeJob<int>
+        {
+            /// <summary>
+            ///
+            /// </summary>
+            public NoResultCacheJob()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public NoResultCacheJob(SerializationInfo info, StreamingContext context)
+            {
+                // No-op.
+            }
+
+            /** <inheritDoc /> */
+            public int Execute()
+            {
+                return 1;
+            }
+
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/SerializableClosureTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/SerializableClosureTaskTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/SerializableClosureTaskTest.cs
new file mode 100644
index 0000000..ded56ed
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/SerializableClosureTaskTest.cs
@@ -0,0 +1,217 @@
+/*
+ * 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.Compute
+{
+    using System;
+    using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Compute;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Closure execution tests for serializable objects.
+    /// </summary>
+    public class SerializableClosureTaskTest : ClosureTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public SerializableClosureTaskTest() : base(false) { }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="fork">Fork flag.</param>
+        protected SerializableClosureTaskTest(bool fork) : base(fork) { }
+
+        /** <inheritDoc /> */
+        protected override IComputeFunc<object> OutFunc(bool err)
+        {
+            return new SerializableOutFunc(err);
+        }
+
+        /** <inheritDoc /> */
+        protected override IComputeFunc<object, object> Func(bool err)
+        {
+            return new SerializableFunc(err);
+        }
+
+        /** <inheritDoc /> */
+        protected override void CheckResult(object res)
+        {
+            Assert.IsTrue(res != null);
+
+            SerializableResult res0 = res as SerializableResult;
+
+            Assert.IsTrue(res0 != null);
+            Assert.AreEqual(1, res0.Res);
+        }
+
+        /** <inheritDoc /> */
+        protected override void CheckError(Exception err)
+        {
+            Assert.IsTrue(err != null);
+
+            SerializableException err0 = err as SerializableException;
+
+            Assert.IsTrue(err0 != null);
+            Assert.AreEqual(ErrMsg, err0.Msg);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [Serializable]
+        private class SerializableOutFunc : IComputeFunc<object>
+        {
+            /** Error. */
+            private bool _err;
+
+            /// <summary>
+            ///
+            /// </summary>
+            public SerializableOutFunc()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="err"></param>
+            public SerializableOutFunc(bool err)
+            {
+                _err = err;
+            }
+
+            /** <inheritDoc /> */
+            public object Invoke()
+            {
+                if (_err)
+                    throw new SerializableException(ErrMsg);
+                return new SerializableResult(1);
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [Serializable]
+        private class SerializableFunc : IComputeFunc<object, object>
+        {
+            /** Error. */
+            private bool _err;
+
+            /// <summary>
+            ///
+            /// </summary>
+            public SerializableFunc()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="err"></param>
+            public SerializableFunc(bool err)
+            {
+                _err = err;
+            }
+
+            /** <inheritDoc /> */
+            public object Invoke(object arg)
+            {
+                Console.WriteLine("INVOKED!");
+
+                if (_err)
+                    throw new SerializableException(ErrMsg);
+                return new SerializableResult(1);
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [Serializable]
+        private class SerializableException : Exception
+        {
+            /** */
+            public string Msg;
+
+            /// <summary>
+            ///
+            /// </summary>
+            public SerializableException()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="msg"></param>
+            public SerializableException(string msg) : this()
+            {
+                Msg = msg;
+            }
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="info"></param>
+            /// <param name="context"></param>
+            public SerializableException(SerializationInfo info, StreamingContext context) : base(info, context)
+            {
+                Msg = info.GetString("msg");
+            }
+
+            /** <inheritDoc /> */
+            public override void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("msg", Msg);
+
+                base.GetObjectData(info, context);
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [Serializable]
+        private class SerializableResult
+        {
+            public int Res;
+
+            /// <summary>
+            ///
+            /// </summary>
+            public SerializableResult()
+            {
+                // No-op.
+            }
+
+            /// <summary>
+            ///
+            /// </summary>
+            /// <param name="res"></param>
+            public SerializableResult(int res)
+            {
+                Res = res;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/TaskAdapterTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/TaskAdapterTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/TaskAdapterTest.cs
new file mode 100644
index 0000000..f7fb422
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Compute/TaskAdapterTest.cs
@@ -0,0 +1,274 @@
+/*
+ * 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.Compute
+{
+    using System;
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Portable;
+    using Apache.Ignite.Core.Resource;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Test for task and job adapter.
+    /// </summary>
+    public class TaskAdapterTest : AbstractTaskTest
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public TaskAdapterTest() : base(false) { }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="fork">Fork flag.</param>
+        protected TaskAdapterTest(bool fork) : base(fork) { }
+
+        /// <summary>
+        /// Test for task adapter.
+        /// </summary>
+        [Test]
+        public void TestTaskAdapter()
+        {
+            Assert.AreEqual(3, Grid1.GetCluster().GetNodes().Count);
+
+            HashSet<Guid> allNodes = new HashSet<Guid>(); 
+
+            for (int i = 0; i < 20 && allNodes.Count < 3; i++)
+            {
+                HashSet<Guid> res = Grid1.GetCompute().Execute(new TestSplitTask(), 1);
+
+                Assert.AreEqual(1, res.Count);
+
+                allNodes.UnionWith(res);
+            }
+
+            Assert.AreEqual(3, allNodes.Count);
+
+            HashSet<Guid> res2 = Grid1.GetCompute().Execute<int, Guid, HashSet<Guid>>(typeof(TestSplitTask), 3);
+
+            Assert.IsTrue(res2.Count > 0);
+
+            Grid1.GetCompute().Execute(new TestSplitTask(), 100);
+
+            Assert.AreEqual(3, allNodes.Count);
+        }
+        
+        /// <summary>
+        /// Test for job adapter.
+        /// </summary>
+        [Test]
+        public void TestSerializableJobAdapter()
+        {
+            for (int i = 0; i < 10; i++)
+            {
+                bool res = Grid1.GetCompute().Execute(new TestJobAdapterTask(), true);
+
+                Assert.IsTrue(res);
+            }
+        }
+
+        /// <summary>
+        /// Test for job adapter.
+        /// </summary>
+        [Test]
+        public void TestPortableJobAdapter()
+        {
+            for (int i = 0; i < 10; i++)
+            {
+                bool res = Grid1.GetCompute().Execute(new TestJobAdapterTask(), false);
+
+                Assert.IsTrue(res);
+            }
+        }
+
+        /** <inheritDoc /> */
+        override protected void PortableTypeConfigurations(ICollection<PortableTypeConfiguration> portTypeCfgs)
+        {
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableJob)));
+        }
+
+        /// <summary>
+        /// Test task.
+        /// </summary>
+        public class TestSplitTask : ComputeTaskSplitAdapter<int, Guid, HashSet<Guid>>
+        {
+            /** <inheritDoc /> */
+            override protected ICollection<IComputeJob<Guid>> Split(int gridSize, int arg)
+            {
+                Assert.AreEqual(3, gridSize);
+
+                int jobsNum = arg;
+
+                Assert.IsTrue(jobsNum > 0);
+
+                var jobs = new List<IComputeJob<Guid>>(jobsNum);
+
+                for (int i = 0; i < jobsNum; i++)
+                    jobs.Add(new NodeIdJob());
+
+                return jobs;
+            }
+
+            /** <inheritDoc /> */
+            override public HashSet<Guid> Reduce(IList<IComputeJobResult<Guid>> results)
+            {
+                HashSet<Guid> nodes = new HashSet<Guid>();
+
+                foreach (var res in results) {
+                    Guid id = res.Data();
+
+                    Assert.NotNull(id);
+
+                    nodes.Add(id);
+                }
+
+                return nodes;
+            }
+        }
+
+        /// <summary>
+        /// Test task.
+        /// </summary>
+        public class TestJobAdapterTask : ComputeTaskSplitAdapter<bool, bool, bool>
+        {
+            /** <inheritDoc /> */
+            override protected ICollection<IComputeJob<bool>> Split(int gridSize, bool arg)
+            {
+                bool serializable = arg;
+
+                ICollection<IComputeJob<bool>> jobs = new List<IComputeJob<bool>>(1);
+
+                if (serializable)
+                    jobs.Add(new SerializableJob(100, "str"));
+                else
+                    jobs.Add(new PortableJob(100, "str"));
+
+                return jobs;
+            }
+
+            /** <inheritDoc /> */
+            override public bool Reduce(IList<IComputeJobResult<bool>> results)
+            {
+                Assert.AreEqual(1, results.Count);
+
+                Assert.IsTrue(results[0].Data());
+
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// Test job.
+        /// </summary>
+        [Serializable]
+        public class NodeIdJob : IComputeJob<Guid>
+        {
+            [InstanceResource]
+            private IIgnite _grid = null;
+
+            /** <inheritDoc /> */
+            public Guid Execute()
+            {
+                Assert.NotNull(_grid);
+
+                return _grid.GetCluster().GetLocalNode().Id;
+            }
+
+            /** <inheritDoc /> */
+            public void Cancel()
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        /// Test serializable job.
+        /// </summary>
+        [Serializable]
+        public class SerializableJob : ComputeJobAdapter<bool>
+        {
+            [InstanceResource]
+            private IIgnite _grid = null;
+
+            public SerializableJob(params object[] args) : base(args)
+            { 
+                // No-op.
+            }
+
+            /** <inheritDoc /> */
+            override public bool Execute()
+            {
+                Assert.IsFalse(IsCancelled());
+
+                Cancel();
+
+                Assert.IsTrue(IsCancelled());
+
+                Assert.NotNull(_grid);
+
+                int arg1 = Argument<int>(0);
+
+                Assert.AreEqual(100, arg1);
+
+                string arg2 = Argument<string>(1);
+
+                Assert.AreEqual("str", arg2);
+
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// Test portable job.
+        /// </summary>
+        public class PortableJob : ComputeJobAdapter<bool>
+        {
+            [InstanceResource]
+            private IIgnite _grid = null;
+
+            public PortableJob(params object[] args) : base(args)
+            {
+                // No-op.
+            }
+
+            /** <inheritDoc /> */
+            override public bool Execute()
+            {
+                Assert.IsFalse(IsCancelled());
+
+                Cancel();
+
+                Assert.IsTrue(IsCancelled());
+
+                Assert.NotNull(_grid);
+
+                int arg1 = Argument<int>(0);
+
+                Assert.AreEqual(100, arg1);
+
+                string arg2 = Argument<string>(1);
+
+                Assert.AreEqual("str", arg2);
+
+                return true;
+            }
+        }
+    }
+}


Mime
View raw message