You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by ma...@apache.org on 2018/09/05 15:25:37 UTC
[incubator-openwhisk] branch master updated: Reuse a container on
ApplicationError. (#3941)
This is an automated email from the ASF dual-hosted git repository.
markusthoemmes pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git
The following commit(s) were added to refs/heads/master by this push:
new 1515e41 Reuse a container on ApplicationError. (#3941)
1515e41 is described below
commit 1515e416d95e3a12888b00a4311c7b9bbb6401d9
Author: tysonnorris <ty...@gmail.com>
AuthorDate: Wed Sep 5 08:25:26 2018 -0700
Reuse a container on ApplicationError. (#3941)
Fixes #3918
Renamed `ActivationResponse.containerError` -> `ActivationResponse.developerError`
* generate ApplicationResponse.containerError during failed init (instead of ApplicationResponse.applicationError)
* timeout on run now produces `ActivationResponse.containerError`
---
.../scala/whisk/core/containerpool/Container.scala | 4 +-
.../scala/whisk/core/entity/ActivationResult.scala | 32 ++++-----
.../whisk/core/containerpool/ContainerProxy.scala | 9 +--
.../core/cli/test/WskRestBasicUsageTests.scala | 10 +--
.../docker/test/DockerContainerTests.scala | 4 +-
.../kubernetes/test/KubernetesContainerTests.scala | 4 +-
.../containerpool/test/ContainerProxyTests.scala | 83 ++++++++++++++++++++--
.../core/controller/test/WebActionsApiTests.scala | 2 +-
.../core/entity/test/ActivationResponseTests.scala | 32 ++++-----
.../whisk/core/limits/ActionLimitsTests.scala | 4 +-
.../whisk/core/limits/MaxActionDurationTests.scala | 2 +-
11 files changed, 130 insertions(+), 56 deletions(-)
diff --git a/common/scala/src/main/scala/whisk/core/containerpool/Container.scala b/common/scala/src/main/scala/whisk/core/containerpool/Container.scala
index dc59b3c..54c8a1b 100644
--- a/common/scala/src/main/scala/whisk/core/containerpool/Container.scala
+++ b/common/scala/src/main/scala/whisk/core/containerpool/Container.scala
@@ -116,7 +116,7 @@ trait Container {
Future.failed(
InitializationError(
result.interval,
- ActivationResponse.applicationError(Messages.timedoutActivation(timeout, true))))
+ ActivationResponse.developerError(Messages.timedoutActivation(timeout, true))))
} else {
Future.failed(
InitializationError(
@@ -153,7 +153,7 @@ trait Container {
}
.map { result =>
val response = if (result.interval.duration >= timeout) {
- ActivationResponse.applicationError(Messages.timedoutActivation(timeout, false))
+ ActivationResponse.developerError(Messages.timedoutActivation(timeout, false))
} else {
ActivationResponse.processRunResponseContent(result.response, logging)
}
diff --git a/common/scala/src/main/scala/whisk/core/entity/ActivationResult.scala b/common/scala/src/main/scala/whisk/core/entity/ActivationResult.scala
index 5f8c815..3448ced 100644
--- a/common/scala/src/main/scala/whisk/core/entity/ActivationResult.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/ActivationResult.scala
@@ -44,7 +44,7 @@ protected[core] case class ActivationResponse private (val statusCode: Int, val
def isSuccess = statusCode == ActivationResponse.Success
def isApplicationError = statusCode == ActivationResponse.ApplicationError
- def isContainerError = statusCode == ActivationResponse.ContainerError
+ def isContainerError = statusCode == ActivationResponse.DeveloperError
def isWhiskError = statusCode == ActivationResponse.WhiskError
def withoutResult = ActivationResponse(statusCode, None)
@@ -57,7 +57,7 @@ protected[core] object ActivationResponse extends DefaultJsonProtocol {
val Success = 0 // action ran successfully and produced a result
val ApplicationError = 1 // action ran but there was an error and it was handled
- val ContainerError = 2 // action ran but failed to handle an error, or action did not run and failed to initialize
+ val DeveloperError = 2 // action ran but failed to handle an error, or action did not run and failed to initialize
val WhiskError = 3 // internal system error
protected[core] def messageForCode(code: Int) = {
@@ -71,7 +71,7 @@ protected[core] object ActivationResponse extends DefaultJsonProtocol {
}
private def error(code: Int, errorValue: JsValue) = {
- require(code == ApplicationError || code == ContainerError || code == WhiskError)
+ require(code == ApplicationError || code == DeveloperError || code == WhiskError)
ActivationResponse(code, Some(JsObject(ERROR_FIELD -> errorValue)))
}
@@ -79,8 +79,8 @@ protected[core] object ActivationResponse extends DefaultJsonProtocol {
protected[core] def applicationError(errorValue: JsValue) = error(ApplicationError, errorValue)
protected[core] def applicationError(errorMsg: String) = error(ApplicationError, JsString(errorMsg))
- protected[core] def containerError(errorValue: JsValue) = error(ContainerError, errorValue)
- protected[core] def containerError(errorMsg: String) = error(ContainerError, JsString(errorMsg))
+ protected[core] def developerError(errorValue: JsValue) = error(DeveloperError, errorValue)
+ protected[core] def developerError(errorMsg: String) = error(DeveloperError, JsString(errorMsg))
protected[core] def whiskError(errorValue: JsValue) = error(WhiskError, errorValue)
protected[core] def whiskError(errorMsg: String) = error(WhiskError, JsString(errorMsg))
@@ -148,21 +148,21 @@ protected[core] object ActivationResponse extends DefaultJsonProtocol {
// If the response is a JSON object container an error field, accept it as the response error.
val errorOpt = fields.get(ERROR_FIELD)
val errorContent = errorOpt getOrElse invalidInitResponse(str).toJson
- containerError(errorContent)
+ developerError(errorContent)
case _ =>
- containerError(invalidInitResponse(str))
+ developerError(invalidInitResponse(str))
}
case Some((length, maxlength)) =>
- containerError(truncatedResponse(str, length, maxlength))
+ developerError(truncatedResponse(str, length, maxlength))
}
case Left(_: MemoryExhausted) =>
- containerError(memoryExhausted)
+ developerError(memoryExhausted)
case Left(e) =>
// This indicates a terminal failure in the container (it exited prematurely).
- containerError(abnormalInitialization)
+ developerError(abnormalInitialization)
}
}
@@ -194,29 +194,29 @@ protected[core] object ActivationResponse extends DefaultJsonProtocol {
// Any non-200 code is treated as a container failure. We still need to check whether
// there was a useful error message in there.
val errorContent = errorOpt getOrElse invalidRunResponse(str).toJson
- containerError(errorContent)
+ developerError(errorContent)
}
case scala.util.Success(notAnObj) =>
// This should affect only blackbox containers, since our own containers should already test for that.
- containerError(invalidRunResponse(str))
+ developerError(invalidRunResponse(str))
case scala.util.Failure(t) =>
// This should affect only blackbox containers, since our own containers should already test for that.
logger.warn(this, s"response did not json parse: '$str' led to $t")
- containerError(invalidRunResponse(str))
+ developerError(invalidRunResponse(str))
}
case Some((length, maxlength)) =>
- containerError(truncatedResponse(str, length, maxlength))
+ developerError(truncatedResponse(str, length, maxlength))
}
case Left(_: MemoryExhausted) =>
- containerError(memoryExhausted)
+ developerError(memoryExhausted)
case Left(e) =>
// This indicates a terminal failure in the container (it exited prematurely).
- containerError(abnormalRun)
+ developerError(abnormalRun)
}
}
diff --git a/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala b/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala
index 0ddd666..b34ce58 100644
--- a/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala
+++ b/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala
@@ -154,7 +154,7 @@ class ContainerProxy(
// the failure is either the system fault, or for docker actions, the application/developer fault
val response = t match {
case WhiskContainerStartupError(msg) => ActivationResponse.whiskError(msg)
- case BlackboxStartupError(msg) => ActivationResponse.applicationError(msg)
+ case BlackboxStartupError(msg) => ActivationResponse.developerError(msg)
case _ => ActivationResponse.whiskError(Messages.resourceProvisionError)
}
val context = UserContext(job.msg.user)
@@ -423,9 +423,10 @@ class ContainerProxy(
// Disambiguate activation errors and transform the Either into a failed/successful Future respectively.
activationWithLogs.flatMap {
- case Right(act) if !act.response.isSuccess => Future.failed(ActivationUnsuccessfulError(act))
- case Left(error) => Future.failed(error)
- case Right(act) => Future.successful(act)
+ case Right(act) if !act.response.isSuccess && !act.response.isApplicationError =>
+ Future.failed(ActivationUnsuccessfulError(act))
+ case Left(error) => Future.failed(error)
+ case Right(act) => Future.successful(act)
}
}
}
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskRestBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskRestBasicUsageTests.scala
index a92bcdf..7fd950a 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskRestBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskRestBasicUsageTests.scala
@@ -185,7 +185,7 @@ class WskRestBasicUsageTests extends TestHelpers with WskTestHelpers with WskAct
withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
val response = activation.response
response.result.get.fields("error") shouldBe Messages.abnormalInitialization.toJson
- response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
+ response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
}
}
@@ -199,7 +199,7 @@ class WskRestBasicUsageTests extends TestHelpers with WskTestHelpers with WskAct
withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
val response = activation.response
response.result.get.fields("error") shouldBe Messages.timedoutActivation(3 seconds, true).toJson
- response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+ response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
}
}
@@ -213,7 +213,7 @@ class WskRestBasicUsageTests extends TestHelpers with WskTestHelpers with WskAct
withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
val response = activation.response
response.result.get.fields("error") shouldBe Messages.abnormalRun.toJson
- response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
+ response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
}
}
@@ -285,7 +285,7 @@ class WskRestBasicUsageTests extends TestHelpers with WskTestHelpers with WskAct
val run = wsk.action.invoke(name)
withActivation(wsk.activation, run) { activation =>
- activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+ activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
activation.response.result.get
.fields("error") shouldBe s"Failed to pull container image '$containerName'.".toJson
activation.annotations shouldBe defined
@@ -375,7 +375,7 @@ class WskRestBasicUsageTests extends TestHelpers with WskTestHelpers with WskAct
val hungRun = wsk.action.invoke(name, Map("forceHang" -> true.toJson))
withActivation(wsk.activation, hungRun) { activation =>
// the first action must fail with a timeout error
- activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+ activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
activation.response.result shouldBe Some(
JsObject("error" -> Messages.timedoutActivation(3 seconds, false).toJson))
}
diff --git a/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerTests.scala b/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerTests.scala
index eb3b2ff..f4c7535 100644
--- a/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerTests.scala
+++ b/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerTests.scala
@@ -426,7 +426,7 @@ class DockerContainerTests
val error = the[InitializationError] thrownBy await(init, initTimeout)
error.interval shouldBe interval
- error.response.statusCode shouldBe ActivationResponse.ApplicationError
+ error.response.statusCode shouldBe ActivationResponse.DeveloperError
// assert the finish log is there
val end = LogMarker.parse(logLines.last)
@@ -474,7 +474,7 @@ class DockerContainerTests
}
val runResult = container.run(JsObject.empty, JsObject.empty, runTimeout)
- await(runResult) shouldBe (interval, ActivationResponse.applicationError(
+ await(runResult) shouldBe (interval, ActivationResponse.developerError(
Messages.timedoutActivation(runTimeout, false)))
// assert the finish log is there
diff --git a/tests/src/test/scala/whisk/core/containerpool/kubernetes/test/KubernetesContainerTests.scala b/tests/src/test/scala/whisk/core/containerpool/kubernetes/test/KubernetesContainerTests.scala
index 4214cf7..227d3c9 100644
--- a/tests/src/test/scala/whisk/core/containerpool/kubernetes/test/KubernetesContainerTests.scala
+++ b/tests/src/test/scala/whisk/core/containerpool/kubernetes/test/KubernetesContainerTests.scala
@@ -241,7 +241,7 @@ class KubernetesContainerTests
val error = the[InitializationError] thrownBy await(init, initTimeout)
error.interval shouldBe interval
- error.response.statusCode shouldBe ActivationResponse.ApplicationError
+ error.response.statusCode shouldBe ActivationResponse.DeveloperError
// assert the finish log is there
val end = LogMarker.parse(logLines.last)
@@ -287,7 +287,7 @@ class KubernetesContainerTests
}
val runResult = container.run(JsObject.empty, JsObject.empty, runTimeout)
- await(runResult) shouldBe (interval, ActivationResponse.applicationError(
+ await(runResult) shouldBe (interval, ActivationResponse.developerError(
Messages.timedoutActivation(runTimeout, false)))
// assert the finish log is there
diff --git a/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala b/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
index 4a2a133..da1d8e9 100644
--- a/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
+++ b/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
@@ -80,6 +80,11 @@ class ContainerProxyTests
Interval(now, now.plusMillis(200))
}
+ val errorInterval = {
+ val now = initInterval.end.plusMillis(75) // delay between init and run
+ Interval(now, now.plusMillis(150))
+ }
+
val uuid = UUID()
val message = ActivationMessage(
@@ -386,6 +391,73 @@ class ContainerProxyTests
}
}
+ it should "complete the transaction and reuse the container on a failed run IFF failure was applicationError" in within(
+ timeout) {
+ val container = new TestContainer {
+ override def run(parameters: JsObject, environment: JsObject, timeout: FiniteDuration)(
+ implicit transid: TransactionId): Future[(Interval, ActivationResponse)] = {
+ runCount += 1
+ //every other run fails
+ if (runCount % 2 == 0) {
+ Future.successful((runInterval, ActivationResponse.success()))
+ } else {
+ Future.successful((errorInterval, ActivationResponse.applicationError(("boom"))))
+ }
+ }
+ }
+ val factory = createFactory(Future.successful(container))
+ val acker = createAcker()
+ val store = createStore
+ val collector = createCollector()
+
+ val machine =
+ childActorOf(
+ ContainerProxy
+ .props(factory, acker, store, collector, InvokerInstanceId(0), poolConfig, pauseGrace = timeout))
+ registerCallback(machine)
+ preWarm(machine)
+
+ //first one will fail
+ run(machine, Started)
+
+ // Note that there are no intermediate state changes
+ //second one will succeed
+ run(machine, Ready)
+
+ //With exception of the error on first run, the assertions should be the same as in
+ // `run an action and continue with a next run without pausing the container`
+ awaitAssert {
+ factory.calls should have size 1
+ container.initializeCount shouldBe 1
+ container.runCount shouldBe 2
+ collector.calls should have size 2
+ container.suspendCount shouldBe 0
+ container.destroyCount shouldBe 0
+ acker.calls should have size 2
+ store.calls should have size 2
+
+ val initErrorActivation = acker.calls(0)._2
+ initErrorActivation.duration shouldBe Some((initInterval.duration + errorInterval.duration).toMillis)
+ initErrorActivation.annotations
+ .get(WhiskActivation.initTimeAnnotation)
+ .get
+ .convertTo[Int] shouldBe initInterval.duration.toMillis
+ initErrorActivation.annotations
+ .get(WhiskActivation.waitTimeAnnotation)
+ .get
+ .convertTo[Int] shouldBe
+ Interval(message.transid.meta.start, initInterval.start).duration.toMillis
+
+ val runOnlyActivation = acker.calls(1)._2
+ runOnlyActivation.duration shouldBe Some(runInterval.duration.toMillis)
+ runOnlyActivation.annotations.get(WhiskActivation.initTimeAnnotation) shouldBe empty
+ runOnlyActivation.annotations.get(WhiskActivation.waitTimeAnnotation).get.convertTo[Int] shouldBe {
+ Interval(message.transid.meta.start, runInterval.start).duration.toMillis
+ }
+ }
+
+ }
+
/*
* ERROR CASES
*/
@@ -424,7 +496,7 @@ class ContainerProxyTests
override def initialize(initializer: JsObject,
timeout: FiniteDuration)(implicit transid: TransactionId): Future[Interval] = {
initializeCount += 1
- Future.failed(InitializationError(initInterval, ActivationResponse.applicationError("boom")))
+ Future.failed(InitializationError(initInterval, ActivationResponse.developerError("boom")))
}
}
val factory = createFactory(Future.successful(container))
@@ -449,7 +521,7 @@ class ContainerProxyTests
collector.calls should have size 1
container.destroyCount shouldBe 1
val activation = acker.calls(0)._2
- activation.response shouldBe ActivationResponse.applicationError("boom")
+ activation.response shouldBe ActivationResponse.developerError("boom")
activation.annotations
.get(WhiskActivation.initTimeAnnotation)
.get
@@ -459,12 +531,13 @@ class ContainerProxyTests
}
}
- it should "complete the transaction and destroy the container on a failed run" in within(timeout) {
+ it should "complete the transaction and destroy the container on a failed run IFF failure was containerError" in within(
+ timeout) {
val container = new TestContainer {
override def run(parameters: JsObject, environment: JsObject, timeout: FiniteDuration)(
implicit transid: TransactionId): Future[(Interval, ActivationResponse)] = {
runCount += 1
- Future.successful((initInterval, ActivationResponse.applicationError("boom")))
+ Future.successful((initInterval, ActivationResponse.developerError(("boom"))))
}
}
val factory = createFactory(Future.successful(container))
@@ -488,7 +561,7 @@ class ContainerProxyTests
container.runCount shouldBe 1
collector.calls should have size 1
container.destroyCount shouldBe 1
- acker.calls(0)._2.response shouldBe ActivationResponse.applicationError("boom")
+ acker.calls(0)._2.response shouldBe ActivationResponse.developerError("boom")
store.calls should have size 1
}
}
diff --git a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
index a0acf18..ba9e2cc 100644
--- a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
@@ -286,7 +286,7 @@ trait WebActionsApiBaseTests extends ControllerTestCommon with BeforeAndAfterEac
r.fields.get("application_error").map { e =>
ActivationResponse.applicationError(e)
} orElse r.fields.get("developer_error").map { e =>
- ActivationResponse.containerError(e)
+ ActivationResponse.developerError(e)
} orElse r.fields.get("whisk_error").map { e =>
ActivationResponse.whiskError(e)
} orElse None // for clarity
diff --git a/tests/src/test/scala/whisk/core/entity/test/ActivationResponseTests.scala b/tests/src/test/scala/whisk/core/entity/test/ActivationResponseTests.scala
index 78dd296..bbc5257 100644
--- a/tests/src/test/scala/whisk/core/entity/test/ActivationResponseTests.scala
+++ b/tests/src/test/scala/whisk/core/entity/test/ActivationResponseTests.scala
@@ -43,14 +43,14 @@ class ActivationResponseTests extends FlatSpec with Matchers {
{
val response = ContainerResponse(okStatus = false, m.take(max.toBytes.toInt - 1), Some(m.length.B, max))
val init = processInitResponseContent(Right(response), logger)
- init.statusCode shouldBe ContainerError
+ init.statusCode shouldBe DeveloperError
init.result.get.asJsObject
.fields(ERROR_FIELD) shouldBe truncatedResponse(response.entity, m.length.B, max).toJson
}
{
val response = ContainerResponse(okStatus = true, m.take(max.toBytes.toInt - 1), Some(m.length.B, max))
val run = processRunResponseContent(Right(response), logger)
- run.statusCode shouldBe ContainerError
+ run.statusCode shouldBe DeveloperError
run.result.get.asJsObject
.fields(ERROR_FIELD) shouldBe truncatedResponse(response.entity, m.length.B, max).toJson
}
@@ -62,7 +62,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
.map(Left(_))
.foreach { e =>
val ar = processInitResponseContent(e, logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe abnormalInitialization.toJson
}
}
@@ -70,7 +70,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed init that responds with null string" in {
val response = ContainerResponse(okStatus = false, null)
val ar = processInitResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidInitResponse(response.entity).toJson
ar.result.get.toString should not include regex("null")
}
@@ -78,7 +78,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed init that responds with empty string" in {
val response = ContainerResponse(okStatus = false, "")
val ar = processInitResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidInitResponse(response.entity).toJson
ar.result.get.asJsObject.fields(ERROR_FIELD).toString.endsWith(".\"") shouldBe true
}
@@ -86,7 +86,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed init that responds with non-empty string" in {
val response = ContainerResponse(okStatus = false, "string")
val ar = processInitResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidInitResponse(response.entity).toJson
ar.result.get.toString should include(response.entity)
}
@@ -94,7 +94,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed init that responds with JSON string not object" in {
val response = ContainerResponse(okStatus = false, Vector(1).toJson.compactPrint)
val ar = processInitResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidInitResponse(response.entity).toJson
ar.result.get.toString should include(response.entity)
}
@@ -102,14 +102,14 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed init that responds with JSON object containing error" in {
val response = ContainerResponse(okStatus = false, Map(ERROR_FIELD -> "foobar").toJson.compactPrint)
val ar = processInitResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get shouldBe response.entity.parseJson
}
it should "interpret failed init that responds with JSON object" in {
val response = ContainerResponse(okStatus = false, Map("foobar" -> "baz").toJson.compactPrint)
val ar = processInitResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidInitResponse(response.entity).toJson
ar.result.get.toString should include("baz")
}
@@ -126,7 +126,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
.map(Left(_))
.foreach { e =>
val ar = processRunResponseContent(e, logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe abnormalRun.toJson
}
}
@@ -134,7 +134,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed run that responds with null string" in {
val response = ContainerResponse(okStatus = false, null)
val ar = processRunResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidRunResponse(response.entity).toJson
ar.result.get.toString should not include regex("null")
}
@@ -142,7 +142,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed run that responds with empty string" in {
val response = ContainerResponse(okStatus = false, "")
val ar = processRunResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidRunResponse(response.entity).toJson
ar.result.get.asJsObject.fields(ERROR_FIELD).toString.endsWith(".\"") shouldBe true
}
@@ -150,7 +150,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed run that responds with non-empty string" in {
val response = ContainerResponse(okStatus = false, "string")
val ar = processRunResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidRunResponse(response.entity).toJson
ar.result.get.toString should include(response.entity)
}
@@ -158,7 +158,7 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed run that responds with JSON string not object" in {
val response = ContainerResponse(okStatus = false, Vector(1).toJson.compactPrint)
val ar = processRunResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidRunResponse(response.entity).toJson
ar.result.get.toString should include(response.entity)
}
@@ -166,14 +166,14 @@ class ActivationResponseTests extends FlatSpec with Matchers {
it should "interpret failed run that responds with JSON object containing error" in {
val response = ContainerResponse(okStatus = false, Map(ERROR_FIELD -> "foobar").toJson.compactPrint)
val ar = processRunResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get shouldBe response.entity.parseJson
}
it should "interpret failed run that responds with JSON object" in {
val response = ContainerResponse(okStatus = false, Map("foobar" -> "baz").toJson.compactPrint)
val ar = processRunResponseContent(Right(response), logger)
- ar.statusCode shouldBe ContainerError
+ ar.statusCode shouldBe DeveloperError
ar.result.get.asJsObject.fields(ERROR_FIELD) shouldBe invalidRunResponse(response.entity).toJson
ar.result.get.toString should include("baz")
}
diff --git a/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala b/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala
index bd78db3..f2a759b 100644
--- a/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala
+++ b/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala
@@ -185,7 +185,7 @@ class ActionLimitsTests extends TestHelpers with WskTestHelpers with WskActorSys
val run = wsk.action.invoke(name, Map("sleepTimeInMs" -> allowedActionDuration.plus(1 second).toMillis.toJson))
withActivation(wsk.activation, run) { result =>
withClue("Activation result not as expected:") {
- result.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+ result.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
result.response.result.get.fields("error") shouldBe {
Messages.timedoutActivation(allowedActionDuration, init = false).toJson
}
@@ -272,7 +272,7 @@ class ActionLimitsTests extends TestHelpers with WskTestHelpers with WskActorSys
def checkResponse(activation: ActivationResult) = {
val response = activation.response
response.success shouldBe false
- response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
+ response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
val msg = response.result.get.fields(ActivationResponse.ERROR_FIELD).convertTo[String]
val expected = Messages.truncatedResponse((allowedSize + 10).B, allowedSize.B)
withClue(s"is: ${msg.take(expected.length)}\nexpected: $expected") {
diff --git a/tests/src/test/scala/whisk/core/limits/MaxActionDurationTests.scala b/tests/src/test/scala/whisk/core/limits/MaxActionDurationTests.scala
index 1a854f1..591c8a9 100644
--- a/tests/src/test/scala/whisk/core/limits/MaxActionDurationTests.scala
+++ b/tests/src/test/scala/whisk/core/limits/MaxActionDurationTests.scala
@@ -86,7 +86,7 @@ class MaxActionDurationTests extends TestHelpers with WskTestHelpers with WskAct
pollPeriod = 1.minute,
totalWait = TimeLimit.MAX_DURATION + 2.minutes) { activation =>
withClue("Activation result not as expected:") {
- activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+ activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.DeveloperError)
activation.response.result shouldBe Some(
JsObject("error" -> Messages.timedoutActivation(TimeLimit.MAX_DURATION, init = false).toJson))
activation.duration.toInt should be >= TimeLimit.MAX_DURATION.toMillis.toInt