// Copyright © 2012-2020 VLINGO LABS. All rights reserved. // // This Source Code Form is subject to the terms of the // Mozilla Public License, v. 2.0. If a copy of the MPL // was not distributed with this file, You can obtain // one at https://mozilla.org/MPL/2.0/. package io.vlingo.actors.supervision; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; import io.vlingo.actors.ActorsTest; import io.vlingo.actors.Definition; import io.vlingo.actors.Supervisor; import io.vlingo.actors.supervision.EscalateSupervisorActor.EscalateSupervisorTestResults; import io.vlingo.actors.supervision.FailureControlActor.FailureControlTestResults; import io.vlingo.actors.supervision.PingActor.PingTestResults; import io.vlingo.actors.supervision.PongActor.PongTestResults; import io.vlingo.actors.supervision.RestartFiveInOneSupervisorActor.RestartFiveInOneSupervisorTestResults; import io.vlingo.actors.supervision.RestartForeverSupervisorActor.RestartForeverSupervisorTestResults; import io.vlingo.actors.supervision.ResumeForeverSupervisorActor.ResumeForeverSupervisorTestResults; import io.vlingo.actors.supervision.StopAllSupervisorActor.StopAllSupervisorResult; import io.vlingo.actors.testkit.AccessSafely; import io.vlingo.actors.testkit.TestActor; public class SupervisionStrategyTest extends ActorsTest { @Test public void testResumeForeverStrategy() { final ResumeForeverSupervisorTestResults resumeForeverSupervisorTestResults = new ResumeForeverSupervisorTestResults(); final TestActor<Supervisor> supervisor = testWorld.actorFor( Supervisor.class, Definition.has(ResumeForeverSupervisorActor.class, Definition.parameters(resumeForeverSupervisorTestResults), "resume-forever-supervisor")); final FailureControlTestResults failureControlTestResults = new FailureControlTestResults(); final TestActor<FailureControl> failure = testWorld.actorFor( FailureControl.class, Definition.has(FailureControlActor.class, Definition.parameters(failureControlTestResults), supervisor.actorInside(), "failure-for-stop")); AccessSafely failureAccess = failureControlTestResults.afterCompleting(0); AccessSafely resumeAccess = resumeForeverSupervisorTestResults.afterCompleting(1); for (int idx = 1; idx <= 20; ++idx) { failureAccess = failureControlTestResults.afterCompleting(1); failure.actor().failNow(); failure.actor().afterFailure(); } assertEquals(20, (int) failureAccess.readFrom("failNowCount")); assertEquals(20, (int) failureAccess.readFrom("afterFailureCount")); assertEquals(20, (int) resumeAccess.readFrom("informedCount")); failureAccess = failureControlTestResults.afterCompleting(20); for (int idx = 1; idx <= 20; ++idx) { failure.actor().failNow(); failure.actor().afterFailure(); } assertEquals(40, (int) failureAccess.readFrom("failNowCount")); assertEquals(40, (int) failureAccess.readFrom("afterFailureCount")); assertTrue(40 <= (int) resumeAccess.readFrom("informedCount")); } @Test public void testRestartForeverStrategy() { final RestartForeverSupervisorTestResults restartForeverSupervisorTestResults = new RestartForeverSupervisorTestResults(); final TestActor<Supervisor> supervisor = testWorld.actorFor( Supervisor.class, Definition.has(RestartForeverSupervisorActor.class, Definition.parameters(restartForeverSupervisorTestResults), "restart-forever-supervisor")); final FailureControlTestResults failureControlTestResults = new FailureControlTestResults(); final TestActor<FailureControl> failure = testWorld.actorFor( FailureControl.class, Definition.has(FailureControlActor.class, Definition.parameters(failureControlTestResults), supervisor.actorInside(), "failure-for-stop")); AccessSafely failedAccess = failureControlTestResults.afterCompleting(40); AccessSafely restartAccess = restartForeverSupervisorTestResults.afterCompleting(40); for (int idx = 1; idx <= 20; ++idx) { failure.actor().failNow(); failure.actor().afterFailure(); } assertEquals(20, (int) failedAccess.readFrom("failNowCount")); assertEquals(20, (int) failedAccess.readFrom("afterFailureCount")); failedAccess = failureControlTestResults.afterCompleting(40); for (int idx = 1; idx <= 20; ++idx) { failure.actor().failNow(); failure.actor().afterFailure(); } assertEquals(40, (int) failedAccess.readFrom("failNowCount")); assertEquals(40, (int) failedAccess.readFrom("afterFailureCount")); assertTrue(40 <= (int) restartAccess.readFrom("informedCount")); } @Test public void test5Intensity1PeriodRestartStrategy() { final RestartFiveInOneSupervisorTestResults restartFiveInOneSupervisorTestResults = new RestartFiveInOneSupervisorTestResults(); final TestActor<Supervisor> supervisor = testWorld.actorFor( Supervisor.class, Definition.has(RestartFiveInOneSupervisorActor.class, Definition.parameters(restartFiveInOneSupervisorTestResults), "resuming-5-1-supervisor")); final FailureControlTestResults failureControlTestResults = new FailureControlTestResults(); final TestActor<FailureControl> failure = testWorld.actorFor( FailureControl.class, Definition.has(FailureControlActor.class, Definition.parameters(failureControlTestResults), supervisor.actorInside(), "failure-for-stop")); AccessSafely failureAccess = failureControlTestResults.afterCompleting(0); AccessSafely restartAccess = restartFiveInOneSupervisorTestResults.afterCompleting(5); for (int idx = 1; idx <= 5; ++idx) { failureAccess = failureControlTestResults.afterCompleting(1); failure.actor().failNow(); failure.actor().afterFailure(); } assertEquals(5, (int) failureAccess.readFrom("failNowCount")); assertEquals(5, (int) failureAccess.readFrom("afterFailureCount")); failureAccess = failureControlTestResults.afterCompleting(1); restartAccess = restartFiveInOneSupervisorTestResults.afterCompleting(1); failure.actor().failNow(); // should stop failure.actor().afterFailure(); assertTrue(failure.actorInside().isStopped()); assertEquals(6, (int) failureAccess.readFrom("failNowCount")); assertEquals(5, (int) failureAccess.readFrom("afterFailureCount")); assertEquals(6, (int) restartAccess.readFrom("informedCount")); } @Test public void testEscalate() { final EscalateSupervisorTestResults escalateSupervisorTestResults = new EscalateSupervisorTestResults(); final TestActor<Supervisor> supervisor = testWorld.actorFor( Supervisor.class, Definition.has(EscalateSupervisorActor.class, Definition.parameters(escalateSupervisorTestResults), "escalate")); final FailureControlTestResults failureControlTestResults = new FailureControlTestResults(); final TestActor<FailureControl> failure = testWorld.actorFor( FailureControl.class, Definition.has(FailureControlActor.class, Definition.parameters(failureControlTestResults), supervisor.actorInside(), "failure")); AccessSafely escalateAccess = escalateSupervisorTestResults.afterCompleting(1); AccessSafely failureAccess = failureControlTestResults.afterCompleting(1); failure.actor().failNow(); assertEquals(1, (int) escalateAccess.readFrom("informedCount")); assertEquals(1, (int) failureAccess.readFrom("stoppedCount")); } @Test public void testStopAll() { StopAllSupervisorResult stopResults = new StopAllSupervisorResult(); world.actorFor( Supervisor.class, Definition.has(StopAllSupervisorActor.class, Definition.parameters(stopResults), "stop-all")); final PingTestResults pingTestResults = new PingTestResults(); final Ping ping = world.actorFor( Ping.class, Definition.has(PingActor.class, Definition.parameters(pingTestResults), StopAllSupervisorActor.instance, "ping")); final PongTestResults pongTestResults = new PongTestResults(); world.actorFor( Pong.class, Definition.has(PongActor.class, Definition.parameters(pongTestResults), StopAllSupervisorActor.instance, "pong")); AccessSafely pingAccess = pingTestResults.afterCompleting(1); AccessSafely pongAccess = pongTestResults.afterCompleting(1); AccessSafely stopAccess = stopResults.afterCompleting(1); ping.ping(); assertEquals(1, (int) stopAccess.readFrom("informedCount")); assertEquals(1, (int) pingAccess.readFrom("stopCount")); assertEquals(1, (int) pongAccess.readFrom("stopCount")); } }