Skip to content

Commit

Permalink
Add AsyncHttp4sServlet test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
vasilmkd committed Apr 25, 2021
1 parent 5250875 commit 979eda4
Showing 1 changed file with 107 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright 2013 http4s.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.http4s
package servlet

import cats.syntax.all._
import cats.effect.{IO, Resource, Timer}
import java.net.{HttpURLConnection, URL}
import java.nio.charset.StandardCharsets
import org.eclipse.jetty.server.HttpConfiguration
import org.eclipse.jetty.server.HttpConnectionFactory
import org.eclipse.jetty.server.{Server => EclipseServer}
import org.eclipse.jetty.server.ServerConnector
import org.eclipse.jetty.servlet.{ServletContextHandler, ServletHolder}
import org.http4s.dsl.io._
import org.http4s.syntax.all._
import org.http4s.server.DefaultServiceErrorHandler
import scala.io.Source
import scala.concurrent.duration._

class AsyncHttp4sServletSuite extends Http4sSuite {
lazy val service = HttpRoutes
.of[IO] {
case GET -> Root / "simple" =>
Ok("simple")
case req @ POST -> Root / "echo" =>
Ok(req.body)
case GET -> Root / "shifted" =>
IO.shift(munitExecutionContext) *>
// Wait for a bit to make sure we lose the race
Timer[IO].sleep(50.millis) *>
Ok("shifted")
}
.orNotFound

val servletServer = ResourceFixture[Int](serverPortR)

def get(serverPort: Int, path: String): IO[String] =
testBlocker.delay[IO, String](
Source
.fromURL(new URL(s"http://127.0.0.1:$serverPort/$path"))
.getLines()
.mkString)

def post(serverPort: Int, path: String, body: String): IO[String] =
testBlocker.delay[IO, String] {
val url = new URL(s"http://127.0.0.1:$serverPort/$path")
val conn = url.openConnection().asInstanceOf[HttpURLConnection]
val bytes = body.getBytes(StandardCharsets.UTF_8)
conn.setRequestMethod("POST")
conn.setRequestProperty("Content-Length", bytes.size.toString)
conn.setDoOutput(true)
conn.getOutputStream.write(bytes)
Source.fromInputStream(conn.getInputStream, StandardCharsets.UTF_8.name).getLines().mkString
}

servletServer.test("Http4sBlockingServlet handle GET requests") { server =>
get(server, "simple").assertEquals("simple")
}

servletServer.test("Http4sBlockingServlet handle POST requests") { server =>
post(server, "echo", "input data").assertEquals("input data")
}

servletServer.test("Http4sBlockingServlet work for shifted IO") { server =>
get(server, "shifted").assertEquals("shifted")
}

lazy val servlet = new AsyncHttp4sServlet[IO](
service = service,
servletIo = new NonBlockingServletIo[IO](4096),
serviceErrorHandler = DefaultServiceErrorHandler[IO]
)

lazy val serverPortR = Resource
.make(IO(new EclipseServer))(server => IO(server.stop()))
.evalMap { server =>
IO {
val connector =
new ServerConnector(server, new HttpConnectionFactory(new HttpConfiguration()))

val context = new ServletContextHandler
context.addServlet(new ServletHolder(servlet), "/*")

server.addConnector(connector)
server.setHandler(context)

server.start()

connector.getLocalPort
}
}
}

0 comments on commit 979eda4

Please sign in to comment.