我正在尝试追踪自定义Flow中的一个错误,其中有额外的请求上行。我写了一个测试用例,考虑到我所看到的行为和日志记录应该失败,但它没有。
然后我做了一个微不足道的Flow,有一个明显的额外拉力,但测试仍然没有失败。
以下是一个例子:
class EagerFlow extends GraphStage[FlowShape[String, String]] {
val in: Inlet[String] = Inlet("EagerFlow.in")
val out: Outlet[String] = Outlet("EagerFlow.out")
override def shape: FlowShape[String, String] = FlowShape(in, out)
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape) {
setHandler(in, new InHandler {
override def onPush() = {
println("EagerFlow.in.onPush")
println("EagerFlow.out.push")
push(out, grab(in))
println("EagerFlow.in.pull")
pull(in)
}
})
setHandler(out, new OutHandler {
override def onPull() = {
println("EagerFlow.out.onPull")
println("EagerFlow.in.pull")
pull(in)
}
})
}
}
这是一个应该通过的测试,即确认有额外的请求。
"Eager Flow" should "pull on every push" in {
val sourceProbe = TestSource.probe[String]
val sinkProbe = TestSink.probe[String]
val eagerFlow = Flow.fromGraph(new EagerFlow)
val (source, sink) = sourceProbe.
via(eagerFlow).
toMat(sinkProbe)(Keep.both).
run
sink.request(1)
source.expectRequest()
source.expectNoMsg()
source.sendNext("hello")
sink.expectNext()
source.expectRequest()
}
在标准输出中,您可以看到:
0C3E08A8 PULL DownstreamBoundary -> TestSpec$EagerFlow@1d154180 (TestSpec$EagerFlow$$anon$4$$anon$6@7e62ecbd) [TestSpec$EagerFlow$$anon$4@36904dd4]
EagerFlow.out.onPull
EagerFlow.in.pull
0C3E08A8 PULL TestSpec$EagerFlow@1d154180 -> UpstreamBoundary (BatchingActorInputBoundary(id=0, fill=0/16, completed=false, canceled=false)) [UpstreamBoundary]
EagerFlow.in.onPush
EagerFlow.out.push
EagerFlow.in.pull
0C3E08A8 PULL TestSpec$EagerFlow@1d154180 -> UpstreamBoundary (BatchingActorInputBoundary(id=0, fill=0/16, completed=false, canceled=false)) [UpstreamBoundary]
assertion failed: timeout (3 seconds) during expectMsg:
java.lang.AssertionError: assertion failed: timeout (3 seconds) during expectMsg:
at scala.Predef$.assert(Predef.scala:170)
at akka.testkit.TestKitBase$class.expectMsgPF(TestKit.scala:368)
at akka.testkit.TestKit.expectMsgPF(TestKit.scala:737)
at akka.stream.testkit.StreamTestKit$PublisherProbeSubscription.expectRequest(StreamTestKit.scala:665)
at akka.stream.testkit.TestPublisher$Probe.expectRequest(StreamTestKit.scala:172)
(这是akka.stream.impl.fusing.GraphInterpreter#processEvent
中的调试日志记录,实际上是使用打印点,但实际上是相同的事情)
为什么这种情况会在UpstreamBoundary
停止并且永远不会回到TestSource.probe
?
我有很多测试使用expectNoMsg()
来确保正确的背压,但似乎这些只会给出误报。如果这不起作用,我该如何测试呢?
答案 0 :(得分:1)
要使测试适用,您需要将Flow缓冲区设置为1。
val settings = ActorMaterializerSettings(system)
.withInputBuffer(initialSize = 1, maxSize = 1)
implicit val mat = ActorMaterializer(settings)
默认尺寸为:
# Initial size of buffers used in stream elements
initial-input-buffer-size = 4
# Maximum size of buffers used in stream elements
max-input-buffer-size = 16
这意味着Akka会在您第一次请求时急切地请求并摄取最多16个元素 。有关内部缓冲区的更多信息可以在source找到。