Giter Club home page Giter Club logo

Comments (8)

AdamJKing avatar AdamJKing commented on May 24, 2024 1

I believe this is happening due to an intentional design choice with ScalaTest's SerialExecutionContext which only executes Futures scheduled during the test body. This execution context only executes scheduled futures when the runNow method is explicitly invoked;

https://github.com/scalatest/scalatest/blob/6bf2e09b646909547ccbd64480a2cf1089e7f8dc/jvm/core/src/main/scala/org/scalatest/concurrent/SerialExecutionContext.scala#L111

For async test suites this is performed as part of the deferred outcome / status that occurs when the test is run;

https://github.com/scalatest/scalatest/blob/6bf2e09b646909547ccbd64480a2cf1089e7f8dc/jvm/core/src/main/scala/org/scalatest/AsyncEngine.scala#L377C19-L377C19

However the BeforeAndAfterAll trait registers the teardown action as happening after the test body has executed and returned a status;

https://github.com/scalatest/scalatest/blob/6bf2e09b646909547ccbd64480a2cf1089e7f8dc/jvm/core/src/main/scala/org/scalatest/BeforeAndAfterAll.scala#L223-L226

Since the runNow has already completed any new tasks on the queue won't be executed

Using a different EC works because task execution is no longer dependant on being triggered during the test. Would there be any issues using a dedicated EC for the resources while still having IO in test delegated to the serial execution context?

from cats-effect-testing.

froth avatar froth commented on May 24, 2024

I am also running into this problem.

(here was some thought which does not make sense any longer since I read the scalatest issues you linked. But I am unable to delete this comment)

from cats-effect-testing.

froth avatar froth commented on May 24, 2024

The following workaround solves the problem for me (jvm):

class TestExample extends FixtureAsyncFreeSpec with AsyncIOSpec with CatsResourceIO[Int] {

override val executionContext: ExecutionContext = ExecutionContext.global
// ...
}

from cats-effect-testing.

ghostbuster91 avatar ghostbuster91 commented on May 24, 2024

I think that changing only the execution context to the one which is backed by multiple threads can result in some concurrency issues as described in the first part.

from cats-effect-testing.

sentenza avatar sentenza commented on May 24, 2024

The following workaround solves the problem for me (jvm):

class TestExample extends FixtureAsyncFreeSpec with AsyncIOSpec with CatsResourceIO[Int] {

override val executionContext: ExecutionContext = ExecutionContext.global
// ...
}

The only workaround that is actually working for me is using the global EC. Otherwise the resource defined here will never be deallocated/released:

class RpcLocationServiceSpec
    extends FixtureAsyncWordSpec
    with AsyncIOSpec
    with Matchers
    with OptionValues
    with AsyncMockFactory
    with CatsResourceIO[IO[OutcomeIO[Nothing]]] {
  abstract class MockUnLocationService(
      unLocationRepo: UnLocationRepositoryAlgebra[IO],
      logger: SelfAwareStructuredLogger[IO]
  ) extends UnLocationService[IO](unLocationRepo, logger)
  implicit val unsafeLogger: SelfAwareStructuredLogger[IO] = Slf4jLogger.getLogger[IO]
  private val testRpcPort: Int                             = 9095
  private val mockLocationService                          = mock[MockUnLocationService]
  private val rpcConfig                                    = RpcConfig("127.0.0.1", testRpcPort)
// THE ONLY WORKAROUND THAT WORKS:
  override val executionContext: ExecutionContext = ExecutionContext.global
  override val resource: Resource[IO, IO[OutcomeIO[Nothing]]] =
    RpcLocationService
      .service[IO](mockLocationService, unsafeLogger)
      .flatMap(RpcServerManager.startServer[IO](_, rpcConfig, unsafeLogger).useForever.background)

from cats-effect-testing.

adamretter avatar adamretter commented on May 24, 2024

We are also experiencing this problem with the simple reproducible code:

import cats.effect.{IO, Resource}
import cats.effect.testing.scalatest.{AsyncIOSpec, CatsResourceIO}
import org.scalatest.wordspec.FixtureAsyncWordSpec

class TestMeSpec extends FixtureAsyncWordSpec with AsyncIOSpec with CatsResourceIO[Int] {

  override val resource: Resource[IO, Int] = Resource.make(IO.pure(1).flatTap(id => IO.println(s"Acquired Resource: $id")))(id => IO.println(s"Released Resource: $id"))

  "cats resource specifications" should {
    "should acquire and release the resource" in { id =>
        IO.print(s"I have the resource: $id")
    }
  }
}

This only prints:

Acquired Resource: 1
I have the resource: 1[info] TestMeSpec:
[info] cats resource specifications
[info] - should should acquire and release the resource

Whereas we expect it to instead print:

Acquired Resource: 1
I have the resource: 1[info] TestMeSpec:
[info] cats resource specifications
[info] - should should acquire and release the resource
Released Resource: 1

from cats-effect-testing.

sentenza avatar sentenza commented on May 24, 2024

@djspiewak @sh0hei do you know who could look into this issue? It's been reported more than 1 year ago 🙏

from cats-effect-testing.

Daenyth avatar Daenyth commented on May 24, 2024

I took a glance at CatsResource and it seems fine - I think the problem here is the ExecutionContext that the futures are running on being terminated before the shutdown step can complete. I'm not 100% certain though

from cats-effect-testing.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.