Repository: reef Updated Branches: refs/heads/master 9ae741af3 -> 6835369c4
[REEF-1439] Validate Exception in spun off System.Threading.Thread => FailedEvaluator Event This addressed the issue by * Moving existing Test to the right folder for user Exception validation. JIRA: [REEF-1439](https://issues.apache.org/jira/browse/REEF-1439) This closes #1035 Project: http://git-wip-us.apache.org/repos/asf/reef/repo Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/6835369c Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/6835369c Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/6835369c Branch: refs/heads/master Commit: 6835369c4a0a61978fed6ef1d4ad9b5f989350f6 Parents: 9ae741a Author: Andrew Chung <[email protected]> Authored: Tue Jun 7 11:25:21 2016 -0700 Committer: Julia Wang <[email protected]> Committed: Thu Jun 9 15:11:46 2016 -0700 ---------------------------------------------------------------------- .../Bridge/TestUnhandledTaskException.cs | 238 ------------------- .../User/UnhandledThreadExceptionInTaskTest.cs | 238 +++++++++++++++++++ .../Org.Apache.REEF.Tests.csproj | 2 +- 3 files changed, 239 insertions(+), 239 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/reef/blob/6835369c/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs deleted file mode 100644 index 0f85d71..0000000 --- a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/TestUnhandledTaskException.cs +++ /dev/null @@ -1,238 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -using System; -using System.Threading; -using Org.Apache.REEF.Common.Exceptions; -using Org.Apache.REEF.Common.Tasks; -using Org.Apache.REEF.Driver; -using Org.Apache.REEF.Driver.Evaluator; -using Org.Apache.REEF.Driver.Task; -using Org.Apache.REEF.Tang.Annotations; -using Org.Apache.REEF.Tang.Implementations.Configuration; -using Org.Apache.REEF.Tang.Implementations.Tang; -using Org.Apache.REEF.Tang.Interface; -using Org.Apache.REEF.Tang.Util; -using Org.Apache.REEF.Tests.Functional.Bridge.Exceptions; -using Org.Apache.REEF.Tests.Functional.Bridge.Parameters; -using Org.Apache.REEF.Utilities.Logging; -using Xunit; - -namespace Org.Apache.REEF.Tests.Functional.Bridge -{ - [Collection("FunctionalTests")] - public sealed class TestUnhandledTaskException : ReefFunctionalTest - { - private const string ExpectedEvaluatorFailureMessage = "Unhandled Exception."; - private const string ExpectedTaskId = "TaskID"; - private const string SerializableSuccessMessage = "Evaluator successfully received serializable unhandled Exception."; - private const string NonSerializableSuccessMessage = "Evaluator successfully received nonserializable unhandled Exception."; - - /// <summary> - /// This test validates that an unhandled Task Exception crashes the Evaluator and the Evaluator - /// does an attempt to send a final message to the Driver. - /// </summary> - [Fact] - public void TestUnhandledTaskExceptionCrashesEvaluator() - { - var testFolder = DefaultRuntimeFolder + TestId; - TestRun(GetDriverConfiguration(), typeof(TestUnhandledTaskException), 1, "testUnhandledTaskException", "local", testFolder); - ValidateSuccessForLocalRuntime(0, numberOfEvaluatorsToFail: 2, testFolder: testFolder); - ValidateMessageSuccessfullyLoggedForDriver(SerializableSuccessMessage, testFolder, 1); - ValidateMessageSuccessfullyLoggedForDriver(NonSerializableSuccessMessage, testFolder, 1); - CleanUp(testFolder); - } - - private static IConfiguration GetDriverConfiguration() - { - return DriverConfiguration.ConfigurationModule - .Set(DriverConfiguration.OnDriverStarted, GenericType<UnhandledExceptionTestDriver>.Class) - .Set(DriverConfiguration.OnEvaluatorCompleted, GenericType<UnhandledExceptionTestDriver>.Class) - .Set(DriverConfiguration.OnEvaluatorFailed, GenericType<UnhandledExceptionTestDriver>.Class) - .Set(DriverConfiguration.OnEvaluatorAllocated, GenericType<UnhandledExceptionTestDriver>.Class) - .Set(DriverConfiguration.OnTaskCompleted, GenericType<UnhandledExceptionTestDriver>.Class) - .Build(); - } - - /// <summary> - /// This Task throws an unhandled Exception in the thread that it spins off to - /// trigger an Evaluator failure. - /// </summary> - private sealed class UnhandledExceptionTestTask : ITask - { - private readonly bool _shouldThrowSerializableException; - - [Inject] - private UnhandledExceptionTestTask( - [Parameter(typeof(ShouldThrowSerializableException))] bool shouldThrowSerializableException) - { - _shouldThrowSerializableException = shouldThrowSerializableException; - } - - public byte[] Call(byte[] memento) - { - var thread = new Thread(() => - { - if (_shouldThrowSerializableException) - { - throw new TestSerializableException(ExpectedEvaluatorFailureMessage); - } - else - { - throw new TestNonSerializableException(ExpectedEvaluatorFailureMessage); - } - }); - - thread.Start(); - thread.Join(); - return null; - } - - public void Dispose() - { - } - } - - /// <summary> - /// This Driver verifies that the unhandled Exception triggers an Evaluator failure - /// and verifies the type of Exception and its message. - /// </summary> - private sealed class UnhandledExceptionTestDriver : - IObserver<IDriverStarted>, - IObserver<IAllocatedEvaluator>, - IObserver<IFailedEvaluator>, - IObserver<ICompletedEvaluator>, - IObserver<ICompletedTask> - { - private static readonly Logger Logger = Logger.GetLogger(typeof(UnhandledExceptionTestDriver)); - - private readonly IEvaluatorRequestor _evaluatorRequestor; - private bool _shouldReceiveSerializableException = true; - - [Inject] - private UnhandledExceptionTestDriver(IEvaluatorRequestor evaluatorRequestor) - { - _evaluatorRequestor = evaluatorRequestor; - } - - public void OnNext(IDriverStarted value) - { - _evaluatorRequestor.Submit( - _evaluatorRequestor.NewBuilder() - .SetCores(1) - .SetNumber(1) - .Build()); - } - - public void OnNext(IAllocatedEvaluator value) - { - var taskConf = TaskConfiguration.ConfigurationModule - .Set(TaskConfiguration.Identifier, ExpectedTaskId) - .Set(TaskConfiguration.Task, GenericType<UnhandledExceptionTestTask>.Class) - .Build(); - - var shouldThrowSerializableConfig = TangFactory.GetTang().NewConfigurationBuilder() - .BindNamedParameter<ShouldThrowSerializableException, bool>( - GenericType<ShouldThrowSerializableException>.Class, _shouldReceiveSerializableException.ToString()) - .Build(); - - value.SubmitTask(Configurations.Merge(taskConf, shouldThrowSerializableConfig)); - } - - public void OnNext(ICompletedTask value) - { - throw new Exception("Driver should not have received a completed Task."); - } - - public void OnNext(ICompletedEvaluator value) - { - throw new Exception("Driver should not have received a completed Evaluator."); - } - - public void OnNext(IFailedEvaluator value) - { - if (value.EvaluatorException == null) - { - throw new Exception("Evaluator should contain a valid Exception."); - } - - if (!value.EvaluatorException.Message.Contains(ExpectedEvaluatorFailureMessage)) - { - throw new Exception("Evaluator expected to contain the message " + ExpectedEvaluatorFailureMessage); - } - - if (!value.FailedTask.IsPresent()) - { - throw new Exception("Failed task should be present."); - } - - if (value.FailedTask.Value.Id != ExpectedTaskId) - { - throw new Exception("Failed Task does not have the right Task ID."); - } - - if (_shouldReceiveSerializableException) - { - var serializableEx = value.EvaluatorException.InnerException as TestSerializableException; - if (serializableEx == null) - { - throw new Exception("Evaluator InnerException expected to be of type " + typeof(TestSerializableException).Name); - } - - if (!serializableEx.Message.Equals(ExpectedEvaluatorFailureMessage)) - { - throw new Exception("Evaluator InnerException.Message expected to be " + ExpectedEvaluatorFailureMessage); - } - - _shouldReceiveSerializableException = false; - Logger.Log(Level.Info, SerializableSuccessMessage); - - _evaluatorRequestor.Submit( - _evaluatorRequestor.NewBuilder() - .SetCores(1) - .SetNumber(1) - .Build()); - } - else - { - var nonSerializableEx = value.EvaluatorException.InnerException as NonSerializableEvaluatorException; - if (nonSerializableEx == null) - { - throw new Exception("Evaluator Exception expected to be of type " + typeof(NonSerializableEvaluatorException)); - } - - if (!nonSerializableEx.Message.Contains(ExpectedEvaluatorFailureMessage)) - { - throw new Exception("Evaluator InnerException.Message expected to contain the message " + ExpectedEvaluatorFailureMessage); - } - - Logger.Log(Level.Info, NonSerializableSuccessMessage); - } - } - - public void OnError(Exception error) - { - throw new NotImplementedException(); - } - - public void OnCompleted() - { - throw new NotImplementedException(); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/6835369c/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/UnhandledThreadExceptionInTaskTest.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/UnhandledThreadExceptionInTaskTest.cs b/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/UnhandledThreadExceptionInTaskTest.cs new file mode 100644 index 0000000..6508859 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/UnhandledThreadExceptionInTaskTest.cs @@ -0,0 +1,238 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using System; +using System.Threading; +using Org.Apache.REEF.Common.Exceptions; +using Org.Apache.REEF.Common.Tasks; +using Org.Apache.REEF.Driver; +using Org.Apache.REEF.Driver.Evaluator; +using Org.Apache.REEF.Driver.Task; +using Org.Apache.REEF.Tang.Annotations; +using Org.Apache.REEF.Tang.Implementations.Configuration; +using Org.Apache.REEF.Tang.Implementations.Tang; +using Org.Apache.REEF.Tang.Interface; +using Org.Apache.REEF.Tang.Util; +using Org.Apache.REEF.Tests.Functional.Bridge.Exceptions; +using Org.Apache.REEF.Tests.Functional.Bridge.Parameters; +using Org.Apache.REEF.Utilities.Logging; +using Xunit; + +namespace Org.Apache.REEF.Tests.Functional.Failure.User +{ + [Collection("FunctionalTests")] + public sealed class UnhandledThreadExceptionInTaskTest : ReefFunctionalTest + { + private const string ExpectedEvaluatorFailureMessage = "Unhandled Exception."; + private const string ExpectedTaskId = "TaskID"; + private const string SerializableSuccessMessage = "Evaluator successfully received serializable unhandled Exception."; + private const string NonSerializableSuccessMessage = "Evaluator successfully received nonserializable unhandled Exception."; + + /// <summary> + /// This test validates that an unhandled Thread Exception in a user's Task crashes the Evaluator and + /// the Evaluator does an attempt to send a final message to the Driver. + /// </summary> + [Fact] + public void TestUnhandledTaskExceptionCrashesEvaluator() + { + var testFolder = DefaultRuntimeFolder + TestId; + TestRun(GetDriverConfiguration(), typeof(UnhandledThreadExceptionInTaskTest), 1, "testUnhandledTaskException", "local", testFolder); + ValidateSuccessForLocalRuntime(0, numberOfEvaluatorsToFail: 2, testFolder: testFolder); + ValidateMessageSuccessfullyLoggedForDriver(SerializableSuccessMessage, testFolder, 1); + ValidateMessageSuccessfullyLoggedForDriver(NonSerializableSuccessMessage, testFolder, 1); + CleanUp(testFolder); + } + + private static IConfiguration GetDriverConfiguration() + { + return DriverConfiguration.ConfigurationModule + .Set(DriverConfiguration.OnDriverStarted, GenericType<UnhandledThreadExceptionInTaskTestDriver>.Class) + .Set(DriverConfiguration.OnEvaluatorCompleted, GenericType<UnhandledThreadExceptionInTaskTestDriver>.Class) + .Set(DriverConfiguration.OnEvaluatorFailed, GenericType<UnhandledThreadExceptionInTaskTestDriver>.Class) + .Set(DriverConfiguration.OnEvaluatorAllocated, GenericType<UnhandledThreadExceptionInTaskTestDriver>.Class) + .Set(DriverConfiguration.OnTaskCompleted, GenericType<UnhandledThreadExceptionInTaskTestDriver>.Class) + .Build(); + } + + /// <summary> + /// This Task throws an unhandled Exception in the thread that it spins off to + /// trigger an Evaluator failure. + /// </summary> + private sealed class UnhandledThreadExceptionInTaskTestTask : ITask + { + private readonly bool _shouldThrowSerializableException; + + [Inject] + private UnhandledThreadExceptionInTaskTestTask( + [Parameter(typeof(ShouldThrowSerializableException))] bool shouldThrowSerializableException) + { + _shouldThrowSerializableException = shouldThrowSerializableException; + } + + public byte[] Call(byte[] memento) + { + var thread = new Thread(() => + { + if (_shouldThrowSerializableException) + { + throw new TestSerializableException(ExpectedEvaluatorFailureMessage); + } + else + { + throw new TestNonSerializableException(ExpectedEvaluatorFailureMessage); + } + }); + + thread.Start(); + thread.Join(); + return null; + } + + public void Dispose() + { + } + } + + /// <summary> + /// This Driver verifies that the unhandled Exception triggers an Evaluator failure + /// and verifies the type of Exception and its message. + /// </summary> + private sealed class UnhandledThreadExceptionInTaskTestDriver : + IObserver<IDriverStarted>, + IObserver<IAllocatedEvaluator>, + IObserver<IFailedEvaluator>, + IObserver<ICompletedEvaluator>, + IObserver<ICompletedTask> + { + private static readonly Logger Logger = Logger.GetLogger(typeof(UnhandledThreadExceptionInTaskTestDriver)); + + private readonly IEvaluatorRequestor _evaluatorRequestor; + private bool _shouldReceiveSerializableException = true; + + [Inject] + private UnhandledThreadExceptionInTaskTestDriver(IEvaluatorRequestor evaluatorRequestor) + { + _evaluatorRequestor = evaluatorRequestor; + } + + public void OnNext(IDriverStarted value) + { + _evaluatorRequestor.Submit( + _evaluatorRequestor.NewBuilder() + .SetCores(1) + .SetNumber(1) + .Build()); + } + + public void OnNext(IAllocatedEvaluator value) + { + var taskConf = TaskConfiguration.ConfigurationModule + .Set(TaskConfiguration.Identifier, ExpectedTaskId) + .Set(TaskConfiguration.Task, GenericType<UnhandledThreadExceptionInTaskTestTask>.Class) + .Build(); + + var shouldThrowSerializableConfig = TangFactory.GetTang().NewConfigurationBuilder() + .BindNamedParameter<ShouldThrowSerializableException, bool>( + GenericType<ShouldThrowSerializableException>.Class, _shouldReceiveSerializableException.ToString()) + .Build(); + + value.SubmitTask(Configurations.Merge(taskConf, shouldThrowSerializableConfig)); + } + + public void OnNext(ICompletedTask value) + { + throw new Exception("Driver should not have received a completed Task."); + } + + public void OnNext(ICompletedEvaluator value) + { + throw new Exception("Driver should not have received a completed Evaluator."); + } + + public void OnNext(IFailedEvaluator value) + { + if (value.EvaluatorException == null) + { + throw new Exception("Evaluator should contain a valid Exception."); + } + + if (!value.EvaluatorException.Message.Contains(ExpectedEvaluatorFailureMessage)) + { + throw new Exception("Evaluator expected to contain the message " + ExpectedEvaluatorFailureMessage); + } + + if (!value.FailedTask.IsPresent()) + { + throw new Exception("Failed task should be present."); + } + + if (value.FailedTask.Value.Id != ExpectedTaskId) + { + throw new Exception("Failed Task does not have the right Task ID."); + } + + if (_shouldReceiveSerializableException) + { + var serializableEx = value.EvaluatorException.InnerException as TestSerializableException; + if (serializableEx == null) + { + throw new Exception("Evaluator InnerException expected to be of type " + typeof(TestSerializableException).Name); + } + + if (!serializableEx.Message.Equals(ExpectedEvaluatorFailureMessage)) + { + throw new Exception("Evaluator InnerException.Message expected to be " + ExpectedEvaluatorFailureMessage); + } + + _shouldReceiveSerializableException = false; + Logger.Log(Level.Info, SerializableSuccessMessage); + + _evaluatorRequestor.Submit( + _evaluatorRequestor.NewBuilder() + .SetCores(1) + .SetNumber(1) + .Build()); + } + else + { + var nonSerializableEx = value.EvaluatorException.InnerException as NonSerializableEvaluatorException; + if (nonSerializableEx == null) + { + throw new Exception("Evaluator Exception expected to be of type " + typeof(NonSerializableEvaluatorException)); + } + + if (!nonSerializableEx.Message.Contains(ExpectedEvaluatorFailureMessage)) + { + throw new Exception("Evaluator InnerException.Message expected to contain the message " + ExpectedEvaluatorFailureMessage); + } + + Logger.Log(Level.Info, NonSerializableSuccessMessage); + } + } + + public void OnError(Exception error) + { + throw new NotImplementedException(); + } + + public void OnCompleted() + { + throw new NotImplementedException(); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/6835369c/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj b/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj index 0746e12..997d05d 100644 --- a/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj +++ b/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj @@ -85,10 +85,10 @@ under the License. <Compile Include="Functional\Bridge\TestSimpleContext.cs" /> <Compile Include="Functional\Bridge\TestSimpleEventHandlers.cs" /> <Compile Include="Functional\Bridge\TestSuspendTask.cs" /> - <Compile Include="Functional\Bridge\TestUnhandledTaskException.cs" /> <Compile Include="Functional\Common\Task\Handlers\LoggingHandler.cs" /> <Compile Include="Functional\Common\Task\LoggingTask.cs" /> <Compile Include="Functional\Common\Task\Handlers\ExceptionThrowingHandler.cs" /> + <Compile Include="Functional\Failure\User\UnhandledThreadExceptionInTaskTest.cs" /> <Compile Include="Functional\Driver\DriverTestStartHandler.cs" /> <Compile Include="Functional\Failure\BasePoisonedEvaluatorWithActiveContextDriver.cs" /> <Compile Include="Functional\Failure\BasePoisonedEvaluatorWithRunningTaskDriver.cs" />
