Repository: reef Updated Branches: refs/heads/master 234eeba7d -> 08f096a27
[REEF-1615] Add unit tests and improve logging for `REEFEnvironment` functionality This is work towards [REEF-1561](https://issues.apache.org/jira/browse/REEF-1561) *REEF as a library* project. Some unit tests in `REEFEnvironmentFailDriverTest` are currently commented out due to the [REEF-1637](https://issues.apache.org/jira/browse/REEF-1637) issue (Driver does not receive Evaluator heartbeats). Summary of changes: * Create unit tests for failures on different stages of REEF Driver life cycle; * Create a version of `HelloREEF` example for `REEFEnvironment`; * Improve in `TestUtils` to handle in-process jobs; * Get rid of checkstyle warnings in `FailDriver`; * Comment out singleton assertion in `Evaluators`: it is no longer true in `REEFEnvironment` setting; * Add a TODO note for Evaluator singleton assertion; * Add `.toString()` methods to some events for better logging and debuggability; * Minor fixes to improve logging and code readability. JIRA: [REEF-1615](https://issues.apache.org/jira/browse/REEF-1615) Pull Request: This closes #1152 Project: http://git-wip-us.apache.org/repos/asf/reef/repo Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/08f096a2 Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/08f096a2 Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/08f096a2 Branch: refs/heads/master Commit: 08f096a2778a731c4de40c13edb1e7141f39a02b Parents: 234eeba Author: Sergiy Matusevych <mo...@apache.org> Authored: Tue Oct 11 13:52:05 2016 -0700 Committer: Markus Weimer <wei...@apache.org> Committed: Fri Oct 14 16:53:15 2016 -0700 ---------------------------------------------------------------------- .../common/driver/evaluator/Evaluators.java | 6 +- .../ResourceStatusEventImpl.java | 8 ++ .../resourcemanager/RuntimeStatusEventImpl.java | 19 +++ .../examples/hello/HelloREEFEnvironment.java | 77 ++++++++++ .../reef/tests/fail/driver/FailDriver.java | 47 +++--- .../java/org/apache/reef/tests/TestUtils.java | 34 ++++- .../tests/driver/REEFEnvironmentDriverTest.java | 3 +- .../fail/REEFEnvironmentFailDriverTest.java | 144 +++++++++++++++++++ 8 files changed, 306 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java index fac1ab4..8962895 100644 --- a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java +++ b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java @@ -22,7 +22,6 @@ import org.apache.reef.annotations.audience.DriverSide; import org.apache.reef.annotations.audience.Private; import org.apache.reef.runtime.common.driver.resourcemanager.ResourceAllocationEvent; import org.apache.reef.util.Optional; -import org.apache.reef.util.SingletonAsserter; import org.apache.reef.tang.util.MonotonicSet; import javax.inject.Inject; @@ -53,7 +52,10 @@ public final class Evaluators implements AutoCloseable { @Inject Evaluators() { LOG.log(Level.FINE, "Instantiated 'Evaluators'"); - assert SingletonAsserter.assertSingleton(Evaluators.class); + // TODO[REEF-1642] Assert singleton per REEFEnvironment + // There can be several instances of the class for multiple REEFEnvironments. + // It is still a singleton when REEF Driver owns the entire JVM. + // assert SingletonAsserter.assertSingleton(Evaluators.class); } /** http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/ResourceStatusEventImpl.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/ResourceStatusEventImpl.java b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/ResourceStatusEventImpl.java index 4a9da3d..3b4654c 100644 --- a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/ResourceStatusEventImpl.java +++ b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/ResourceStatusEventImpl.java @@ -27,6 +27,7 @@ import org.apache.reef.util.Optional; * Use newBuilder to construct an instance. */ public final class ResourceStatusEventImpl implements ResourceStatusEvent { + private final String identifier; private final State state; private final Optional<String> diagnostics; @@ -42,6 +43,13 @@ public final class ResourceStatusEventImpl implements ResourceStatusEvent { } @Override + public String toString() { + return String.format( + "ResourceStatusEventImpl:{id:%s, runtime:%s, state:%s, diag:%s, exit:%s}", + identifier, runtimeName, state, diagnostics, exitCode); + } + + @Override public String getIdentifier() { return identifier; } http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/RuntimeStatusEventImpl.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/RuntimeStatusEventImpl.java b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/RuntimeStatusEventImpl.java index 48c9ed3..a3ce557 100644 --- a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/RuntimeStatusEventImpl.java +++ b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/resourcemanager/RuntimeStatusEventImpl.java @@ -31,6 +31,7 @@ import java.util.List; * Use newBuilder to construct an instance. */ public final class RuntimeStatusEventImpl implements RuntimeStatusEvent { + private final String name; private final State state; private final List<String> containerAllocationList; @@ -46,6 +47,24 @@ public final class RuntimeStatusEventImpl implements RuntimeStatusEvent { } @Override + public String toString() { + + // Replace with String.join() after migration to Java 1.8 + final StringBuilder allocatedContainers = new StringBuilder(); + for (String container : this.containerAllocationList) { + if (allocatedContainers.length() > 0) { + allocatedContainers.append(','); + } + allocatedContainers.append(container); + } + + return String.format( + "RuntimeStatusEventImpl:{name:%s, state:%s, allocated:[%s], outstanding:%d, error:%s}", + this.name, this.state, allocatedContainers, this.outstandingContainerRequests.orElse(0), + this.error.isPresent()); + } + + @Override public String getName() { return name; } http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-examples/src/main/java/org/apache/reef/examples/hello/HelloREEFEnvironment.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/hello/HelloREEFEnvironment.java b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/hello/HelloREEFEnvironment.java new file mode 100644 index 0000000..5d023fd --- /dev/null +++ b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/hello/HelloREEFEnvironment.java @@ -0,0 +1,77 @@ +/* + * 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. + */ +package org.apache.reef.examples.hello; + +import org.apache.reef.client.DriverConfiguration; +import org.apache.reef.proto.ReefServiceProtos; +import org.apache.reef.runtime.common.REEFEnvironment; +import org.apache.reef.runtime.common.driver.parameters.ClientRemoteIdentifier; +import org.apache.reef.runtime.local.driver.LocalDriverConfiguration; +import org.apache.reef.runtime.local.driver.RuntimeIdentifier; +import org.apache.reef.tang.Configuration; +import org.apache.reef.tang.exceptions.InjectionException; +import org.apache.reef.util.EnvironmentUtils; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * The Client for Hello REEF example running driver and client in the same process. + */ +public final class HelloREEFEnvironment { + + private static final Logger LOG = Logger.getLogger(HelloREEFEnvironment.class.getName()); + + private static final Configuration DRIVER_CONFIG = DriverConfiguration.CONF + .set(DriverConfiguration.GLOBAL_LIBRARIES, EnvironmentUtils.getClassLocation(HelloDriver.class)) + .set(DriverConfiguration.DRIVER_IDENTIFIER, "HelloREEF") + .set(DriverConfiguration.ON_DRIVER_STARTED, HelloDriver.StartHandler.class) + .set(DriverConfiguration.ON_EVALUATOR_ALLOCATED, HelloDriver.EvaluatorAllocatedHandler.class) + .build(); + + private static final Configuration LOCAL_DRIVER_MODULE = LocalDriverConfiguration.CONF + .set(LocalDriverConfiguration.MAX_NUMBER_OF_EVALUATORS, 2) + .set(LocalDriverConfiguration.ROOT_FOLDER, ".") + .set(LocalDriverConfiguration.JVM_HEAP_SLACK, 0.0) + .set(LocalDriverConfiguration.CLIENT_REMOTE_IDENTIFIER, ClientRemoteIdentifier.NONE) + .set(LocalDriverConfiguration.JOB_IDENTIFIER, "LOCAL_ENV_DRIVER_TEST") + .set(LocalDriverConfiguration.RUNTIME_NAMES, RuntimeIdentifier.RUNTIME_NAME) + .build(); + + /** + * Start Hello REEF job with Driver and Client sharing the same process. + * + * @param args command line parameters - not used. + * @throws InjectionException configuration error. + */ + public static void main(final String[] args) throws InjectionException { + + try (final REEFEnvironment reef = REEFEnvironment.fromConfiguration(LOCAL_DRIVER_MODULE, DRIVER_CONFIG)) { + reef.run(); + final ReefServiceProtos.JobStatusProto status = reef.getLastStatus(); + LOG.log(Level.INFO, "REEF job completed: {0}", status); + } + } + + /** + * Empty private constructor to prohibit instantiation of all-static class. + */ + private HelloREEFEnvironment() { + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-tests/src/main/java/org/apache/reef/tests/fail/driver/FailDriver.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-tests/src/main/java/org/apache/reef/tests/fail/driver/FailDriver.java b/lang/java/reef-tests/src/main/java/org/apache/reef/tests/fail/driver/FailDriver.java index fe1b507..8b4c8de 100644 --- a/lang/java/reef-tests/src/main/java/org/apache/reef/tests/fail/driver/FailDriver.java +++ b/lang/java/reef-tests/src/main/java/org/apache/reef/tests/fail/driver/FailDriver.java @@ -106,8 +106,7 @@ public final class FailDriver { private void checkMsgOrder(final Object msg) throws SimulatedDriverFailure, DriverSideFailure { final String msgClassName = msg.getClass().getName(); - LOG.log(Level.FINE, "At {0} {1}:{2}", new Object[]{ - this.state, this.expectIdx, msgClassName}); + LOG.log(Level.FINE, "At {0} {1}:{2}", new Object[] {this.state, this.expectIdx, msgClassName}); if (this.state == DriverState.FAILED) { // If already failed, do not do anything @@ -132,11 +131,11 @@ public final class FailDriver { if (notFound) { LOG.log(Level.SEVERE, "Event out of sequence: {0} {1}:{2}", - new Object[]{this.state, this.expectIdx, msgClassName}); + new Object[] {this.state, this.expectIdx, msgClassName}); throw new DriverSideFailure("Event out of sequence: " + msgClassName); } - LOG.log(Level.INFO, "{0}: send: {1} got: {2}", new Object[]{ + LOG.log(Level.INFO, "{0}: send: {1} got: {2}", new Object[] { this.state, EVENT_SEQUENCE[this.expectIdx], msgClassName}); ++this.expectIdx; @@ -161,13 +160,13 @@ public final class FailDriver { /** * Expected message class. */ - public static final class ExpectedMessage { + static final class ExpectedMessage { private final transient Class<?> msgClass; private final transient RequiredFlag requiredFlag; private final transient String repr; - public ExpectedMessage(final Class<?> clazz, final RequiredFlag requiredFlag) { + private ExpectedMessage(final Class<?> clazz, final RequiredFlag requiredFlag) { this.msgClass = clazz; this.requiredFlag = requiredFlag; this.repr = this.msgClass.getSimpleName() + ":" + this.requiredFlag; @@ -181,7 +180,7 @@ public final class FailDriver { /** * "Required" flag for message class. */ - public enum RequiredFlag {OPTIONAL, REQUIRED} + enum RequiredFlag {OPTIONAL, REQUIRED} } final class AllocatedEvaluatorHandler implements EventHandler<AllocatedEvaluator> { @@ -267,10 +266,9 @@ public final class FailDriver { final class RunningTaskHandler implements EventHandler<RunningTask> { @Override - @SuppressWarnings("checkstyle:hiddenfield") - public void onNext(final RunningTask task) { - checkMsgOrder(task); - FailDriver.this.task = task; + public void onNext(final RunningTask runningTask) { + checkMsgOrder(runningTask); + FailDriver.this.task = runningTask; switch (state) { case INIT: state = DriverState.SEND_MSG; @@ -289,13 +287,12 @@ public final class FailDriver { final class SuspendedTaskHandler implements EventHandler<SuspendedTask> { @Override - @SuppressWarnings("checkstyle:hiddenfield") - public void onNext(final SuspendedTask task) { - checkMsgOrder(task); + public void onNext(final SuspendedTask suspendedTask) { + checkMsgOrder(suspendedTask); state = DriverState.RESUME; try { - task.getActiveContext().submitTask(TaskConfiguration.CONF - .set(TaskConfiguration.IDENTIFIER, task.getId() + "_RESUMED") + suspendedTask.getActiveContext().submitTask(TaskConfiguration.CONF + .set(TaskConfiguration.IDENTIFIER, suspendedTask.getId() + "_RESUMED") .set(TaskConfiguration.TASK, NoopTask.class) .set(TaskConfiguration.ON_MESSAGE, NoopTask.DriverMessageHandler.class) .set(TaskConfiguration.ON_SUSPEND, NoopTask.TaskSuspendHandler.class) @@ -324,22 +321,20 @@ public final class FailDriver { final class FailedTaskHandler implements EventHandler<FailedTask> { @Override - @SuppressWarnings("checkstyle:hiddenfield") - public void onNext(final FailedTask task) { - LOG.log(Level.WARNING, "Task failed: " + task.getId(), task.getReason().orElse(null)); - checkMsgOrder(task); - if (task.getActiveContext().isPresent()) { - task.getActiveContext().get().close(); + public void onNext(final FailedTask failedTask) { + LOG.log(Level.WARNING, "Task failed: " + failedTask.getId(), failedTask.getReason().orElse(null)); + checkMsgOrder(failedTask); + if (failedTask.getActiveContext().isPresent()) { + failedTask.getActiveContext().get().close(); } } } final class CompletedTaskHandler implements EventHandler<CompletedTask> { @Override - @SuppressWarnings("checkstyle:hiddenfield") - public void onNext(final CompletedTask task) { - checkMsgOrder(task); - task.getActiveContext().close(); + public void onNext(final CompletedTask completedTask) { + checkMsgOrder(completedTask); + completedTask.getActiveContext().close(); } } http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-tests/src/test/java/org/apache/reef/tests/TestUtils.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-tests/src/test/java/org/apache/reef/tests/TestUtils.java b/lang/java/reef-tests/src/test/java/org/apache/reef/tests/TestUtils.java index c578238..3088bbd 100644 --- a/lang/java/reef-tests/src/test/java/org/apache/reef/tests/TestUtils.java +++ b/lang/java/reef-tests/src/test/java/org/apache/reef/tests/TestUtils.java @@ -19,6 +19,8 @@ package org.apache.reef.tests; import org.apache.reef.client.LauncherStatus; +import org.apache.reef.proto.ReefServiceProtos; +import org.apache.reef.runtime.common.utils.ExceptionCodec; import org.junit.Assert; import java.util.logging.Level; @@ -48,16 +50,42 @@ public final class TestUtils { } /** + * Make sure the job status is FAILED and it has the specified exception in the stack. + * + * @param status Job status. State must be FAILED for test to pass. + * @param clazz Exception that should be in the stack of exceptions of the launcher status. + */ + public static void assertJobFailure( + final ReefServiceProtos.JobStatusProto status, + final ExceptionCodec exceptionCodec, + final Class<? extends Throwable> clazz) { + + Assert.assertNotNull("Final job status must not be null", status); + + Assert.assertTrue("Job state missing", status.hasState()); + Assert.assertEquals("Unexpected final job state", ReefServiceProtos.State.FAILED, status.getState()); + + Assert.assertTrue("Job status must contain an exception", status.hasException()); + + final Throwable ex = exceptionCodec.fromBytes(status.getException().toByteArray()).orElse(null); + Assert.assertNotNull("Unable to decode exception", ex); + + if (!hasCause(ex, clazz)) { + LOG.log(Level.WARNING, "Unexpected Error: " + status, ex); + Assert.fail("Unexpected error: " + ex); + } + } + + /** * Return True if cause chain of exception ex contains * exception of class clazz (or one inherited from it). * - * @param ex exception to analyze (can be null) + * @param ex exception to analyze (can be null). * @param clazz class inherited from type Throwable. * @return True if ex or any other exception in its cause chain is instance of class clazz. */ public static boolean hasCause(final Throwable ex, final Class<? extends Throwable> clazz) { - Throwable exception = ex; - for (; exception != null; exception = exception.getCause()) { + for (Throwable exception = ex; exception != null; exception = exception.getCause()) { if (clazz.isInstance(exception)) { return true; } http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-tests/src/test/java/org/apache/reef/tests/driver/REEFEnvironmentDriverTest.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-tests/src/test/java/org/apache/reef/tests/driver/REEFEnvironmentDriverTest.java b/lang/java/reef-tests/src/test/java/org/apache/reef/tests/driver/REEFEnvironmentDriverTest.java index 9082a36..fa788f2 100644 --- a/lang/java/reef-tests/src/test/java/org/apache/reef/tests/driver/REEFEnvironmentDriverTest.java +++ b/lang/java/reef-tests/src/test/java/org/apache/reef/tests/driver/REEFEnvironmentDriverTest.java @@ -23,6 +23,7 @@ import org.apache.reef.proto.ReefServiceProtos; import org.apache.reef.runtime.common.REEFEnvironment; import org.apache.reef.runtime.common.driver.parameters.ClientRemoteIdentifier; import org.apache.reef.runtime.local.driver.LocalDriverConfiguration; +import org.apache.reef.runtime.local.driver.RuntimeIdentifier; import org.apache.reef.tang.Configuration; import org.apache.reef.tang.exceptions.BindException; import org.apache.reef.tang.exceptions.InjectionException; @@ -47,7 +48,7 @@ public final class REEFEnvironmentDriverTest { .set(LocalDriverConfiguration.JVM_HEAP_SLACK, 0.0) .set(LocalDriverConfiguration.CLIENT_REMOTE_IDENTIFIER, ClientRemoteIdentifier.NONE) .set(LocalDriverConfiguration.JOB_IDENTIFIER, "LOCAL_ENV_DRIVER_TEST") - .set(LocalDriverConfiguration.RUNTIME_NAMES, org.apache.reef.runtime.local.driver.RuntimeIdentifier.RUNTIME_NAME) + .set(LocalDriverConfiguration.RUNTIME_NAMES, RuntimeIdentifier.RUNTIME_NAME) .build(); @Test http://git-wip-us.apache.org/repos/asf/reef/blob/08f096a2/lang/java/reef-tests/src/test/java/org/apache/reef/tests/fail/REEFEnvironmentFailDriverTest.java ---------------------------------------------------------------------- diff --git a/lang/java/reef-tests/src/test/java/org/apache/reef/tests/fail/REEFEnvironmentFailDriverTest.java b/lang/java/reef-tests/src/test/java/org/apache/reef/tests/fail/REEFEnvironmentFailDriverTest.java new file mode 100644 index 0000000..08ef4be --- /dev/null +++ b/lang/java/reef-tests/src/test/java/org/apache/reef/tests/fail/REEFEnvironmentFailDriverTest.java @@ -0,0 +1,144 @@ +/* + * 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. + */ +package org.apache.reef.tests.fail; + +import org.apache.reef.driver.context.ActiveContext; +import org.apache.reef.driver.evaluator.AllocatedEvaluator; +import org.apache.reef.driver.evaluator.CompletedEvaluator; +import org.apache.reef.driver.task.CompletedTask; +import org.apache.reef.driver.task.RunningTask; +import org.apache.reef.driver.task.SuspendedTask; +import org.apache.reef.driver.task.TaskMessage; +import org.apache.reef.proto.ReefServiceProtos; +import org.apache.reef.runtime.common.driver.parameters.ClientRemoteIdentifier; +import org.apache.reef.runtime.common.utils.ExceptionCodec; +import org.apache.reef.runtime.local.driver.LocalDriverConfiguration; +import org.apache.reef.runtime.local.driver.RuntimeIdentifier; +import org.apache.reef.tang.Configuration; +import org.apache.reef.tang.Injector; +import org.apache.reef.tang.Tang; +import org.apache.reef.tang.exceptions.BindException; +import org.apache.reef.tang.exceptions.InjectionException; +import org.apache.reef.tests.TestUtils; +import org.apache.reef.tests.fail.driver.FailClient; +import org.apache.reef.tests.fail.driver.FailDriver; +import org.apache.reef.tests.library.exceptions.SimulatedDriverFailure; +import org.apache.reef.wake.time.event.Alarm; +import org.apache.reef.wake.time.event.StartTime; +import org.apache.reef.wake.time.event.StopTime; +import org.junit.Assert; +import org.junit.Test; + +/** + * Run FailDriver with different types of failures using in-process driver with local runtime. + */ +public class REEFEnvironmentFailDriverTest { + + private static final Configuration LOCAL_DRIVER_MODULE = LocalDriverConfiguration.CONF + .set(LocalDriverConfiguration.MAX_NUMBER_OF_EVALUATORS, 1) + .set(LocalDriverConfiguration.ROOT_FOLDER, ".") + .set(LocalDriverConfiguration.JVM_HEAP_SLACK, 0.0) + .set(LocalDriverConfiguration.CLIENT_REMOTE_IDENTIFIER, ClientRemoteIdentifier.NONE) + .set(LocalDriverConfiguration.JOB_IDENTIFIER, "LOCAL_ENV_FAIL_DRIVER_TEST") + .set(LocalDriverConfiguration.RUNTIME_NAMES, RuntimeIdentifier.RUNTIME_NAME) + .build(); + + private static void failOn(final Class<?> clazz) throws BindException, InjectionException { + + final Injector injector = Tang.Factory.getTang().newInjector(LOCAL_DRIVER_MODULE); + final ExceptionCodec exceptionCodec = injector.getInstance(ExceptionCodec.class); + + TestUtils.assertJobFailure( + FailClient.runInProcess(clazz, LOCAL_DRIVER_MODULE, 0), + exceptionCodec, SimulatedDriverFailure.class); + } + + @Test + public void testFailDriverConstructor() throws BindException, InjectionException { + try { + failOn(FailDriver.class); + } catch (final Throwable ex) { + Assert.assertTrue("Unexpected error: " + ex, TestUtils.hasCause(ex, SimulatedDriverFailure.class)); + } + } + + @Test + public void testFailDriverStart() throws BindException, InjectionException { + failOn(StartTime.class); + } + + @Test + public void testFailDriverAllocatedEvaluator() throws BindException, InjectionException { + failOn(AllocatedEvaluator.class); + } + + // TODO[REEF-1637] This and subsequent tests: enable when the bug is fixed. + // (i.e. in-process Driver can receive heartbeats from Evaluators). + // @Test + public void testFailDriverActiveContext() throws BindException, InjectionException { + failOn(ActiveContext.class); + } + + // @Test + public void testFailDriverRunningTask() throws BindException, InjectionException { + failOn(RunningTask.class); + } + + // @Test + public void testFailDriverTaskMessage() throws BindException, InjectionException { + failOn(TaskMessage.class); + } + + // @Test + public void testFailDriverSuspendedTask() throws BindException, InjectionException { + failOn(SuspendedTask.class); + } + + // @Test + public void testFailDriverCompletedTask() throws BindException, InjectionException { + failOn(CompletedTask.class); + } + + // @Test + public void testFailDriverCompletedEvaluator() throws BindException, InjectionException { + failOn(CompletedEvaluator.class); + } + + // @Test + public void testFailDriverAlarm() throws BindException, InjectionException { + failOn(Alarm.class); + } + + // @Test + public void testFailDriverStop() throws BindException, InjectionException { + failOn(StopTime.class); + } + + // @Test + public void testDriverCompleted() throws BindException, InjectionException { + + // REEFEnvironmentFailDriverTest can be replaced with any other class never used in FailDriver + final ReefServiceProtos.JobStatusProto status = FailClient.runInProcess( + REEFEnvironmentFailDriverTest.class, LOCAL_DRIVER_MODULE, 0); + + Assert.assertNotNull("Final job status must not be null", status); + Assert.assertTrue("Job state missing", status.hasState()); + Assert.assertEquals("Unexpected final job state", ReefServiceProtos.State.DONE, status.getState()); + } +}