Tests, fixes; working version

This commit is contained in:
Jaime Freire 2024-01-03 18:41:25 +01:00
parent c8a7f22a45
commit a2c2e9faf6
7 changed files with 166 additions and 52 deletions

View File

@ -12,8 +12,8 @@ import lombok.Getter;
import lombok.Setter;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static dev.freireservices.social_altruism.chat.participant.ParticipantType.JUSTICIERO;
import static dev.freireservices.social_altruism.chat.participant.ParticipantType.SANTO;
@ -59,23 +59,48 @@ public class Participant {
}
private Behavior<ParticipantMessage> behavior() {
return uninitialized();
}
private Behavior<ParticipantMessage> uninitialized() {
return Behaviors.receive(ParticipantMessage.class)
.onMessage(SessionStarted.class, this::onSessionStarted)
.onMessage(SessionDenied.class, this::onSessionDenied)
.onMessage(SessionGranted.class, this::onSessionGranted)
.onMessage(SessionGranted.class, x ->
{
onSessionGranted(x);
return readyToStart();
})
.build();
}
private Behavior<ParticipantMessage> readyToStart() {
return Behaviors.receive(ParticipantMessage.class)
.onMessage(SessionStarted.class,
x -> {
onSessionStarted(x);
return started();
}
)
.build();
}
private Behavior<ParticipantMessage> started() {
return Behaviors.receive(ParticipantMessage.class)
.onMessage(PotReturned.class, this::onPotReturned)
.onMessage(SessionEnded.class, this::onSessionEnded)
.build();
}
private Behavior<ParticipantMessage> onSessionEnded(SessionEnded sessionEnded) {
context.getLog().info("Session ended for user {}", context.getSelf().path().name());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
context.getLog().info("Session ended for user: Stats: {}. Earned {} coins, profit {} %"
, context.getSelf().path().name()
, getParticipantCoins() - getInitialCoins()
, (getParticipantCoins() - getInitialCoins())
);
return Behaviors.stopped();
}
@ -85,32 +110,33 @@ public class Participant {
return Behaviors.stopped();
}
private Behavior<ParticipantMessage> onSessionGranted(
private void onSessionGranted(
SessionGranted message) {
context.getLog().info("Session granted message received for {} ", context.getSelf().path().name());
setChatRoom(message.chatRoom());
setSession(message.session());
return Behaviors.same();
}
private Behavior<ParticipantMessage> onSessionStarted(
private void onSessionStarted(
SessionStarted startSession) {
context.getLog().info("Session started for {} with {} participants", context.getSelf().path().name(), startSession.participants().size());
resetCurrentTurn();
setParticipants(startSession.participants());
setTotalTurns(startSession.totalTurns());
playTurn(startSession.replyTo());
context.getLog().info("Session started for {} with {} participants", context.getSelf().path().name(), startSession.participants().size());
return Behaviors.same();
playTurnWithSmallDelay(startSession.replyTo());
}
private void playTurn(ActorRef<SessionMessage> replyTo) {
private void playTurnWithSmallDelay(ActorRef<SessionMessage> replyTo) {
if (getParticipantCoins() > 0 && getCurrentTurn() < getTotalTurns()) {
replyTo.tell(new SessionProtocol.PlayTurn(
context.scheduleOnce(Duration.ofSeconds(5),
replyTo,
new SessionProtocol.PlayTurn(
replyTo,
context.getSelf(),
participants,
getCurrentTurn(),
getParticipationForCurrentTurn()
));
getParticipationForCurrentTurn())
);
}
}
@ -141,12 +167,7 @@ public class Participant {
// Still game?
if (getParticipantCoins() > 1) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
playTurn(potReturned.session());
playTurnWithSmallDelay(potReturned.session());
} else {
context
.getLog()
@ -160,7 +181,10 @@ public class Participant {
context.getLog().info("END GAME");
context.getLog().info("---------");
context.getLog().info("END GAME");
return Behaviors.stopped();
context.stop(context.getSelf());
Behaviors.stopped();
}
adjustBehaviour(potReturned);
return Behaviors.same();

View File

@ -10,6 +10,10 @@ public class ParticipantProtocol {
public interface ParticipantMessage {
}
enum Timeout implements ParticipantMessage {
INSTANCE
}
public record SessionGranted(
ActorRef<PotRoomMessage> chatRoom,
ActorRef<SessionMessage> session

View File

@ -4,7 +4,6 @@ import akka.actor.typed.ActorRef;
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.Behaviors;
import dev.freireservices.social_altruism.chat.participant.ParticipantProtocol.*;
import dev.freireservices.social_altruism.chat.potroom.PotRoomProtocol.EnterPot;
import dev.freireservices.social_altruism.chat.potroom.PotRoomProtocol.PotRoomMessage;
import dev.freireservices.social_altruism.chat.potroom.SessionProtocol.SessionMessage;
@ -54,9 +53,10 @@ public class PotRoom {
Session.create(participants, totalTurns),
URLEncoder.encode(enterPot.replyTo().path().name(), UTF_8));
participant.tell(new SessionGranted(chatRoom, session.narrow()));
// Communicate session start and share pot info with all participants
//Fishy, probably could spare one..
participants.forEach(p -> p.tell(new SessionGranted(chatRoom, session.narrow())));
participants.forEach(p -> p.tell(new SessionStarted(chatRoom, session, participants, totalTurns)));
return createPotBehaviour(chatRoom);
@ -89,6 +89,7 @@ public class PotRoom {
public static Behavior<PotRoomMessage> create(int numberOfParticipants, int totalTurns) {
return Behaviors.setup(
ctx -> new PotRoom(ctx, numberOfParticipants, totalTurns).createPotBehaviour(ctx.getSelf()));
ctx -> new PotRoom(ctx, numberOfParticipants, totalTurns)
.createPotBehaviour(ctx.getSelf()));
}
}

View File

@ -20,16 +20,6 @@ public class SessionProtocol {
implements SessionMessage {
}
public record ShareReturnPotWithParticipants(
ActorRef<SessionMessage> session,
List<ActorRef<ParticipantMessage>> participants,
double returnedAmount) implements SessionMessage {
}
public record EndSession() implements SessionMessage { }
public record PlayTurn(
ActorRef<SessionMessage> session,
@ -40,4 +30,13 @@ public class SessionProtocol {
implements SessionMessage {
}
public record ShareReturnPotWithParticipants(
ActorRef<SessionMessage> session,
List<ActorRef<ParticipantMessage>> participants,
double returnedAmount) implements SessionMessage {
}
public record EndSession() implements SessionMessage { }
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true"
xmlns:log4j='https://jakarta.apache.org/log4j/'>
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">

View File

@ -0,0 +1,58 @@
package dev.freireservices.social_altruism.chat;
import akka.actor.testkit.typed.javadsl.ActorTestKit;
import akka.actor.testkit.typed.javadsl.BehaviorTestKit;
import akka.actor.testkit.typed.javadsl.TestProbe;
import akka.actor.typed.ActorRef;
import dev.freireservices.social_altruism.chat.participant.Participant;
import dev.freireservices.social_altruism.chat.participant.ParticipantProtocol;
import dev.freireservices.social_altruism.chat.participant.ParticipantProtocol.ParticipantMessage;
import dev.freireservices.social_altruism.chat.potroom.PotRoom;
import dev.freireservices.social_altruism.chat.potroom.PotRoomProtocol;
import org.junit.Test;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import static dev.freireservices.social_altruism.chat.participant.ParticipantType.*;
public class CaseStudiesTests {
public static final int INITIAL_COINS = 100;
public static final int TOTAL_PARTICIPANTS = 3;
public static final int TOTAL_TURNS = 10;
@Test
public void testCooperation() {
final ActorTestKit testKit = ActorTestKit.create();
var potRoom = PotRoom.create(TOTAL_PARTICIPANTS, TOTAL_TURNS);
ActorRef<PotRoomProtocol.PotRoomMessage> chatRoomTest =
testKit.spawn(potRoom, "potRoom");
ActorRef<ParticipantMessage> p1 =
testKit.spawn(Participant.create(INITIAL_COINS, PICARO), "PICARO-1");
ActorRef<ParticipantMessage> p2 =
testKit.spawn(Participant.create(INITIAL_COINS, JUSTICIERO), "JUSTICIERO-1");
ActorRef<ParticipantMessage> p3 =
testKit.spawn(Participant.create(INITIAL_COINS, SANTO), "SANTO-1");
// Enter POT
chatRoomTest.tell(new PotRoomProtocol.EnterPot(p1));
chatRoomTest.tell(new PotRoomProtocol.EnterPot(p2));
chatRoomTest.tell(new PotRoomProtocol.EnterPot(p3));
try {
TimeUnit.MINUTES.sleep(3);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -2,7 +2,6 @@ package dev.freireservices.social_altruism.chat;
import akka.actor.testkit.typed.javadsl.ActorTestKit;
import akka.actor.testkit.typed.javadsl.BehaviorTestKit;
import akka.actor.testkit.typed.javadsl.BehaviorTestKit$;
import akka.actor.testkit.typed.javadsl.TestProbe;
import akka.actor.typed.ActorRef;
import dev.freireservices.social_altruism.chat.participant.Participant;
@ -16,13 +15,12 @@ import java.time.Duration;
import static dev.freireservices.social_altruism.chat.participant.ParticipantType.*;
public class PotQuickStartTest {
public class ProtocolTests {
public static final int INITIAL_COINS = 100;
public static final int TOTAL_PARTICIPANTS = 4;
@Test
// FIXME - Improve or delete..
public void testCooperationCaseOne() {
public void testSessionStartedOnJoinParticipants() {
final ActorTestKit testKit = ActorTestKit.create();
@ -57,8 +55,25 @@ public class PotQuickStartTest {
}
@Test
public void testActorGetsUserDenied() {
public void testActorGetsSessionGranted() {
final ActorTestKit testKit = ActorTestKit.create();
TestProbe<ParticipantMessage> testProbe =
testKit.createTestProbe("TestProbe");
ActorRef<PotRoomProtocol.PotRoomMessage> chatRoomTest =
testKit.spawn(PotRoom.create(1, 1), "chatRoom");
chatRoomTest.tell(new PotRoomProtocol.EnterPot(testProbe.ref()));
testProbe.expectMessageClass(ParticipantProtocol.SessionGranted.class, Duration.ofSeconds(10));
// #assert
}
@Test
public void testActorGetsSessionDenied() {
final ActorTestKit testKit = ActorTestKit.create();
TestProbe<ParticipantMessage> testProbe =
testKit.createTestProbe("TestProbe");
@ -67,13 +82,26 @@ public class PotQuickStartTest {
testKit.spawn(PotRoom.create(2, 1), "chatRoom");
chatRoomTest.tell(new PotRoomProtocol.EnterPot(testProbe.ref()));
testProbe.expectMessageClass(ParticipantProtocol.SessionGranted.class, Duration.ofSeconds(10));
chatRoomTest.tell(new PotRoomProtocol.EnterPot(testProbe.ref()));
testProbe.expectMessage(
Duration.ofSeconds(10), new ParticipantProtocol.SessionDenied("Can only enter a pot once"));
testProbe.expectMessageClass(ParticipantProtocol.SessionDenied.class, Duration.ofSeconds(5));
// #assert
}
@Test
public void testMultipleSessions() {
final ActorTestKit testKit = ActorTestKit.create();
TestProbe<ParticipantMessage> testProbe =
testKit.createTestProbe("TestProbe");
ActorRef<PotRoomProtocol.PotRoomMessage> chatRoomTest =
testKit.spawn(PotRoom.create(2, 1), "chatRoom");
chatRoomTest.tell(new PotRoomProtocol.EnterPot(testProbe.ref()));
chatRoomTest.tell(new PotRoomProtocol.EnterPot(testProbe.ref()));
testProbe.expectMessageClass(ParticipantProtocol.SessionDenied.class, Duration.ofSeconds(5));
// #assert
}