Skip to content

Commit 737fce1

Browse files
committed
reset counter in beforeEach, set IdleTimout explicitly,
1 parent b00c43b commit 737fce1

File tree

4 files changed

+34
-18
lines changed

4 files changed

+34
-18
lines changed

rest/.jvm/src/test/scala/io/udash/rest/SttpRestCallTest.scala

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@ package rest
33

44
import io.udash.rest.raw.HttpErrorException
55
import io.udash.rest.raw.RawRest.HandleRequest
6-
import sttp.client3.SttpBackend
6+
import sttp.client3.{HttpClientFutureBackend, SttpBackend}
77

8-
import scala.concurrent.duration._
8+
import java.net.http.HttpClient
9+
import java.time.Duration as JDuration
10+
import scala.concurrent.duration.*
911
import scala.concurrent.{Await, Future}
1012

1113
trait SttpClientRestTest extends ServletBasedRestApiTest {
12-
implicit val backend: SttpBackend[Future, Any] = SttpRestClient.defaultBackend()
14+
implicit val backend: SttpBackend[Future, Any] = HttpClientFutureBackend.usingClient(
15+
//like defaultHttpClient but with connection timeout >> CallTimeout
16+
HttpClient
17+
.newBuilder()
18+
.connectTimeout(JDuration.ofMillis(IdleTimout.toMillis))
19+
.followRedirects(HttpClient.Redirect.NEVER)
20+
.build()
21+
)
1322

1423
def clientHandle: HandleRequest =
1524
SttpRestClient.asHandleRequest[Future](s"$baseUrl/api")

rest/jetty/src/test/scala/io/udash/rest/jetty/JettyRestCallTest.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import org.eclipse.jetty.client.HttpClient
88
final class JettyRestCallTest extends ServletBasedRestApiTest with RestApiTestScenarios {
99
val client: HttpClient = new HttpClient() {
1010
setMaxConnectionsPerDestination(MaxConnections)
11+
setIdleTimeout(IdleTimout.toMillis)
1112
}
1213

1314
def clientHandle: HandleRequest =

rest/src/test/scala/io/udash/rest/RestApiTest.scala

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,27 @@ import io.udash.rest.raw.RawRest.HandleRequest
88
import monix.eval.Task
99
import monix.execution.Scheduler
1010
import org.scalactic.source.Position
11+
import org.scalatest.BeforeAndAfterEach
1112
import org.scalatest.concurrent.ScalaFutures
1213
import org.scalatest.funsuite.AnyFunSuite
1314
import org.scalatest.time.{Millis, Seconds, Span}
1415

1516
import scala.concurrent.duration.FiniteDuration
1617

17-
abstract class RestApiTest extends AnyFunSuite with ScalaFutures {
18+
abstract class RestApiTest extends AnyFunSuite with ScalaFutures with BeforeAndAfterEach {
19+
implicit def scheduler: Scheduler = Scheduler.global
20+
1821
protected final val MaxConnections: Int = 1 // to timeout quickly
1922
protected final val Connections: Int = 10 // > MaxConnections
2023
protected final val CallTimeout: FiniteDuration = 300.millis // << idle timeout
24+
protected final val IdleTimout: FiniteDuration = CallTimeout * 100
2125

22-
implicit def scheduler: Scheduler = Scheduler.global
26+
protected val impl: RestTestApi.Impl = new RestTestApi.Impl
2327

24-
private val impl: RestTestApi = RestTestApi.impl()
28+
override protected def beforeEach(): Unit = {
29+
super.beforeEach()
30+
impl.resetCounter()
31+
}
2532

2633
final val serverHandle: RawRest.HandleRequest =
2734
RawRest.asHandleRequest[RestTestApi](impl)
@@ -41,9 +48,6 @@ abstract class RestApiTest extends AnyFunSuite with ScalaFutures {
4148
case arr: Array[_] => IArraySeq.empty[AnyRef] ++ arr.iterator.map(mkDeep)
4249
case _ => value
4350
}
44-
45-
def getNeverGetCounter(): Int = impl.neverGetCounter.get()
46-
def resetNeverGetCounter(): Unit = impl.neverGetCounter.set(0)
4751
}
4852

4953
trait RestApiTestScenarios extends RestApiTest {
@@ -107,24 +111,22 @@ trait RestApiTestScenarios extends RestApiTest {
107111
}
108112

109113
test("close connection on monix task timeout") {
110-
resetNeverGetCounter()
111114
Task
112115
.traverse(List.range(0, Connections))(_ => Task.deferFuture(proxy.neverGet).timeout(CallTimeout).failed)
113-
.map(_ => assertResult(expected = Connections)(actual = getNeverGetCounter())) // neverGet should be called Connections times
116+
.map(_ => assertResult(expected = Connections)(actual = impl.counterValue())) // neverGet should be called Connections times
114117
.runToFuture
115118
.futureValue
116119
}
117120

118121
test("close connection on monix task cancellation") {
119-
resetNeverGetCounter()
120122
Task
121123
.traverse(List.range(0, Connections)) { i =>
122124
val cancelable = Task.deferFuture(proxy.neverGet).runAsync(_ => ())
123125
Task.sleep(100.millis)
124-
.restartUntil(_ => getNeverGetCounter() >= i)
126+
.restartUntil(_ => impl.counterValue() >= i)
125127
.map(_ => cancelable.cancel())
126128
}
127-
.map(_ => assertResult(expected = Connections)(actual = getNeverGetCounter())) // neverGet should be called Connections times
129+
.map(_ => assertResult(expected = Connections)(actual = impl.counterValue())) // neverGet should be called Connections times
128130
.runToFuture
129131
.futureValue
130132
}

rest/src/test/scala/io/udash/rest/RestTestApi.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import com.avsystem.commons.serialization.json.JsonStringOutput
99
import io.udash.rest.openapi.adjusters.*
1010
import io.udash.rest.openapi.{Header as OASHeader, *}
1111
import io.udash.rest.raw.*
12-
import monix.execution.atomic.Atomic
12+
import monix.execution.atomic.{Atomic, AtomicInt}
1313
import monix.execution.{FutureUtils, Scheduler}
1414

1515
import scala.concurrent.Future
@@ -95,7 +95,6 @@ case class ErrorWrapper[T](error: T)
9595
object ErrorWrapper extends HasPolyGenCodec[ErrorWrapper]
9696

9797
trait RestTestApi {
98-
final val neverGetCounter = Atomic(0)
9998

10099
@GET @group("TrivialGroup") def trivialGet: Future[Unit]
101100
@GET @group("TrivialDescribedGroup") @tagDescription("something") def failingGet: Future[Unit]
@@ -179,13 +178,13 @@ object RestTestApi extends DefaultRestApiCompanion[RestTestApi] {
179178

180179
import Scheduler.Implicits.global
181180

182-
def impl(): RestTestApi = new RestTestApi {
181+
final class Impl extends RestTestApi {
183182
def trivialGet: Future[Unit] = Future.unit
184183
def failingGet: Future[Unit] = Future.failed(HttpErrorException.plain(503, "nie"))
185184
def jsonFailingGet: Future[Unit] = Future.failed(HttpErrorException(503, HttpBody.json(JsonValue(JsonStringOutput.write(ErrorWrapper("nie"))))))
186185
def moreFailingGet: Future[Unit] = throw HttpErrorException.plain(503, "nie")
187186
def neverGet: Future[Unit] = {
188-
neverGetCounter.transform(_ + 1)
187+
counter.increment()
189188
Future.never
190189
}
191190
def wait(millis: Int): Future[String] = FutureUtils.delayedResult(millis.millis)(s"waited $millis ms")
@@ -209,6 +208,11 @@ object RestTestApi extends DefaultRestApiCompanion[RestTestApi] {
209208
def wrappedBinaryEcho(bytes: Bytes): Future[Bytes] = Future.successful(bytes)
210209
def wrappedBody(id: RestEntityId): Future[RestEntityId] = Future.successful(id)
211210
def thirdPartyBody(dur: HasThirdParty): Future[HasThirdParty] = Future.successful(dur)
211+
212+
/** Counter for neverGet calls */
213+
private val counter: AtomicInt = Atomic(0)
214+
def counterValue(): Int = counter.get()
215+
def resetCounter(): Unit = counter.set(0)
212216
}
213217
}
214218

0 commit comments

Comments
 (0)