Skip to content

Commit fa77904

Browse files
committed
Fix test cases.
1 parent 227f3ac commit fa77904

File tree

2 files changed

+53
-64
lines changed

2 files changed

+53
-64
lines changed

tests/src/test/scala/org/apache/openwhisk/core/scheduler/queue/test/MemoryQueueFlowTests.scala

Lines changed: 52 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import spray.json.{JsObject, JsString}
4747
import java.time.Instant
4848
import scala.collection.immutable.Queue
4949
import scala.concurrent.Future
50-
import scala.concurrent.duration.DurationInt
50+
import scala.concurrent.duration.{DurationInt, FiniteDuration, MILLISECONDS}
5151
import scala.language.postfixOps
5252

5353
@RunWith(classOf[JUnitRunner])
@@ -74,7 +74,6 @@ class MemoryQueueFlowTests
7474

7575
behavior of "MemoryQueueFlow"
7676

77-
// this is 1. normal case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
7877
it should "normally be created and handle an activation and became idle an finally removed" in {
7978
val mockEtcdClient = mock[EtcdClient]
8079
val parent = TestProbe()
@@ -168,7 +167,6 @@ class MemoryQueueFlowTests
168167
probe.expectTerminated(fsm, 10.seconds)
169168
}
170169

171-
// this is 1-2. normal case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
172170
it should "became Idle and Running again if a message arrives" in {
173171
val mockEtcdClient = mock[EtcdClient]
174172
val parent = TestProbe()
@@ -282,7 +280,6 @@ class MemoryQueueFlowTests
282280
probe.expectTerminated(fsm, 10.seconds)
283281
}
284282

285-
// this is 2. NamespaceThrottled case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
286283
it should "go to the Flushing state dropping messages when it can't create an initial container" in {
287284
val mockEtcdClient = mock[EtcdClient]
288285
val parent = TestProbe()
@@ -365,7 +362,6 @@ class MemoryQueueFlowTests
365362
probe.expectTerminated(fsm, 10.seconds)
366363
}
367364

368-
// this is 3. NamespaceThrottled case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
369365
it should "go to the NamespaceThrottled state without dropping messages and get back to the Running container" in {
370366
val mockEtcdClient = mock[EtcdClient]
371367
val parent = TestProbe()
@@ -488,7 +484,6 @@ class MemoryQueueFlowTests
488484
probe.expectTerminated(fsm, 10.seconds)
489485
}
490486

491-
// this is 4. ActionThrottled case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
492487
it should "go to the ActionThrottled state when there are too many stale activations including transition to NamespaceThrottling" in {
493488
val mockEtcdClient = mock[EtcdClient]
494489
val parent = TestProbe()
@@ -637,7 +632,6 @@ class MemoryQueueFlowTests
637632
probe.expectTerminated(fsm, 10.seconds)
638633
}
639634

640-
// this is 5. Paused case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
641635
it should "be Flushing when the limit is 0 and restarted back to Running state when the limit is increased" in {
642636
val mockEtcdClient = mock[EtcdClient]
643637
val parent = TestProbe()
@@ -691,26 +685,18 @@ class MemoryQueueFlowTests
691685
expectInitialData(watcher, dataMgmtService)
692686
probe.expectMsg(Transition(fsm, Uninitialized, Running))
693687

694-
awaitAssert({
695-
ackedMessageCount shouldBe 1
696-
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
697-
storedMessageCount shouldBe 1
698-
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
699-
fsm.underlyingActor.queue.length shouldBe 0
700-
}, 5.seconds)
701-
702688
probe.expectMsg(Transition(fsm, Running, Flushing))
689+
// activation received in Flushing state won't be flushed immediately if Flushing state is caused by a whisk error
690+
Thread.sleep(flushGrace.toMillis)
691+
fsm ! messages(1)
703692

704693
awaitAssert({
705-
// in the paused state, all incoming messages should be dropped immediately
706-
fsm ! messages(1)
707-
ackedMessageCount shouldBe 2
694+
ackedMessageCount shouldBe 1
708695
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
709-
storedMessageCount shouldBe 2
696+
storedMessageCount shouldBe 1
710697
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
711-
fsm.underlyingActor.queue.length shouldBe 0
712-
}, 5.seconds)
713-
698+
fsm.underlyingActor.queue.length shouldBe 1
699+
}, FiniteDuration(retentionTimeout, MILLISECONDS))
714700
// limit is increased by an operator
715701
limit = 10
716702

@@ -728,14 +714,12 @@ class MemoryQueueFlowTests
728714
// Queue is now working
729715
probe.expectMsg(Transition(fsm, Flushing, Running))
730716

731-
fsm ! messages(2)
732-
733717
// one container is created
734718
fsm.underlyingActor.namespaceContainerCount.existingContainerNumByNamespace += 1
735719

736720
// only one message is handled
737721
container.send(fsm, getActivation(true, "testContainerId1"))
738-
container.expectMsg(ActivationResponse(Right(messages(2))))
722+
container.expectMsg(ActivationResponse(Right(messages(1))))
739723

740724
// deleting the container from containers set
741725
container.send(fsm, getActivation(false, "testContainerId1"))
@@ -758,7 +742,6 @@ class MemoryQueueFlowTests
758742
probe.expectTerminated(fsm, 10.seconds)
759743
}
760744

761-
// this is 5-2. Paused case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
762745
it should "be Flushing when the limit is 0 and be terminated without recovering" in {
763746
val mockEtcdClient = mock[EtcdClient]
764747
val parent = TestProbe()
@@ -770,7 +753,7 @@ class MemoryQueueFlowTests
770753
system.actorOf(SchedulingDecisionMaker.props(testInvocationNamespace, fqn, schedulingConfig))
771754

772755
// generate 2 activations
773-
val messages = getActivationMessages(3)
756+
val messages = getActivationMessages(2)
774757

775758
val getUserLimit = (_: String) => Future.successful(0)
776759

@@ -804,35 +787,25 @@ class MemoryQueueFlowTests
804787
registerCallback(probe, fsm)
805788

806789
fsm ! Start
790+
fsm ! messages(0)
807791
expectInitialData(watcher, dataMgmtService)
808792
fsm ! testInitialDataStorageResult
809793

810794
probe.expectMsg(Transition(fsm, Uninitialized, Running))
811795

812-
fsm ! messages(0)
813-
awaitAssert({
814-
ackedMessageCount shouldBe 1
815-
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
816-
storedMessageCount shouldBe 1
817-
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
818-
fsm.underlyingActor.queue.length shouldBe 0
819-
}, 5.seconds)
820-
821796
probe.expectMsg(Transition(fsm, Running, Flushing))
822-
823-
// in the paused state, all incoming messages should be dropped immediately
824797
fsm ! messages(1)
825798

799+
// activation received in Flushing state won't be flushed immediately if Flushing state is caused by a whisk error
800+
Thread.sleep(flushGrace.toMillis)
801+
826802
awaitAssert({
827803
ackedMessageCount shouldBe 2
828804
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
829805
storedMessageCount shouldBe 2
830806
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString(namespaceLimitUnderZero)))
831807
fsm.underlyingActor.queue.length shouldBe 0
832-
}, 5.seconds)
833-
834-
// normal termination process
835-
Thread.sleep(flushGrace.toMillis * 2)
808+
}, FiniteDuration(retentionTimeout, MILLISECONDS))
836809

837810
// In this case data clean up happens first.
838811
expectDataCleanUp(watcher, dataMgmtService)
@@ -844,7 +817,6 @@ class MemoryQueueFlowTests
844817
probe.expectTerminated(fsm, 10.seconds)
845818
}
846819

847-
// this is 6. Waiting case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
848820
it should "be the Flushing state when a whisk error happens" in {
849821
val mockEtcdClient = mock[EtcdClient]
850822
val parent = TestProbe()
@@ -921,13 +893,15 @@ class MemoryQueueFlowTests
921893

922894
fsm ! messages(1)
923895

896+
Thread.sleep(flushGrace.toMillis)
897+
924898
awaitAssert({
925899
ackedMessageCount shouldBe 2
926900
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString("whisk error")))
927901
storedMessageCount shouldBe 2
928902
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString("whisk error")))
929903
fsm.underlyingActor.queue.length shouldBe 0
930-
}, 5.seconds)
904+
}, FiniteDuration(retentionTimeout, MILLISECONDS))
931905

932906
Thread.sleep(flushGrace.toMillis * 2)
933907

@@ -941,7 +915,6 @@ class MemoryQueueFlowTests
941915
probe.expectTerminated(fsm, 10.seconds)
942916
}
943917

944-
// this is 6-2. Waiting case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
945918
it should "be the Flushing state when a whisk error happens and be recovered when a container is created" in {
946919
val mockEtcdClient = mock[EtcdClient]
947920
val parent = TestProbe()
@@ -952,6 +925,8 @@ class MemoryQueueFlowTests
952925
system.actorOf(SchedulingDecisionMaker.props(testInvocationNamespace, fqn, schedulingConfig))
953926
val probe = TestProbe()
954927
val container = TestProbe()
928+
// generate 2 activations
929+
val messages = getActivationMessages(2)
955930

956931
expectDurationChecking(mockEsClient, testInvocationNamespace)
957932

@@ -988,36 +963,39 @@ class MemoryQueueFlowTests
988963

989964
probe.expectMsg(Transition(fsm, Uninitialized, Running))
990965

991-
fsm ! message
992-
// any id is fine because it would be overridden
993-
var creationId = CreationId.generate()
966+
fsm ! messages(0)
994967

968+
// Failed to create a container
995969
containerManager.expectMsgPF() {
996970
case ContainerCreation(List(ContainerCreationMessage(_, _, _, _, _, _, _, _, _, id)), _, _) =>
997-
creationId = id
971+
fsm ! FailedCreationJob(id, testInvocationNamespace, fqn, revision, WhiskError, "whisk error")
998972
}
999-
// Failed to create a container
1000-
fsm ! FailedCreationJob(creationId, testInvocationNamespace, fqn, revision, WhiskError, "whisk error")
973+
974+
probe.expectMsg(Transition(fsm, Running, Flushing))
975+
Thread.sleep(1000)
976+
fsm ! messages(1)
977+
978+
// activation received in Flushing state won't be flushed immediately if Flushing state is caused by a whisk error
979+
Thread.sleep(flushGrace.toMillis)
1001980

1002981
awaitAssert({
1003982
ackedMessageCount shouldBe 1
1004983
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString("whisk error")))
1005984
storedMessageCount shouldBe 1
1006985
lastAckedActivationResult.response.result shouldBe Some(JsObject("error" -> JsString("whisk error")))
1007-
fsm.underlyingActor.queue.length shouldBe 0
1008-
}, 5.seconds)
986+
fsm.underlyingActor.queue.length shouldBe 1
987+
}, FiniteDuration(retentionTimeout, MILLISECONDS))
1009988

1010-
probe.expectMsg(Transition(fsm, Running, Flushing))
1011-
1012-
// Failed to create a container
1013-
fsm ! SuccessfulCreationJob(creationId, testInvocationNamespace, fqn, revision)
989+
// Succeed to create a container
990+
containerManager.expectMsgPF() {
991+
case ContainerCreation(List(ContainerCreationMessage(_, _, _, _, _, _, _, _, _, id)), _, _) =>
992+
fsm ! SuccessfulCreationJob(id, testInvocationNamespace, fqn, revision)
993+
}
1014994

1015995
probe.expectMsg(Transition(fsm, Flushing, Running))
1016996

1017-
fsm ! message
1018-
1019997
container.send(fsm, getActivation())
1020-
container.expectMsg(ActivationResponse(Right(message)))
998+
container.expectMsg(ActivationResponse(Right(messages(1))))
1021999

10221000
// deleting the container from containers set
10231001
container.send(fsm, getActivation(false))
@@ -1039,7 +1017,6 @@ class MemoryQueueFlowTests
10391017
probe.expectTerminated(fsm, 10.seconds)
10401018
}
10411019

1042-
// this is 7. Flushing case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
10431020
it should "be the Flushing state when a developer error happens" in {
10441021
val mockEtcdClient = mock[EtcdClient]
10451022
val parent = TestProbe()
@@ -1143,7 +1120,6 @@ class MemoryQueueFlowTests
11431120
probe.expectTerminated(fsm, 10.seconds)
11441121
}
11451122

1146-
// this is 8. GracefulShuttingDown case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
11471123
it should "be gracefully terminated when it receives a GracefulShutDown message" in {
11481124
val mockEtcdClient = mock[EtcdClient]
11491125
val parent = TestProbe()
@@ -1250,7 +1226,6 @@ class MemoryQueueFlowTests
12501226
probe.expectTerminated(fsm, 10.seconds)
12511227
}
12521228

1253-
// this is 10. deprecated case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
12541229
it should "be deprecated when a new queue supersedes it." in {
12551230
// GracefulShuttingDown is not applicable
12561231
val allStates = List(Running, Idle, Flushing, ActionThrottled, NamespaceThrottled, Removing, Removed)
@@ -1335,7 +1310,6 @@ class MemoryQueueFlowTests
13351310
}
13361311
}
13371312

1338-
// this is 10-2. deprecated case in https://yobi.navercorp.com/Lambda-dev/posts/240?referrerId=-2099518320#1612223450057
13391313
it should "be deprecated and stops even if the queue manager could not respond." in {
13401314
// GracefulShuttingDown is not applicable
13411315
val allStates = List(Running, Idle, Flushing, ActionThrottled, NamespaceThrottled, Removing, Removed)
@@ -1564,6 +1538,20 @@ class MemoryQueueFlowTests
15641538
fsm ! QueueRemovedCompleted
15651539
probe.expectTerminated(fsm, 10.seconds)
15661540

1541+
case Flushing =>
1542+
// queue is stale and will be removed
1543+
parent.expectMsg(staleQueueRemovedMsg)
1544+
probe.expectMsg(Transition(fsm, state, Removed))
1545+
1546+
fsm ! QueueRemovedCompleted
1547+
1548+
Thread.sleep(gracefulShutdownTimeout.toMillis)
1549+
1550+
watcher.expectMsgAllOf(
1551+
UnwatchEndpoint(inProgressContainerKey, isPrefix = true, watcherName),
1552+
UnwatchEndpoint(existingContainerKey, isPrefix = true, watcherName),
1553+
UnwatchEndpoint(leaderKey, isPrefix = false, watcherName))
1554+
15671555
case _ =>
15681556
parent.expectMsg(staleQueueRemovedMsg)
15691557
parent.expectMsg(message)

tests/src/test/scala/org/apache/openwhisk/core/scheduler/queue/test/MemoryQueueTestsFixture.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class MemoryQueueTestsFixture
158158
val idleGrace = queueConfig.idleGrace
159159
val stopGrace = queueConfig.stopGrace
160160
val flushGrace = queueConfig.flushGrace
161+
val retentionTimeout = queueConfig.maxRetentionMs
161162
val blackboxTimeout = queueConfig.maxBlackboxRetentionMs
162163
val gracefulShutdownTimeout = queueConfig.gracefulShutdownTimeout
163164
val testRetentionSize = queueConfig.maxRetentionSize

0 commit comments

Comments
 (0)