!str,htc replace and remove OneBoundedInterpreter

main work by @drewhk with contributions from @2m and @rkuhn

This work uncovered many well-hidden bugs in existing Stages, in
particular StatefulStage. These were hidden by the behavior of
OneBoundedInterpreter that normally behaves more orderly than it
guarantees in general, especially with respect to the timeliness of
delivery of upstream termination signals; the bugs were then that
internal state was not flushed when onComplete arrived “too early”.
This commit is contained in:
Roland Kuhn 2015-10-31 14:46:10 +01:00
parent 20f54435f1
commit 556012b7ee
107 changed files with 2456 additions and 3061 deletions

View file

@ -1,4 +1,5 @@
akka {
loggers = ["akka.testkit.TestEventListener"]
actor {
serialize-creators = on
serialize-messages = on

View file

@ -7,6 +7,7 @@ package akka.http.scaladsl.server
import akka.http.scaladsl.model
import model.HttpMethods._
import model.StatusCodes
import akka.testkit.EventFilter
class BasicRouteSpecs extends RoutingSpec {
@ -134,7 +135,7 @@ class BasicRouteSpecs extends RoutingSpec {
case object MyException extends RuntimeException
"Route sealing" should {
"catch route execution exceptions" in {
"catch route execution exceptions" in EventFilter[MyException.type](occurrences = 1).intercept {
Get("/abc") ~> Route.seal {
get { ctx
throw MyException
@ -143,7 +144,7 @@ class BasicRouteSpecs extends RoutingSpec {
status shouldEqual StatusCodes.InternalServerError
}
}
"catch route building exceptions" in {
"catch route building exceptions" in EventFilter[MyException.type](occurrences = 1).intercept {
Get("/abc") ~> Route.seal {
get {
throw MyException
@ -152,7 +153,7 @@ class BasicRouteSpecs extends RoutingSpec {
status shouldEqual StatusCodes.InternalServerError
}
}
"convert all rejections to responses" in {
"convert all rejections to responses" in EventFilter[RuntimeException](occurrences = 1).intercept {
object MyRejection extends Rejection
Get("/abc") ~> Route.seal {
get {

View file

@ -7,8 +7,8 @@ package directives
import akka.http.scaladsl.model.{ MediaTypes, MediaRanges, StatusCodes }
import akka.http.scaladsl.model.headers._
import scala.concurrent.Future
import akka.testkit.EventFilter
class ExecutionDirectivesSpec extends RoutingSpec {
object MyException extends RuntimeException
@ -51,7 +51,7 @@ class ExecutionDirectivesSpec extends RoutingSpec {
}
}
}
"not interfere with alternative routes" in {
"not interfere with alternative routes" in EventFilter[MyException.type](occurrences = 1).intercept {
Get("/abc") ~>
get {
handleExceptions(handler)(reject) ~ { ctx
@ -62,22 +62,22 @@ class ExecutionDirectivesSpec extends RoutingSpec {
responseAs[String] shouldEqual "There was an internal server error."
}
}
"not handle other exceptions" in {
"not handle other exceptions" in EventFilter[RuntimeException](occurrences = 1, message = "buh").intercept {
Get("/abc") ~>
get {
handleExceptions(handler) {
throw new RuntimeException
throw new RuntimeException("buh")
}
} ~> check {
status shouldEqual StatusCodes.InternalServerError
responseAs[String] shouldEqual "There was an internal server error."
}
}
"always fall back to a default content type" in {
"always fall back to a default content type" in EventFilter[RuntimeException](occurrences = 2, message = "buh2").intercept {
Get("/abc") ~> Accept(MediaTypes.`application/json`) ~>
get {
handleExceptions(handler) {
throw new RuntimeException
throw new RuntimeException("buh2")
}
} ~> check {
status shouldEqual StatusCodes.InternalServerError
@ -87,7 +87,7 @@ class ExecutionDirectivesSpec extends RoutingSpec {
Get("/abc") ~> Accept(MediaTypes.`text/xml`, MediaRanges.`*/*`.withQValue(0f)) ~>
get {
handleExceptions(handler) {
throw new RuntimeException
throw new RuntimeException("buh2")
}
} ~> check {
status shouldEqual StatusCodes.InternalServerError

View file

@ -6,8 +6,8 @@ package akka.http.scaladsl.server
package directives
import akka.http.scaladsl.model.StatusCodes
import scala.concurrent.Future
import akka.testkit.EventFilter
class FutureDirectivesSpec extends RoutingSpec {
@ -56,7 +56,7 @@ class FutureDirectivesSpec extends RoutingSpec {
responseAs[String] shouldEqual "yes"
}
}
"propagate the exception in the failure case" in {
"propagate the exception in the failure case" in EventFilter[Exception](occurrences = 1, message = "XXX").intercept {
Get() ~> onSuccess(Future.failed(TestException)) { echoComplete } ~> check {
status shouldEqual StatusCodes.InternalServerError
}
@ -67,7 +67,7 @@ class FutureDirectivesSpec extends RoutingSpec {
responseAs[String] shouldEqual s"Oops. akka.http.scaladsl.server.directives.FutureDirectivesSpec$$TestException: EX when ok"
}
}
"catch an exception in the failure case" in {
"catch an exception in the failure case" in EventFilter[Exception](occurrences = 1, message = "XXX").intercept {
Get() ~> onSuccess(Future.failed(TestException)) { throwTestException("EX when ") } ~> check {
status shouldEqual StatusCodes.InternalServerError
responseAs[String] shouldEqual "There was an internal server error."

View file

@ -8,7 +8,6 @@ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport
import akka.stream.scaladsl.Sink
import org.scalatest.FreeSpec
import scala.concurrent.{ Future, Promise }
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._
import akka.http.scaladsl.marshalling._
@ -18,8 +17,8 @@ import akka.http.impl.util._
import headers._
import StatusCodes._
import MediaTypes._
import scala.xml.NodeSeq
import akka.testkit.EventFilter
class RouteDirectivesSpec extends FreeSpec with GenericRoutingSpec {
@ -47,7 +46,7 @@ class RouteDirectivesSpec extends FreeSpec with GenericRoutingSpec {
"for successful futures and marshalling" in {
Get() ~> complete(Promise.successful("yes").future) ~> check { responseAs[String] shouldEqual "yes" }
}
"for failed futures and marshalling" in {
"for failed futures and marshalling" in EventFilter[RuntimeException](occurrences = 1).intercept {
object TestException extends RuntimeException
Get() ~> complete(Promise.failed[String](TestException).future) ~>
check {

View file

@ -9,6 +9,7 @@ import scala.concurrent.Future
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.server.AuthenticationFailedRejection.{ CredentialsRejected, CredentialsMissing }
import akka.testkit.EventFilter
class SecurityDirectivesSpec extends RoutingSpec {
val dontBasicAuth = authenticateBasicAsync[String]("MyRealm", _ Future.successful(None))
@ -60,11 +61,13 @@ class SecurityDirectivesSpec extends RoutingSpec {
}
"properly handle exceptions thrown in its inner route" in {
object TestException extends RuntimeException
Get() ~> Authorization(BasicHttpCredentials("Alice", "")) ~> {
Route.seal {
doBasicAuth { _ throw TestException }
}
} ~> check { status shouldEqual StatusCodes.InternalServerError }
EventFilter[TestException.type](occurrences = 1).intercept {
Get() ~> Authorization(BasicHttpCredentials("Alice", "")) ~> {
Route.seal {
doBasicAuth { _ throw TestException }
}
} ~> check { status shouldEqual StatusCodes.InternalServerError }
}
}
}
"bearer token authentication" should {
@ -108,11 +111,13 @@ class SecurityDirectivesSpec extends RoutingSpec {
}
"properly handle exceptions thrown in its inner route" in {
object TestException extends RuntimeException
Get() ~> Authorization(OAuth2BearerToken("myToken")) ~> {
Route.seal {
doOAuth2Auth { _ throw TestException }
}
} ~> check { status shouldEqual StatusCodes.InternalServerError }
EventFilter[TestException.type](occurrences = 1).intercept {
Get() ~> Authorization(OAuth2BearerToken("myToken")) ~> {
Route.seal {
doOAuth2Auth { _ throw TestException }
}
} ~> check { status shouldEqual StatusCodes.InternalServerError }
}
}
}
"authentication directives" should {