I've been using .futureValue in some of my async tests as syntactic sugar to block instead of using Await.result() just to make things like data creation easier to deal with. I just updated by Play 2.5 app with ScalaTest 3.0.x and scalatestplus-play 2.0.1 to Play 2.6 with scalatestplus-play 3.1.2, then Play 2.7 with scalatestplus-play 4.0.1.
After I upgraded to Play 2.6, I noticed that 1 of my test suites started hanging and failing.
I narrowed it down to a usage of someDeleteMethod.futureValue. When I replaced that one line with Await.result(someDeleteMethod, 30.seconds), the deadlock went away. While I've fixed this one scenario, the potential bigger implications worry me. I'm wondering why the deadlock would occur here, and I'm pondering if I should stop using .futureValue everywhere in my tests or if I'm just generally doing something wrong.
The code that hung was inside a deeply future chain. Some of the lower levels wrap blocking code inside a future with Future { blocking { ... } }, and I noticed the area where I was incidentally hanging had a Future { ... } block, which never got executed. I'm thinking that Await.result fixed things because it calls blocking(), and I noticed that if I wrapped my existing code in blocking(), it also removed the deadlock, but I thought I was supposed to call that inside Future { ... }?
Any ideas or suggestions on avoiding deadlock? I'm wondering why this came up with Play 2.6+ also, but that might just be a coincidence due to some internal changes.