@@ -24,7 +24,8 @@ import akka.stream.ActorMaterializer
24
24
import akka .testkit .{TestKit , TestProbe }
25
25
import common .StreamLogging
26
26
import org .apache .kafka .clients .producer .RecordMetadata
27
- import org .apache .openwhisk .common .TransactionId
27
+ import org .apache .openwhisk .common .{Logging , TransactionId }
28
+ import org .apache .openwhisk .core .{WarmUp , WhiskConfig }
28
29
import org .apache .openwhisk .core .connector .ContainerCreationError ._
29
30
import org .apache .openwhisk .core .connector ._
30
31
import org .apache .openwhisk .core .connector .test .TestConnector
@@ -34,6 +35,7 @@ import org.apache.openwhisk.core.entity.ExecManifest.{ImageName, RuntimeManifest
34
35
import org .apache .openwhisk .core .entity ._
35
36
import org .apache .openwhisk .core .entity .size ._
36
37
import org .apache .openwhisk .core .entity .test .ExecHelpers
38
+ import org .apache .openwhisk .core .invoker .ContainerMessageConsumer
37
39
import org .apache .openwhisk .http .Messages
38
40
import org .apache .openwhisk .utils .{retry => utilRetry }
39
41
import org .junit .runner .RunWith
@@ -43,10 +45,11 @@ import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach, FlatSpecLike, Match
43
45
44
46
import scala .concurrent .Future
45
47
import scala .concurrent .duration ._
48
+ import scala .util .Try
46
49
47
50
@ RunWith (classOf [JUnitRunner ])
48
51
class ContainerMessageConsumerTests
49
- extends TestKit (ActorSystem (" ContainerMessageConsumer" ))
52
+ extends TestKit (ActorSystem (" ContainerMessageConsumer" ))
50
53
with FlatSpecLike
51
54
with Matchers
52
55
with BeforeAndAfterEach
@@ -67,7 +70,16 @@ class ContainerMessageConsumerTests
67
70
super .afterAll()
68
71
}
69
72
73
+ private val whiskConfig = new WhiskConfig (
74
+ Map (
75
+ WhiskConfig .actionInvokePerMinuteLimit -> null ,
76
+ WhiskConfig .triggerFirePerMinuteLimit -> null ,
77
+ WhiskConfig .actionInvokeConcurrentLimit -> null ,
78
+ WhiskConfig .runtimesManifest -> null ,
79
+ WhiskConfig .actionSequenceMaxLimit -> null ))
80
+
70
81
private val entityStore = WhiskEntityStore .datastore()
82
+ private val producer = stub[MessageProducer ]
71
83
72
84
private val defaultUserMemory : ByteSize = 1024 .MB
73
85
private val invokerInstance = InvokerInstanceId (0 , userMemory = defaultUserMemory)
@@ -83,6 +95,27 @@ class ContainerMessageConsumerTests
83
95
cleanup()
84
96
}
85
97
98
+ private def fakeMessageProvider (consumer : TestConnector ): MessagingProvider = {
99
+ new MessagingProvider {
100
+ override def getConsumer (
101
+ whiskConfig : WhiskConfig ,
102
+ groupId : String ,
103
+ topic : String ,
104
+ maxPeek : Int ,
105
+ maxPollInterval : FiniteDuration )(implicit logging : Logging , actorSystem : ActorSystem ): MessageConsumer =
106
+ consumer
107
+
108
+ override def getProducer (config : WhiskConfig , maxRequestSize : Option [ByteSize ])(
109
+ implicit logging : Logging ,
110
+ actorSystem : ActorSystem ): MessageProducer = consumer.getProducer()
111
+
112
+ override def ensureTopic (config : WhiskConfig ,
113
+ topic : String ,
114
+ topicConfig : String ,
115
+ maxMessageBytes : Option [ByteSize ])(implicit logging : Logging ): Try [Unit ] = Try {}
116
+ }
117
+ }
118
+
86
119
def sendAckToScheduler (producer : MessageProducer )(schedulerInstanceId : SchedulerInstanceId ,
87
120
ackMessage : ContainerCreationAckMessage ): Future [RecordMetadata ] = {
88
121
val topic = s " creationAck ${schedulerInstanceId.asString}"
@@ -110,6 +143,18 @@ class ContainerMessageConsumerTests
110
143
it should " forward ContainerCreationMessage to containerPool" in {
111
144
val pool = TestProbe ()
112
145
val mockConsumer = new TestConnector (" fakeTopic" , 4 , true )
146
+ val msgProvider = fakeMessageProvider(mockConsumer)
147
+
148
+ val consumer =
149
+ new ContainerMessageConsumer (
150
+ invokerInstance,
151
+ pool.ref,
152
+ entityStore,
153
+ whiskConfig,
154
+ msgProvider,
155
+ 200 .milliseconds,
156
+ 500 ,
157
+ sendAckToScheduler(producer))
113
158
114
159
val exec = CodeExecAsString (RuntimeManifest (" nodejs:10" , ImageName (" testImage" )), " testCode" , None )
115
160
val action =
@@ -150,10 +195,22 @@ class ContainerMessageConsumerTests
150
195
it should " send ack(failed) to scheduler when failed to get action from DB " in {
151
196
val pool = TestProbe ()
152
197
val creationConsumer = new TestConnector (" creation" , 4 , true )
198
+ val msgProvider = fakeMessageProvider(creationConsumer)
153
199
154
200
val ackTopic = " ack"
155
201
val ackConsumer = new TestConnector (ackTopic, 4 , true )
156
202
203
+ val consumer =
204
+ new ContainerMessageConsumer (
205
+ invokerInstance,
206
+ pool.ref,
207
+ entityStore,
208
+ whiskConfig,
209
+ msgProvider,
210
+ 200 .milliseconds,
211
+ 500 ,
212
+ sendAckToScheduler(ackConsumer.getProducer()))
213
+
157
214
val exec = CodeExecAsString (RuntimeManifest (" nodejs:10" , ImageName (" testImage" )), " testCode" , None )
158
215
val whiskAction =
159
216
WhiskAction (EntityPath (" testns" ), EntityName (" testAction2" ), exec, limits = ActionLimits (TimeLimit (1 .minute)))
@@ -213,4 +270,59 @@ class ContainerMessageConsumerTests
213
270
pool.expectNoMessage(2 .seconds)
214
271
}
215
272
}
273
+
274
+ it should " drop messages of warm-up action" in {
275
+ val pool = TestProbe ()
276
+ val mockConsumer = new TestConnector (" fakeTopic" , 4 , true )
277
+ val msgProvider = fakeMessageProvider(mockConsumer)
278
+
279
+ val consumer =
280
+ new ContainerMessageConsumer (
281
+ invokerInstance,
282
+ pool.ref,
283
+ entityStore,
284
+ whiskConfig,
285
+ msgProvider,
286
+ 200 .milliseconds,
287
+ 500 ,
288
+ sendAckToScheduler(producer))
289
+
290
+ val exec = CodeExecAsString (RuntimeManifest (" nodejs:10" , ImageName (" testImage" )), " testCode" , None )
291
+ val action =
292
+ WhiskAction (
293
+ WarmUp .warmUpAction.namespace.toPath,
294
+ WarmUp .warmUpAction.name,
295
+ exec,
296
+ limits = ActionLimits (TimeLimit (1 .minute)))
297
+ val doc = put(entityStore, action)
298
+ val execMetadata =
299
+ CodeExecMetaDataAsString (exec.manifest, entryPoint = exec.entryPoint)
300
+
301
+ val actionMetadata =
302
+ WhiskActionMetaData (
303
+ action.namespace,
304
+ action.name,
305
+ execMetadata,
306
+ action.parameters,
307
+ action.limits,
308
+ action.version,
309
+ action.publish,
310
+ action.annotations)
311
+
312
+ val msg =
313
+ ContainerCreationMessage (
314
+ transId,
315
+ invocationNamespace.asString,
316
+ action.fullyQualifiedName(false ),
317
+ DocRevision .empty,
318
+ actionMetadata,
319
+ schedulerInstanceId,
320
+ schedulerHost,
321
+ rpcPort,
322
+ creationId = creationId)
323
+
324
+ mockConsumer.send(msg)
325
+
326
+ pool.expectNoMessage(1 .seconds)
327
+ }
216
328
}
0 commit comments