Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE2] Fix be2 test db ref injection #1892

Merged
merged 10 commits into from
Jun 3, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,22 @@ import akka.pattern.AskableActorRef
import ch.epfl.pop.json.MessageDataProtocol.{KeyElectionFormat, resultElectionFormat}
import ch.epfl.pop.model.network.JsonRpcRequest
import ch.epfl.pop.model.network.method.message.data.election.VersionType
import ch.epfl.pop.model.network.method.message.data.election._
import ch.epfl.pop.model.objects.ElectionChannel._
import ch.epfl.pop.model.objects._
import ch.epfl.pop.model.network.method.message.data.election.*
import ch.epfl.pop.model.objects.ElectionChannel.*
import ch.epfl.pop.model.objects.*
import ch.epfl.pop.pubsub.graph.{ErrorCodes, GraphMessage, PipelineError}
import ch.epfl.pop.storage.DbActor
import ch.epfl.pop.storage.DbActor.DbActorReadElectionDataAck

import scala.collection.mutable
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success}
import scala.util.{Failure, Right, Success}

/** ElectionHandler object uses the db instance from the MessageHandler
*/
object ElectionHandler extends MessageHandler {
final lazy val handlerInstance = new ElectionHandler(super.dbActor)

def handleSetupElection(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleSetupElection(rpcMessage)

def handleOpenElection(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleOpenElection(rpcMessage)

def handleCastVoteElection(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleCastVoteElection(rpcMessage)

def handleResultElection(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleResultElection(rpcMessage)

def handleEndElection(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleEndElection(rpcMessage)

def handleKeyElection(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleKeyElection(rpcMessage)
}

class ElectionHandler(dbRef: => AskableActorRef) extends MessageHandler {

/** Overrides default DbActor with provided parameter
*/
override final val dbActor: AskableActorRef = dbRef
private val serverUnexpectedAnswer: String = "The server is doing something unexpected"

def handleSetupElection(rpcMessage: JsonRpcRequest): GraphMessage = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,6 @@ import scala.util.{Failure, Success}
/** RollCallHandler object uses the db instance from the MessageHandler (i.e PublishSubscribe)
*/
object RollCallHandler extends MessageHandler {
final lazy val handlerInstance = new RollCallHandler(super.dbActor)

def handleCreateRollCall(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleCreateRollCall(rpcMessage)

def handleOpenRollCall(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleOpenRollCall(rpcMessage)

def handleReopenRollCall(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleReopenRollCall(rpcMessage)

def handleCloseRollCall(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleCloseRollCall(rpcMessage)
}

/** Implementation of the RollCallHandler that provides a testable interface
*
* @param dbRef
* reference of the db actor
*/
class RollCallHandler(dbRef: => AskableActorRef) extends MessageHandler {

/** Overrides default DbActor with provided parameter
*/
override final val dbActor: AskableActorRef = dbRef

private val serverUnexpectedAnswer: String = "The server is doing something unexpected"

def handleCreateRollCall(rpcRequest: JsonRpcRequest): GraphMessage = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,6 @@ import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success}

object SocialMediaHandler extends MessageHandler {
final lazy val handlerInstance = new SocialMediaHandler(super.dbActor, super.mediator)

def handleAddChirp(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleAddChirp(rpcMessage)

def handleDeleteChirp(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleDeleteChirp(rpcMessage)

def handleNotifyAddChirp(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleNotifyAddChirp(rpcMessage)

def handleNotifyDeleteChirp(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleNotifyDeleteChirp(rpcMessage)

def handleAddReaction(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleAddReaction(rpcMessage)

def handleDeleteReaction(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleDeleteReaction(rpcMessage)
}

class SocialMediaHandler(dbRef: => AskableActorRef, mediatorRef: => AskableActorRef) extends MessageHandler {

/** Overrides default DbActor with provided parameter
*/
override final val dbActor: AskableActorRef = dbRef
override final val mediator: AskableActorRef = mediatorRef

private final val unknownAnswerDatabase: String = "Database actor returned an unknown answer"

private def generateSocialChannel(laoId: Hash): Channel = Channel(Channel.ROOT_CHANNEL_PREFIX + laoId + Channel.SOCIAL_MEDIA_CHIRPS_PREFIX)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,7 @@ import scala.concurrent.ExecutionContext.Implicits.global

/** WitnessHandler object uses the db instance from the MessageHandler
*/
object WitnessHandler {
final lazy val handlerInstance = new WitnessHandler(DbActor.getInstance)

def handleWitnessMessage(rpcMessage: JsonRpcRequest): GraphMessage = handlerInstance.handleWitnessMessage(rpcMessage)
}

class WitnessHandler(dbRef: => AskableActorRef) extends MessageHandler {

/** Overrides default DbActor with provided parameter
*/
override final val dbActor: AskableActorRef = dbRef

object WitnessHandler extends MessageHandler {
def handleWitnessMessage(rpcMessage: JsonRpcRequest): GraphMessage = {
val combined =
for {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
package ch.epfl.pop.pubsub.graph.handlers

import akka.NotUsed
import akka.actor.{Actor, ActorSystem, Props, Status}
import akka.http.scaladsl.model.ws
import akka.pattern.{AskableActorRef, ask}
import akka.stream.scaladsl.Flow
import akka.testkit.{ImplicitSender, TestKit}
import akka.util.Timeout
import ch.epfl.pop.model.network.method.message.Message
import ch.epfl.pop.model.network.method.message.data.ObjectType
import ch.epfl.pop.model.objects._
import ch.epfl.pop.model.objects.*
import ch.epfl.pop.pubsub.{MessageRegistry, PublishSubscribe}
import ch.epfl.pop.pubsub.graph.PipelineError
import ch.epfl.pop.storage.DbActor
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.{AnyFunSuiteLike => FunSuiteLike}
import org.scalatest.funsuite.AnyFunSuiteLike as FunSuiteLike
import org.scalatest.matchers.should.Matchers
import util.examples.Election.CastVoteElectionExamples._
import util.examples.Election.EndElectionExamples._
import util.examples.Election.OpenElectionExamples._
import util.examples.Election.SetupElectionExamples._
import util.examples.Election._
import util.examples.data._
import util.examples.Election.CastVoteElectionExamples.*
import util.examples.Election.EndElectionExamples.*
import util.examples.Election.OpenElectionExamples.*
import util.examples.Election.SetupElectionExamples.*
import util.examples.Election.*
import util.examples.data.*
import util.examples.LaoDataExample

import scala.concurrent.duration.FiniteDuration
Expand Down Expand Up @@ -214,142 +218,144 @@ class ElectionHandlerTest extends TestKit(ActorSystem("Election-DB-System")) wit
system.actorOf(dbActorMock)
}

private def injectDb(dbRef: AskableActorRef) = PublishSubscribe.buildGraph(Actor.noSender, dbRef, Actor.noSender, MessageRegistry(), Actor.noSender, Actor.noSender, Actor.noSender, false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case not, because different types of mocked db are injected. Using BeforeAndAfterEach would force to inject the same db for all test.


test("SetupElection should fail if the database fails storing the message") {
val mockedDB = mockDbWithNack
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = SetupElectionMessages.setupElection

rc.handleSetupElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleSetupElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}

test("SetupElection should succeed if the election doesn't already exists in database") {
val mockedDB = mockDbElectionNotSetUp
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = SetupElectionMessages.setupElection

rc.handleSetupElection(request) should equal(Right(request))
ElectionHandler.handleSetupElection(request) should equal(Right(request))

system.stop(mockedDB.actorRef)
}

test("SetupElection with secret ballot should succeed if it is stored correctly in the database") {
val mockedDB = mockDbWithAck
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = SetupElectionMessages.setupElectionSecretBallot

rc.handleSetupElection(request) should equal(Right(request))
ElectionHandler.handleSetupElection(request) should equal(Right(request))

system.stop(mockedDB.actorRef)
}

test("SetupElection with secret ballot should fail if the election cannot read in the lao data") {
val mockedDB = mockDbElectionSecretBallotReadFailed
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = SetupElectionMessages.setupElectionSecretBallot

rc.handleSetupElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleSetupElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}

test("OpenElection should succeed if the election already exists") {
val mockedDB = mockDbWithAck
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = OpenElectionMessages.openElection

rc.handleOpenElection(request) should equal(Right(request))
ElectionHandler.handleOpenElection(request) should equal(Right(request))

system.stop(mockedDB.actorRef)
}

test("OpenElection should fail if the election does not exist") {
val mockedDB = mockDbElectionNotSetUp
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = OpenElectionMessages.openElection

rc.handleOpenElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleOpenElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}

test("OpenElection should fail if the database fails storing the message") {
val mockedDB = mockDbWithNack
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = OpenElectionMessages.openElection

rc.handleOpenElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleOpenElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}

test("CastVoteElection should succeed if the election already exists") {
val mockedDB = mockDbWithAck
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = CastVoteElectionMessages.castVoteElection

rc.handleCastVoteElection(request) should equal(Right(request))
ElectionHandler.handleCastVoteElection(request) should equal(Right(request))

system.stop(mockedDB.actorRef)
}

test("CastVoteElection should fail if the database fails storing the message") {
val mockedDB = mockDbWithNack
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = CastVoteElectionMessages.castVoteElection

rc.handleCastVoteElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleCastVoteElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}

/*test("EndElection should succeed if the election already exists") {
val mockedDB = mockDbWithAckEndElection
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = EndElectionMessages.endElection

rc.handleEndElection(request) should equal(Right(request))
ElectionHandler.handleEndElection(request) should equal(Right(request))

system.stop(mockedDB.actorRef)
}*/

test("EndElection should fail if the election does not exist") {
val mockedDB = mockDbElectionNotSetUp
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = EndElectionMessages.endElection

rc.handleOpenElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleOpenElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}

test("EndElection should fail if the database fails storing the message") {
val mockedDB = mockDbWithNAckEndElection
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = EndElectionMessages.endElection

rc.handleEndElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleEndElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}

test("KeyElection should succeed if the election already exists") {
val mockedDB = mockDbWithAck
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = KeyElectionMessages.keyElection

rc.handleKeyElection(request) should equal(Right(request))
ElectionHandler.handleKeyElection(request) should equal(Right(request))

system.stop(mockedDB.actorRef)
}

test("keyElection should fail if the database fails storing the message") {
val mockedDB = mockDbWithNack
val rc = new ElectionHandler(mockedDB)
injectDb(mockedDB)
val request = KeyElectionMessages.keyElection

rc.handleKeyElection(request) shouldBe an[Left[PipelineError, _]]
ElectionHandler.handleKeyElection(request) shouldBe an[Left[PipelineError, _]]

system.stop(mockedDB.actorRef)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import akka.NotUsed
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.pattern.{AskableActorRef, ask}
import akka.stream.scaladsl.{Flow, Sink, Source}
import akka.testkit.TestKit
import akka.testkit.{TestKit, TestKitBase}
import akka.util.Timeout
import ch.epfl.pop.IOHelper.readJsonFromPath
import ch.epfl.pop.model.network.JsonRpcResponse
Expand All @@ -17,13 +17,15 @@ import ch.epfl.pop.storage.{DbActor, InMemoryStorage, SecurityModuleActor}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.AnyFunSuiteLike
import org.scalatest.matchers.should.Matchers
import org.scalatest.matchers.should.Matchers._
import org.scalatest.matchers.should.Matchers.*

import scala.concurrent.Await
import scala.concurrent.duration.{DurationInt, FiniteDuration}
import scala.util.Success

class GetMessagesByIdResponseHandlerSuite extends TestKit(ActorSystem("GetMessagesByIdResponseHandlerSuiteSystem")) with AnyFunSuiteLike with AskPatternConstants with BeforeAndAfterAll {
class GetMessagesByIdResponseHandlerSuite extends TestKitBase with AnyFunSuiteLike with AskPatternConstants with BeforeAndAfterAll {

implicit val system: ActorSystem = ActorSystem("GetMessagesByIdResponseHandlerSuiteSystem")

// Implicit for system actors
implicit val timeout: Timeout = Timeout(1.seconds)
Expand All @@ -35,8 +37,11 @@ class GetMessagesByIdResponseHandlerSuite extends TestKit(ActorSystem("GetMessag
val dbActorRef: AskableActorRef = system.actorOf(Props(DbActor(pubSubMediatorRef, messageRegistry, inMemoryStorage)), "DbActor")
val securityModuleActorRef: AskableActorRef = system.actorOf(Props(SecurityModuleActor(testSecurityDirectory)))

// Inject dbActor above
PublishSubscribe.buildGraph(pubSubMediatorRef, dbActorRef, securityModuleActorRef, messageRegistry, ActorRef.noSender, ActorRef.noSender, ActorRef.noSender, isServer = false)
override def beforeAll(): Unit = {
// Inject dbActor above
PublishSubscribe.buildGraph(pubSubMediatorRef, dbActorRef, securityModuleActorRef, messageRegistry, ActorRef.noSender, ActorRef.noSender, ActorRef.noSender, isServer = false)

}

// handler we want to test
val responseHandler: Flow[GraphMessage, GraphMessage, NotUsed] = ProcessMessagesHandler.getMsgByIdResponseHandler(MessageRegistry())
Expand Down
Loading
Loading