I'm new to scala so I might not be clear with the issue I'm facing, I might not be including all the details needed to identify the issue. I'll do my best to clarify.
I'm converting a post
scalatra endpoint to asyncPost
and converting Await.result
s to Future
s. The unit tests that used to pass are now failing intermittently: a test is executed with request from another test. When I remove all tests and run each test individually they all pass. At this point my hypothesis is that the requests are being mixed up across unit tests. I'm not sure if this is an issue with the code or unit test setup.
This is a production code so there is a lot of logic that I can't fit here, I try to remove everything and keep what I think is relevant.
Actual code:
class Endpoints(...)
extends ...
with ABC_ExecutionContext
with FutureSupport {
protected implicit def executor = executionContext
val myEndpoint: Route = asyncPost("/endpoint/", operation(queryGroup)) {
setTransactionName(":post /endpoint")
new AsyncResult { val is = {
for {
...
out <- doSomethingWithRequest() // implicit request is passed, returns a Future
...
response <- doSomething(out) // returns a Future
} yield response
}}
}
}
Tests:
class EndpointsSpec
extends MockitoSugar
with JsonFormats
with ... {
"POST /endpoint on Endpoints" should {
"should work for request A" in {
post("/endpoint/",
write(mockRequestA).getBytes(),
Map("user-id" -> "12345")) {
body must_== """something A"""
status must_== 200
}
}
"should work for request B" in {
post("/endpoint/",
write(mockRequestB).getBytes(),
Map("user-id" -> "12345")) {
body must_== """something B"""
status must_== 200
}
}
}
}
I also tried to create a context per unit test
class EndpointsSpec
extends MockitoSugar
with JsonFormats
with ... {
"POST /endpoint on Endpoints" should {
"should work for request A" in {
val context: HystrixRequestContext = HystrixRequestContext.initializeContext
try {
post("/endpoint/",
write(mockRequestA).getBytes(),
Map("user-id" -> "12345")) {
body must_== """something A"""
status must_== 200
}
} finally {
context.shutdown()
}
}
"should work for request B" in {
val context: HystrixRequestContext = HystrixRequestContext.initializeContext
try {
post("/endpoint/",
write(mockRequestB).getBytes(),
Map("user-id" -> "12345")) {
body must_== """something B"""
status must_== 200
}
} finally {
context.shutdown()
}
}
}
}
The issue might be with something I have omitted, let me know and I can add more details before making sample code too complicate
Extra info:
I don't have experience with Scalatra neither with Specs2. Just giving a quick look to the docs of Scalatra
and how to work with async requests, just using get
, post
or the one you need without the async
prefxi should work. From the docs here you have an example
class MyAppServlet extends ScalatraServlet with FutureSupport {
get("/"){
new AsyncResult { val is =
Future {
// Add async logic here
// ...
}
}
}
}