Skip to content

Commit

Permalink
Merge pull request #135 from tkrs/add-more-spec-for-connection
Browse files Browse the repository at this point in the history
Add more spec for Connection
  • Loading branch information
tkrs authored Nov 19, 2017
2 parents 5276a6b + 20ae6c1 commit 5188f40
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 24 deletions.
3 changes: 1 addition & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,7 @@ lazy val tests = project.in(file("modules/tests"))
name := "tests",
libraryDependencies ++= Pkg.forTest,
)
.settings(fork in test := true)
.settings(fork := true)
.settings(fork in Test := true)
.dependsOn(core, monix, `monix-reactive`, queue, `msgpack-circe`)

lazy val benchmark = (project in file("modules/benchmark"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mock-maker-inline
103 changes: 81 additions & 22 deletions modules/tests/src/test/scala/fluflu/ConnectionSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,51 @@ import java.net.InetSocketAddress
import java.nio.ByteBuffer
import java.nio.channels.SocketChannel
import java.time.{Clock, Duration}
import java.util.concurrent.LinkedBlockingDeque

import org.scalatest.{FunSpec, Matchers}
import org.scalatest.mockito.MockitoSugar
import org.mockito.Mockito._
import org.mockito.invocation.InvocationOnMock
import org.mockito.stubbing.Answer

import scala.util.Failure

class ConnectionSpec extends FunSpec with MockitoSugar with Matchers {
import Connection.ConnectionImpl

implicit val clock: Clock = Clock.systemUTC()

val address: InetSocketAddress = mock[InetSocketAddress]
val duration: Duration = Duration.ofSeconds(1)
val backoff: Backoff = Backoff.fix(duration)
val duration: Duration = Duration.ofSeconds(3)
val backoff: Backoff = Backoff.fix(Duration.ofMillis(1))

describe("constructor") {
it("should create instance successfully with retry some time") {
val isConnectedAnswers = new LinkedBlockingDeque[Boolean]()
isConnectedAnswers.add(false)
isConnectedAnswers.add(false)
isConnectedAnswers.add(true)
val arg = ByteBuffer.wrap(Array(1, 2, 3).map(_.toByte))
val channelMock = mock[SocketChannel]
when(channelMock.isConnected).thenAnswer(new Answer[Boolean] {
override def answer(invocation: InvocationOnMock): Boolean =
isConnectedAnswers.take()
})
when(channelMock.connect(address)).thenReturn(true)
when(channelMock.write(arg)).thenAnswer(new Answer[Int] {
override def answer(invocation: InvocationOnMock): Int = {
val arr = Array.ofDim[Byte](1)
arg.get(arr)
1
}
})
when(channelMock.connect(address))
.thenThrow(new IOException("ε≡≡ヘ( ´Д`)ノ"))
.thenReturn(true)
doNothing().when(channelMock).close()
when(channelMock.isConnected)
.thenReturn(false)
.thenReturn(true)
final class TestConnection extends ConnectionImpl(address, duration, backoff) {
override protected def channelOpen: SocketChannel = channelMock
override protected def channelOpen: SocketChannel =
channelMock
}
new TestConnection
}
it("should throw IOException when it gives up on the connection retry") {
val channelMock = mock[SocketChannel]
when(channelMock.connect(address))
.thenThrow(new IOException("ε≡≡ヘ( ´Д`)ノ"))
doNothing().when(channelMock).close()
final class TestConnection extends ConnectionImpl(address, Duration.ofMillis(5), backoff) {
override protected def channelOpen: SocketChannel =
channelMock
}
assertThrows[IOException](new TestConnection)
}
}
describe("write") {
it("should write successfully") {
Expand All @@ -70,7 +73,9 @@ class ConnectionSpec extends FunSpec with MockitoSugar with Matchers {
it("should write failed when it occurs IOException") {
val arg = ByteBuffer.wrap(Array(1, 2, 3).map(_.toByte))
val channelMock = mock[SocketChannel]
when(channelMock.isConnected).thenReturn(true)
when(channelMock.isConnected)
.thenReturn(false)
.thenReturn(true)
when(channelMock.connect(address)).thenReturn(true)
when(channelMock.write(arg)).thenThrow(new IOException)

Expand All @@ -80,5 +85,59 @@ class ConnectionSpec extends FunSpec with MockitoSugar with Matchers {
val conn = new TestConnection
assert(conn.write(arg).isFailure)
}
it("should return Failure with message: Already closed when it was closed") {
val arg = ByteBuffer.wrap(Array(1, 2, 3).map(_.toByte))
val channelMock = mock[SocketChannel]
when(channelMock.isConnected)
.thenReturn(false)
.thenReturn(true)
when(channelMock.connect(address))
.thenReturn(true)
when(channelMock.write(arg))
.thenThrow(new IOException)

final class TestConnection extends ConnectionImpl(address, duration, backoff) {
override protected def channelOpen: SocketChannel = channelMock
}
val conn = new TestConnection
conn.close()
val Failure(e) = conn.write(arg)
assert(e.getMessage === "Already closed")
}
it("should return Failure with IOException when it SocketChannel.connect returns false") {
val arg = ByteBuffer.wrap(Array(1, 2, 3).map(_.toByte))
val channelMock = mock[SocketChannel]
when(channelMock.isConnected)
.thenReturn(false)
.thenReturn(true)
when(channelMock.connect(address))
.thenReturn(true)
.thenReturn(false)

when(address.toString).thenReturn("hahahahahaha")
final class TestConnection extends ConnectionImpl(address, duration, backoff) {
override protected def channelOpen: SocketChannel = channelMock
}

val conn = new TestConnection
assertThrows[IOException](conn.write(arg).get)
}
}
describe("close") {
it("should close successfully") {
val channelMock = mock[SocketChannel]
when(channelMock.connect(address))
.thenReturn(true)
doNothing().when(channelMock).close()
when(channelMock.isConnected)
.thenReturn(true)
final class TestConnection extends ConnectionImpl(address, duration, backoff) {
override protected def channelOpen: SocketChannel =
channelMock
}
val conn = new TestConnection
conn.close()
assert(conn.isClosed)
}
}
}

0 comments on commit 5188f40

Please sign in to comment.