You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/09/05 15:25:35 UTC

[GitHub] markusthoemmes closed pull request #3941: to address #3918, reuse a container on applicationError

markusthoemmes closed pull request #3941: to address #3918, reuse a container on applicationError
URL: https://github.com/apache/incubator-openwhisk/pull/3941
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

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 ff0124e8d8..fe43155ddc 100644
--- a/common/scala/src/main/scala/whisk/core/containerpool/Container.scala
+++ b/common/scala/src/main/scala/whisk/core/containerpool/Container.scala
@@ -105,7 +105,7 @@ trait Container {
           Future.failed(
             InitializationError(
               result.interval,
-              ActivationResponse.applicationError(Messages.timedoutActivation(timeout, true))))
+              ActivationResponse.developerError(Messages.timedoutActivation(timeout, true))))
         } else {
           Future.failed(
             InitializationError(
@@ -142,7 +142,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 5f8c815a7f..3448ced14f 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 0ddd666d92..b34ce587d4 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 a92bcdfcd7..7fd950ad0c 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 1f2ab3245c..a86149aa40 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 bd3c948410..7d7fec2b12 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
@@ -242,7 +242,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)
@@ -288,7 +288,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 4a2a1331fc..da1d8e9ed3 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 a0acf185c7..ba9e2cc17d 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 78dd29642f..bbc525772d 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 bd78db3c1c..f2a759bfd9 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 1a854f1684..591c8a955e 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


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services