All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sisioh.trinity.test.ControllerIntegrationTestSupport.scala Maven / Gradle / Ivy

The newest version!
package org.sisioh.trinity.test

import com.twitter.finagle.Service
import com.twitter.finagle.builder.ClientBuilder
import com.twitter.finagle.http.{Http, Response => FinagleResponse}
import com.twitter.util.{Await => TAwait}
import java.net.{InetSocketAddress, SocketAddress}
import java.util.concurrent.TimeUnit
import org.jboss.netty.handler.codec.http.{HttpMethod, HttpRequest, HttpResponse}
import org.sisioh.trinity.domain.io.http.{HeaderName, Response => IOResponse}
import org.sisioh.trinity.domain.mvc.Environment
import org.sisioh.trinity.domain.mvc.http.Response
import org.sisioh.trinity.domain.mvc.server.Server
import org.sisioh.trinity.util.DurationConverters._
import org.specs2.execute.{AsResult, Result}
import org.specs2.mutable.Around
import org.specs2.specification.Scope
import scala.concurrent.duration.Duration
import scala.concurrent.{ExecutionContext, Await => SAwait}
import scala.util.Try

/**
 * インテグレーションテストをサポートするためのトレイト。
 */
trait ControllerIntegrationTestSupport extends ControllerTestSupport {

  case class IntegrationTestContext(server: TestServer = TestServer())
                                   (implicit val executor: ExecutionContext) extends TestContext

  private val httpClients = scala.collection.mutable.Map.empty[SocketAddress, Service[HttpRequest, HttpResponse]]



  protected val serverAwaitDuration = Duration(5, TimeUnit.MINUTES)

  protected def buildRequest
  (method: HttpMethod, path: String, content: Option[Content], headers: Map[HeaderName, String], timeout: Duration)
  (implicit testContext: TestContext): Try[Response] = {
    implicit val executor = testContext.executor
    val request = newRequest(method, path, content, headers)
    val host = testContext.server.host.getOrElse(defaultHost)
    val port = testContext.server.port.getOrElse(defaultPort)
    val address: SocketAddress = new InetSocketAddress(host, port)
    val client = httpClients.getOrElseUpdate(
      address,
      ClientBuilder()
        .codec(Http())
        .hosts(address)
        .hostConnectionLimit(1)
        .build()
    )
    Try {
      val finagleResponse = TAwait.result(client(request), timeout.toTwitter)
      val r = IOResponse(FinagleResponse(finagleResponse))
      Response(r)
    }
  }

  protected class WithServer(server: Server,
                             environment: Environment.Value = Environment.Product,
                             awaitDuration: Duration = serverAwaitDuration)
                            (implicit executor: ExecutionContext)
    extends Around with Scope {

    private def running[T](block: => T): T = {
      synchronized {
        val future = server.start(environment).map {
          _ =>
            block
        }.flatMap {
          result =>
            server.stop().map(_ => result)
        }
        SAwait.result(future, awaitDuration)
      }
    }

    def around[T: AsResult](t: => T): Result = {
      running(AsResult.effectively(t))
    }

  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy