http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.cs new file mode 100644 index 0000000..4b303ce --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedPortableClosureTaskTest.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 portable objects. + /// </summary> + [Ignore("IGNITE-1367")] + public class ForkedPortableClosureTaskTest : PortableClosureTaskTest + { + /// <summary> + /// Constructor. + /// </summary> + public ForkedPortableClosureTaskTest() : base(true) { } + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedResourceTaskTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedResourceTaskTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedResourceTaskTest.cs new file mode 100644 index 0000000..00fd28a --- /dev/null +++ b/modules/platform/src/test/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-1367")] + public class ForkedResourceTaskTest : ResourceTaskTest + { + /// <summary> + /// Constructor. + /// </summary> + public ForkedResourceTaskTest() : base(true) { } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedSerializableClosureTaskTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedSerializableClosureTaskTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedSerializableClosureTaskTest.cs new file mode 100644 index 0000000..edc18f2 --- /dev/null +++ b/modules/platform/src/test/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-1367")] + public class ForkedSerializableClosureTaskTest : SerializableClosureTaskTest + { + /// <summary> + /// Constructor. + /// </summary> + public ForkedSerializableClosureTaskTest() : base(true) { } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.cs new file mode 100644 index 0000000..e7bad17 --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/Forked/ForkedTaskAdapterTest.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 task adapter test. + /// </summary> + [Ignore("IGNITE-1367")] + public class ForkedTaskAdapterTest : TaskAdapterTest + { + /// <summary> + /// Constructor. + /// </summary> + public ForkedTaskAdapterTest() : base(true) { } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs new file mode 100644 index 0000000..9918dce --- /dev/null +++ b/modules/platform/src/test/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.Compute().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.Compute().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.Cluster.LocalNode.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/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/PortableClosureTaskTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/PortableClosureTaskTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/PortableClosureTaskTest.cs new file mode 100644 index 0000000..3ca933e --- /dev/null +++ b/modules/platform/src/test/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/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/PortableTaskTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/PortableTaskTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/PortableTaskTest.cs new file mode 100644 index 0000000..b3bd1b1 --- /dev/null +++ b/modules/platform/src/test/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.Compute().Execute(task, taskArg); + + Assert.NotNull(res); + + Assert.AreEqual(400, res.Field<int>("val")); + + PortableTaskResult resObj = res.Deserialize<PortableTaskResult>(); + + Assert.AreEqual(400, resObj.Val); + } + + private static IPortableObject ToPortable(IIgnite grid, object obj) + { + var cache = grid.Cache<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.Attribute<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.Field<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.Field<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.Field<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/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs new file mode 100644 index 0000000..4cc5982 --- /dev/null +++ b/modules/platform/src/test/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.Compute().Execute(new InjectionTask(), 0); + + Assert.AreEqual(Grid1.Cluster.Nodes().Count, res); + } + + /// <summary> + /// Test Ignite injection into the closure. + /// </summary> + [Test] + public void TestClosureInjection() + { + var res = Grid1.Compute().Broadcast(new InjectionClosure(), 1); + + Assert.AreEqual(Grid1.Cluster.Nodes().Count, res.Sum()); + } + + /// <summary> + /// Test Ignite injection into reducer. + /// </summary> + [Test] + public void TestReducerInjection() + { + int res = Grid1.Compute().Apply(new InjectionClosure(), new List<int> { 1, 1, 1 }, new InjectionReducer()); + + Assert.AreEqual(Grid1.Cluster.Nodes().Count, res); + } + + /// <summary> + /// Test no-result-cache attribute. + /// </summary> + [Test] + public void TestNoResultCache() + { + int res = Grid1.Compute().Execute(new NoResultCacheTask(), 0); + + Assert.AreEqual(Grid1.Cluster.Nodes().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/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/SerializableClosureTaskTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/SerializableClosureTaskTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/SerializableClosureTaskTest.cs new file mode 100644 index 0000000..ded56ed --- /dev/null +++ b/modules/platform/src/test/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/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/TaskAdapterTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/TaskAdapterTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Compute/TaskAdapterTest.cs new file mode 100644 index 0000000..cf8c663 --- /dev/null +++ b/modules/platform/src/test/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.Cluster.Nodes().Count); + + HashSet<Guid> allNodes = new HashSet<Guid>(); + + for (int i = 0; i < 20 && allNodes.Count < 3; i++) + { + HashSet<Guid> res = Grid1.Compute().Execute(new TestSplitTask(), 1); + + Assert.AreEqual(1, res.Count); + + allNodes.UnionWith(res); + } + + Assert.AreEqual(3, allNodes.Count); + + HashSet<Guid> res2 = Grid1.Compute().Execute<int, Guid, HashSet<Guid>>(typeof(TestSplitTask), 3); + + Assert.IsTrue(res2.Count > 0); + + Grid1.Compute().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.Compute().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.Compute().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.Cluster.LocalNode.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; + } + } + } +}
