[ 
https://issues.apache.org/jira/browse/SCB-769?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16555020#comment-16555020
 ] 

ASF GitHub Bot commented on SCB-769:
------------------------------------

wujimin closed pull request #833: [SCB-769] Fix delay fault injection blocking 
thread
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/833
 
 
   

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/demo/demo-springmvc/springmvc-client/pom.xml 
b/demo/demo-springmvc/springmvc-client/pom.xml
index 45735c655..abd43f0b8 100644
--- a/demo/demo-springmvc/springmvc-client/pom.xml
+++ b/demo/demo-springmvc/springmvc-client/pom.xml
@@ -45,6 +45,10 @@
       <groupId>org.apache.servicecomb</groupId>
       <artifactId>config-cc</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>handler-fault-injection</artifactId>
+    </dependency>
   </dependencies>
 
   <properties>
diff --git 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSpringmvcIntf.java
 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSpringmvcIntf.java
index cb1824ba2..c2f5cc50d 100644
--- 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSpringmvcIntf.java
+++ 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSpringmvcIntf.java
@@ -68,4 +68,8 @@
 
   String checkQueryGenericString(String str, GenericParam<Person> requestBody, 
long num, String data,
       String strExtended, int intExtended);
+
+  String testDelay();
+
+  String testAbort();
 }
diff --git 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
index e417e200c..e243a2f50 100644
--- 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
+++ 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
@@ -24,6 +24,7 @@
 import org.apache.servicecomb.provider.pojo.Invoker;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
 import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.springframework.http.ResponseEntity;
 
 public class TestResponse {
@@ -36,6 +37,8 @@ public TestResponse() {
   public void runRest() {
     checkQueryGenericObject();
     checkQueryGenericString();
+    testDelay();
+    testAbort();
   }
 
   public void runHighway() {
@@ -102,4 +105,29 @@ private void checkQueryGenericString() {
             + "GenericParam{str='str2', num=2, 
data=dataTest}},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}",
         result);
   }
+
+  private void testDelay() {
+    StringBuilder result = new StringBuilder();
+    for (int i = 0; i < 4; ++i) {
+      result.append(intf.testDelay()).append("|");
+    }
+    TestMgr.check("OK|OK|OK|OK|", result.toString());
+  }
+
+  private void testAbort() {
+    StringBuilder result = new StringBuilder();
+    for (int i = 0; i < 4; ++i) {
+      String response;
+      try {
+        response = intf.testAbort();
+      } catch (InvocationException e) {
+        response = e.getMessage();
+      }
+      result.append(response).append("|");
+    }
+    TestMgr.check(
+        "OK|InvocationException: code=421;msg=CommonExceptionData 
[message=aborted by fault inject]|"
+            + "OK|InvocationException: code=421;msg=CommonExceptionData 
[message=aborted by fault inject]|",
+        result.toString());
+  }
 }
diff --git 
a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml 
b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
index a2ff203c6..2290b6ffe 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
+++ b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
@@ -51,7 +51,7 @@ servicecomb:
   handler:
     chain:
       Consumer:
-        default: loadbalance,bizkeeper-consumer
+        default: loadbalance,fault-injection-consumer,bizkeeper-consumer
   tracing:
     enabled: true
     samplingRate: 0.5
@@ -82,7 +82,28 @@ servicecomb:
     name: myDC
     region: my-Region
     availableZone: my-Zone
-
+  governance:
+    Consumer:
+      springmvc:
+        schemas:
+          codeFirst:
+            operations:
+              testDelay:
+                policy:
+                  fault:
+                    protocols:
+                      rest:
+                        delay:
+                          fixedDelay: 10
+                          percent: 50
+              testAbort:
+                policy:
+                  fault:
+                    protocols:
+                      rest:
+                        abort:
+                          httpStatus: 421
+                          percent: 50
   test:
     duplicate1: newer
 
diff --git 
a/demo/demo-springmvc/springmvc-client/src/test/java/org/apache/servicecomb/demo/springmvc/SpringMvcIT.java
 
b/demo/demo-springmvc/springmvc-client/src/test/java/org/apache/servicecomb/demo/springmvc/SpringMvcIT.java
index 5bb6ec8cf..5d610dee9 100644
--- 
a/demo/demo-springmvc/springmvc-client/src/test/java/org/apache/servicecomb/demo/springmvc/SpringMvcIT.java
+++ 
b/demo/demo-springmvc/springmvc-client/src/test/java/org/apache/servicecomb/demo/springmvc/SpringMvcIT.java
@@ -28,7 +28,7 @@
 public class SpringMvcIT {
 
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
     TestMgr.errors().clear();
   }
 
diff --git 
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
 
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
index 6b97de5aa..53b323009 100644
--- 
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
+++ 
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
@@ -500,4 +500,16 @@ public String checkQueryGenericString(String str, 
@RequestBody GenericParam<Pers
     LOGGER.info("checkQueryGenericObject() is called!");
     return "str=" + str + ",generic=" + generic + ",requestBody=" + 
requestBody;
   }
+
+  @GetMapping(path = "/testDelay")
+  public String testDelay() {
+    LOGGER.info("testDelay() is called!");
+    return "OK";
+  }
+
+  @GetMapping(path = "/testAbort")
+  public String testAbort() {
+    LOGGER.info("testAbort() is called!");
+    return "OK";
+  }
 }
diff --git 
a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
 
b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
index 1135aa6e1..26044606d 100644
--- 
a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
+++ 
b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
@@ -25,39 +25,41 @@
 import org.slf4j.LoggerFactory;
 
 public class AbortFault extends AbstractFault {
+
   private static final Logger LOGGER = 
LoggerFactory.getLogger(AbortFault.class);
 
+  public static final String ABORTED_ERROR_MSG = "aborted by fault inject";
+
   @Override
-  public void injectFault(Invocation invocation, FaultParam faultParam, 
AsyncResponse asynResponse) {
-    // get the config values related to abort.
-    int abortPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
-        "abort.percent");
+  public void injectFault(Invocation invocation, FaultParam faultParam, 
AsyncResponse asyncResponse) {
+    if (!shouldAbort(invocation, faultParam)) {
+      asyncResponse.success(SUCCESS_RESPONSE);
+      return;
+    }
 
-    if (abortPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
-      LOGGER.debug("Fault injection: Abort percentage is not configured");
-      asynResponse.success("success");
+    // get the config values related to abort percentage.
+    int errorCode = FaultInjectionUtil.getFaultInjectionConfig(invocation, 
"abort.httpStatus");
+    if (errorCode == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+      LOGGER.debug("Fault injection: Abort error code is not configured");
+      asyncResponse.success(SUCCESS_RESPONSE);
       return;
     }
 
-    // check fault abort condition.
-    boolean isAbort = 
FaultInjectionUtil.isFaultNeedToInject(faultParam.getReqCount(), abortPercent);
-    if (isAbort) {
-      // get the config values related to abort percentage.
-      int errorCode = FaultInjectionUtil.getFaultInjectionConfig(invocation,
-          "abort.httpStatus");
+    // if request need to be abort then return failure with given error code
+    CommonExceptionData errorData = new CommonExceptionData(ABORTED_ERROR_MSG);
+    asyncResponse.consumerFail(new InvocationException(errorCode, 
ABORTED_ERROR_MSG, errorData));
+  }
 
-      if (errorCode == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
-        LOGGER.debug("Fault injection: Abort error code is not configured");
-        asynResponse.success("success");
-        return;
-      }
-      // if request need to be abort then return failure with given error code
-      CommonExceptionData errorData = new CommonExceptionData("aborted by 
fault inject");
-      asynResponse.consumerFail(new InvocationException(errorCode, "aborted by 
fault inject", errorData));
-      return;
+  private boolean shouldAbort(Invocation invocation, FaultParam faultParam) {
+    // get the config values related to abort.
+    int abortPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation, 
"abort.percent");
+    if (abortPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+      LOGGER.debug("Fault injection: Abort percentage is not configured");
+      return false;
     }
 
-    asynResponse.success("success");
+    // check fault abort condition.
+    return FaultInjectionUtil.isFaultNeedToInject(faultParam.getReqCount(), 
abortPercent);
   }
 
   @Override
diff --git 
a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
 
b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
index ecbb2e103..38318d2de 100644
--- 
a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
+++ 
b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
@@ -22,7 +22,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import io.vertx.core.Handler;
 import io.vertx.core.Vertx;
 
 public class DelayFault extends AbstractFault {
@@ -35,44 +34,47 @@ public int getOrder() {
 
   @Override
   public void injectFault(Invocation invocation, FaultParam faultParam, 
AsyncResponse asynResponse) {
-    int delayPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
-        "delay.percent");
+    if (!shouldDelay(invocation, faultParam, asynResponse)) {
+      asynResponse.success(SUCCESS_RESPONSE);
+      return;
+    }
 
-    if (delayPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
-      LOGGER.debug("Fault injection: delay percentage is not configured");
-      asynResponse.success("success");
+    LOGGER.debug("Fault injection: delay is added for the request by fault 
inject handler");
+    long delay = FaultInjectionUtil.getFaultInjectionConfig(invocation,
+        "delay.fixedDelay");
+    if (delay == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+      LOGGER.debug("Fault injection: delay is not configured");
+      asynResponse.success(SUCCESS_RESPONSE);
       return;
     }
 
-    // check fault delay condition.
-    boolean isDelay = 
FaultInjectionUtil.isFaultNeedToInject(faultParam.getReqCount(), delayPercent);
-    if (isDelay) {
-      LOGGER.debug("Fault injection: delay is added for the request by fault 
inject handler");
-      long delay = FaultInjectionUtil.getFaultInjectionConfig(invocation,
-          "delay.fixedDelay");
+    executeDelay(faultParam, asynResponse, delay);
+  }
 
-      if (delay == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
-        LOGGER.debug("Fault injection: delay is not configured");
-        asynResponse.success("success");
-        return;
-      }
+  private void executeDelay(FaultParam faultParam, AsyncResponse asynResponse, 
long delay) {
+    Vertx vertx = faultParam.getVertx();
+    if (vertx != null) {
+      vertx.setTimer(delay, timeID -> asynResponse.success(SUCCESS_RESPONSE));
+      return;
+    }
 
-      Vertx vertx = faultParam.getVertx();
-      if (vertx != null) {
-        vertx.setTimer(delay, new Handler<Long>() {
-          @Override
-          public void handle(Long timeID) {
-            asynResponse.success("success");
-          }
-        });
-      } else {
-        try {
-          Thread.sleep(delay);
-        } catch (InterruptedException e) {
-          LOGGER.info("Interrupted exception is received");
-        }
-        asynResponse.success("success");
-      }
+    try {
+      Thread.sleep(delay);
+    } catch (InterruptedException e) {
+      LOGGER.info("Interrupted exception is received");
     }
+    asynResponse.success(SUCCESS_RESPONSE);
+  }
+
+  private boolean shouldDelay(Invocation invocation, FaultParam faultParam, 
AsyncResponse asynResponse) {
+    int delayPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
+        "delay.percent");
+    if (delayPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+      LOGGER.debug("Fault injection: delay percentage is not configured");
+      return false;
+    }
+
+    // check fault delay condition.
+    return FaultInjectionUtil.isFaultNeedToInject(faultParam.getReqCount(), 
delayPercent);
   }
 }
diff --git 
a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
 
b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
index ddc422953..a3f254537 100644
--- 
a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
+++ 
b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
@@ -22,6 +22,8 @@
 
 public interface Fault {
 
+  String SUCCESS_RESPONSE = "success";
+
   int getOrder();
 
   void injectFault(Invocation invocation, FaultParam faultAttributes, 
AsyncResponse asynResponse);
diff --git 
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/AbortFaultTest.java
 
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/AbortFaultTest.java
new file mode 100644
index 000000000..ec4f3c1f4
--- /dev/null
+++ 
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/AbortFaultTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.faultinjection;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.xml.ws.Holder;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.Transport;
+import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
+import org.apache.servicecomb.foundation.vertx.VertxUtils;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.netflix.config.DynamicProperty;
+
+import io.vertx.core.Vertx;
+
+public class AbortFaultTest {
+  private Invocation invocation;
+
+  @Before
+  public void before() {
+    invocation = Mockito.mock(Invocation.class);
+    Transport transport = Mockito.mock(Transport.class);
+    
Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName12");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye4");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema4");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts6");
+  }
+
+  @After
+  public void after() {
+    System.getProperties()
+        
.remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        
.remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus");
+    ArchaiusUtils.resetConfig();
+  }
+
+  @Test
+  public void injectFaultError() {
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus",
 "421");
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.percent",
 "100");
+
+    AbortFault abortFault = new AbortFault();
+    FaultParam faultParam = new FaultParam(1);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<InvocationException> resultHolder = new Holder<>();
+    abortFault.injectFault(invocation, faultParam, response -> 
resultHolder.value = response.getResult());
+
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals("421", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus")
+        .getString());
+    assertEquals("100", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.percent")
+        .getString());
+    assertEquals(1, count.get());
+    assertEquals(421, resultHolder.value.getStatusCode());
+    assertEquals("aborted by fault inject", 
resultHolder.value.getReasonPhrase());
+    assertEquals("CommonExceptionData [message=aborted by fault inject]", 
resultHolder.value.getErrorData().toString());
+  }
+
+  @Test
+  public void injectFaultNoError() {
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus",
 "421");
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.percent",
 "0");
+
+    AbortFault abortFault = new AbortFault();
+    FaultParam faultParam = new FaultParam(1);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<String> resultHolder = new Holder<>();
+    abortFault.injectFault(invocation, faultParam, response -> 
resultHolder.value = response.getResult());
+
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals("421", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus")
+        .getString());
+    assertEquals("0", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.percent")
+        .getString());
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+
+  @Test
+  public void injectFaultNoPercentageConfig() {
+    AbortFault abortFault = new AbortFault();
+    FaultParam faultParam = new FaultParam(1);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<String> resultHolder = new Holder<>();
+    abortFault.injectFault(invocation, faultParam, response -> 
resultHolder.value = response.getResult());
+
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+
+  @Test
+  public void injectFaultNoErrorCodeConfig() {
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.percent",
 "10");
+    AbortFault abortFault = new AbortFault();
+    FaultParam faultParam = new FaultParam(10);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<String> resultHolder = new Holder<>();
+    abortFault.injectFault(invocation, faultParam, response -> 
resultHolder.value = response.getResult());
+
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+}
diff --git 
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/DelayFaultTest.java
 
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/DelayFaultTest.java
new file mode 100644
index 000000000..23521dfd3
--- /dev/null
+++ 
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/DelayFaultTest.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.faultinjection;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.xml.ws.Holder;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.Transport;
+import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
+import org.apache.servicecomb.foundation.vertx.VertxUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.netflix.config.DynamicProperty;
+
+import io.vertx.core.Vertx;
+
+public class DelayFaultTest {
+  private Invocation invocation;
+
+  @Before
+  public void before() {
+    invocation = Mockito.mock(Invocation.class);
+    Transport transport = Mockito.mock(Transport.class);
+    
Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName12");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye4");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema4");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts6");
+  }
+
+  @After
+  public void after() {
+    System.getProperties()
+        
.remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        
.remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent");
+    ArchaiusUtils.resetConfig();
+  }
+
+  @Test
+  public void injectFaultVertxDelay() throws InterruptedException {
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay",
 "10");
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent",
 "100");
+
+    DelayFault delayFault = new DelayFault();
+    FaultParam faultParam = new FaultParam(1);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<String> resultHolder = new Holder<>();
+    CountDownLatch latch = new CountDownLatch(1);
+    delayFault.injectFault(invocation, faultParam, response -> {
+      resultHolder.value = response.getResult();
+      latch.countDown();
+    });
+
+    latch.await(10, TimeUnit.SECONDS);
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals("10", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay")
+        .getString());
+    assertEquals("100", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent")
+        .getString());
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+
+  @Test
+  public void injectFaultSystemDelay() throws InterruptedException {
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay",
 "10");
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent",
 "100");
+
+    DelayFault delayFault = new DelayFault();
+    FaultParam faultParam = new FaultParam(1);
+
+    Holder<String> resultHolder = new Holder<>();
+    CountDownLatch latch = new CountDownLatch(1);
+    delayFault.injectFault(invocation, faultParam, response -> {
+      resultHolder.value = response.getResult();
+      latch.countDown();
+    });
+
+    latch.await(10, TimeUnit.SECONDS);
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals("10", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay")
+        .getString());
+    assertEquals("100", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent")
+        .getString());
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+
+  @Test
+  public void injectFaultNotDelay() throws InterruptedException {
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay",
 "10");
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent",
 "0");
+
+    DelayFault delayFault = new DelayFault();
+    FaultParam faultParam = new FaultParam(1);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<String> resultHolder = new Holder<>();
+    CountDownLatch latch = new CountDownLatch(1);
+    delayFault.injectFault(invocation, faultParam, response -> {
+      resultHolder.value = response.getResult();
+      latch.countDown();
+    });
+
+    latch.await(3, TimeUnit.SECONDS);
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals("10", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay")
+        .getString());
+    assertEquals("0", DynamicProperty
+        
.getInstance("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent")
+        .getString());
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+
+  @Test
+  public void injectFaultNoPercentageConfig() {
+    DelayFault delayFault = new DelayFault();
+    FaultParam faultParam = new FaultParam(1);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<String> resultHolder = new Holder<>();
+    delayFault.injectFault(invocation, faultParam, response -> 
resultHolder.value = response.getResult());
+
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+
+  @Test
+  public void injectFaultNoDelayMsConfig() {
+    
System.setProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent",
 "10");
+    DelayFault delayFault = new DelayFault();
+    FaultParam faultParam = new FaultParam(10);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", 
null);
+    faultParam.setVertx(vertx);
+
+    Holder<String> resultHolder = new Holder<>();
+    delayFault.injectFault(invocation, faultParam, response -> 
resultHolder.value = response.getResult());
+
+    AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals(1, count.get());
+    assertEquals("success", resultHolder.value);
+  }
+}
diff --git 
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
 
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
index 16abe96d8..d71f2ac57 100644
--- 
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
+++ 
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
@@ -18,14 +18,18 @@
 package org.apache.servicecomb.faultinjection;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
 
+import javax.xml.ws.Holder;
+
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.Transport;
 import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
 import org.apache.servicecomb.foundation.vertx.VertxUtils;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.Response;
@@ -59,9 +63,6 @@
 
   boolean isAbort;
 
-  @InjectMocks
-  FaultInjectionHandler faultHandler;
-
   @InjectMocks
   AbortFault abortFault;
 
@@ -75,39 +76,30 @@ public void handle(Response resp) {
     }
   };
 
-
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
+    ArchaiusUtils.resetConfig();
     handler = new FaultInjectionHandler();
-
     invocation = Mockito.mock(Invocation.class);
-
     asyncResp = Mockito.mock(AsyncResponse.class);
-
     operationMeta = Mockito.mock(OperationMeta.class);
-
     transport = Mockito.mock(Transport.class);
     MockitoAnnotations.initMocks(this);
   }
 
   @After
-  public void tearDown() throws Exception {
+  public void tearDown() {
     handler = null;
-
     invocation = null;
-
     asyncResp = null;
-
     operationMeta = null;
-
     transport = null;
+    ArchaiusUtils.resetConfig();
   }
 
   /**
    * Tests the fault injection handler functionality with default values for
    * highway transport.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerHighwayWithDefaultCfg() throws Exception {
@@ -131,8 +123,6 @@ public void testFaultInjectHandlerHighwayWithDefaultCfg() 
throws Exception {
   /**
    * Tests the fault injection handler functionality with default values for 
rest
    * transport.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerRestWithDefaultCfg() throws Exception {
@@ -156,8 +146,6 @@ public void testFaultInjectHandlerRestWithDefaultCfg() 
throws Exception {
   /**
    * Tests the fault injection handler functionality with global configuration
    * with delay/abort condition.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerConfigChangeGlobal() throws Exception {
@@ -185,10 +173,12 @@ public void testFaultInjectHandlerConfigChangeGlobal() 
throws Exception {
     Assert.assertFalse(isDelay);
     Assert.assertFalse(isAbort);
 
-    
System.getProperties().remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        
.remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay");
     
System.getProperties().remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent");
     
System.getProperties().remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.percent");
-    
System.getProperties().remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus");
+    System.getProperties()
+        
.remove("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus");
 
     AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName3");
     assertEquals(2, count.get());
@@ -197,8 +187,6 @@ public void testFaultInjectHandlerConfigChangeGlobal() 
throws Exception {
   /**
    * Tests the fault injection handler functionality with service level 
configuration
    * with delay/abort condition.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerServiceCfgSuccess() throws Exception {
@@ -238,19 +226,21 @@ public void testFaultInjectHandlerServiceCfgSuccess() 
throws Exception {
   /**
    * Tests the fault injection handler functionality with schema level 
configuration
    * with delay/abort condition.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerSchemaCfgSuccess() throws Exception {
 
-    
System.setProperty("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.fixedDelay",
+    System.setProperty(
+        
"servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.fixedDelay",
         "1");
-    
System.setProperty("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.percent",
+    System.setProperty(
+        
"servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.percent",
         "10");
-    
System.setProperty("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.percent",
+    System.setProperty(
+        
"servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.percent",
         "10");
-    
System.setProperty("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.httpStatus",
+    System.setProperty(
+        
"servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.httpStatus",
         "421");
 
     
Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName5");
@@ -272,13 +262,15 @@ public void testFaultInjectHandlerSchemaCfgSuccess() 
throws Exception {
     Assert.assertFalse(isAbort);
 
     System.getProperties()
-        
.remove("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.fixedDelay");
+        .remove(
+            
"servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.fixedDelay");
     System.getProperties()
         
.remove("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.percent");
     System.getProperties()
         
.remove("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.percent");
     System.getProperties()
-        
.remove("servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.httpStatus");
+        .remove(
+            
"servicecomb.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.httpStatus");
 
     AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName5");
     assertEquals(2, count.get());
@@ -287,8 +279,6 @@ public void testFaultInjectHandlerSchemaCfgSuccess() throws 
Exception {
   /**
    * Tests the fault injection handler functionality with operation level 
configuration
    * with delay/abort condition.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerOperationCfgSuccess() throws Exception {
@@ -344,8 +334,6 @@ public void testFaultInjectHandlerOperationCfgSuccess() 
throws Exception {
 
   /**
    * Tests the fault injection handler functionality with configuration change 
event for global level config.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerConfigChangeEvent1() throws Exception {
@@ -386,9 +374,12 @@ public void testFaultInjectHandlerConfigChangeEvent1() 
throws Exception {
     TestFaultInjectUtil
         
.updateProperty("servicecomb.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus",
 421);
 
+    Holder<Boolean> isAsserted = new Holder<>(false);
     handler.handle(invocation, ar -> {
-      assertEquals(true, response.isFailed());
+      isAsserted.value = true;
+      assertTrue(response.isFailed());
     });
+    Assert.assertTrue(isAsserted.value);
 
     System.getProperties()
         .remove(
@@ -409,8 +400,6 @@ public void testFaultInjectHandlerConfigChangeEvent1() 
throws Exception {
 
   /**
    * Tests the fault injection handler functionality with configuration change 
event for operation level config.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerConfigChangeEvent2() throws Exception {
@@ -452,14 +441,17 @@ public void testFaultInjectHandlerConfigChangeEvent2() 
throws Exception {
             
"servicecomb.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.delay.fixedDelay",
             500);
 
+    Holder<Boolean> isAsserted = new Holder<>(false);
     handler.handle(invocation, ar -> {
       //check whether error code return
+      isAsserted.value = true;
       assertEquals(420, response.getStatusCode());
-      assertEquals(true, response.isFailed());
+      assertTrue(response.isFailed());
       long timeNow = System.currentTimeMillis();
       //if really time delay is added it should be greater than 5s.
       Assert.assertTrue((timeNow - timeOld) >= 500);
     });
+    Assert.assertTrue(isAsserted.value);
 
     System.getProperties()
         .remove(
@@ -480,8 +472,6 @@ public void testFaultInjectHandlerConfigChangeEvent2() 
throws Exception {
 
   /**
    * Tests the fault injection handler functionality with configuration change 
event for schema level config.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerConfigChangeEvent3() throws Exception {
@@ -523,23 +513,28 @@ public void testFaultInjectHandlerConfigChangeEvent3() 
throws Exception {
             
"servicecomb.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.fixedDelay",
             500);
 
+    Holder<Boolean> isAsserted = new Holder<>(false);
     handler.handle(invocation, ar -> {
       //check whether error code return, defaut is 421.
+      isAsserted.value = true;
       assertEquals(421, response.getStatusCode());
-      assertEquals(true, response.isFailed());
+      assertTrue(response.isFailed());
       long timeNow = System.currentTimeMillis();
       //if really time delay is added it should be greater than 5s.
       Assert.assertTrue((timeNow - timeOld) >= 500);
     });
+    Assert.assertTrue(isAsserted.value);
 
     System.getProperties()
-        
.remove("servicecomb.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.fixedDelay");
+        .remove(
+            
"servicecomb.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.fixedDelay");
     System.getProperties()
         
.remove("servicecomb.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.percent");
     System.getProperties()
         
.remove("servicecomb.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.abort.percent");
     System.getProperties()
-        
.remove("servicecomb.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.abort.httpStatus");
+        .remove(
+            
"servicecomb.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.abort.httpStatus");
 
     AtomicLong count = 
FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName9");
     assertEquals(3, count.get());
@@ -547,8 +542,6 @@ public void testFaultInjectHandlerConfigChangeEvent3() 
throws Exception {
 
   /**
    * Tests the fault injection handler functionality with configuration change 
event for service level config.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerConfigChangeEvent4() throws Exception {
@@ -586,14 +579,17 @@ public void testFaultInjectHandlerConfigChangeEvent4() 
throws Exception {
     TestFaultInjectUtil
         
.updateProperty("servicecomb.governance.Consumer.carts4.policy.fault.protocols.rest.delay.fixedDelay",
 500);
 
+    Holder<Boolean> isAsserted = new Holder<>(false);
     handler.handle(invocation, ar -> {
       //check whether error code return,
+      isAsserted.value = true;
       assertEquals(421, response.getStatusCode());
-      assertEquals(true, response.isFailed());
+      assertTrue(response.isFailed());
       long timeNow = System.currentTimeMillis();
       //if really time delay is added it should be greater than 5s.
       Assert.assertTrue((timeNow - timeOld) >= 500);
     });
+    Assert.assertTrue(isAsserted.value);
 
     System.getProperties()
         
.remove("servicecomb.governance.Consumer.carts4.policy.fault.protocols.rest.delay.fixedDelay");
@@ -610,17 +606,21 @@ public void testFaultInjectHandlerConfigChangeEvent4() 
throws Exception {
 
   /**
    * Tests the fault injection handler functionality with configuration change 
event for service level config.
-   *
-   * @throws Exception
    */
   @Test
   public void testFaultInjectHandlerConfigChangeEvent5() throws Exception {
     System.setProperty(
         
"servicecomb.governance.Consumer.carts5.policy.fault.protocols.rest.delay.percent",
         "100");
+    System.setProperty(
+        
"servicecomb.governance.Consumer.carts5.policy.fault.protocols.rest.delay.fixedDelay",
+        "10");
     System.setProperty(
         
"servicecomb.governance.Consumer.carts5.policy.fault.protocols.rest.abort.percent",
         "100");
+    System.setProperty(
+        
"servicecomb.governance.Consumer.carts5.policy.fault.protocols.rest.abort.httpStatus",
+        "500");
 
     
Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName11");
     Mockito.when(invocation.getTransport()).thenReturn(transport);
@@ -641,11 +641,16 @@ public void testFaultInjectHandlerConfigChangeEvent5() 
throws Exception {
     }
     Assert.assertTrue(validAssert);
     TestFaultInjectUtil
-        
.updateProperty("servicecomb.governance.Consumer.carts5.policy.fault.protocols.rest.abort.percent",
 500);
+        
.updateProperty("servicecomb.governance.Consumer.carts5.policy.fault.protocols.rest.abort.httpStatus",
 "420");
 
+    Holder<Boolean> isAsserted = new Holder<>(false);
     handler.handle(invocation, ar -> {
-      assertEquals(true, response.isFailed());
+      isAsserted.value = true;
+      assertTrue(response.isFailed());
+      assertEquals(500, response.getStatusCode());
+      assertEquals(420, ar.getStatusCode());
     });
+    Assert.assertTrue(isAsserted.value);
 
     System.getProperties()
         
.remove("servicecomb.governance.Consumer.carts5.policy.fault.protocols.rest.delay.fixedDelay");
@@ -662,11 +667,9 @@ public void testFaultInjectHandlerConfigChangeEvent5() 
throws Exception {
 
   /**
    * Tests the fault injection handler functionality with configuration change 
event for service level config.
-   *
-   * @throws Exception
    */
   @Test
-  public void testFaultInjectHandlerConfigChangeEvent6() throws Exception {
+  public void testFaultInjectHandlerConfigChangeEvent6() {
     
System.setProperty("servicecomb.governance.Consumer.carts6.policy.fault.protocols.rest.delay.fixedDelay",
 "1000");
 
     System.setProperty(


 

----------------------------------------------------------------
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:
[email protected]


> When delay fault injection is enabled, the business thread will be blocked 
> ---------------------------------------------------------------------------
>
>                 Key: SCB-769
>                 URL: https://issues.apache.org/jira/browse/SCB-769
>             Project: Apache ServiceComb
>          Issue Type: Bug
>            Reporter: YaoHaishi
>            Assignee: YaoHaishi
>            Priority: Major
>             Fix For: java-chassis-1.1.0
>
>
> When delay fault injection is enabled, the not delayed invocation will make 
> business thread blocked in synchronized mode, or network thread blocked in 
> reactive mode.
> The cause is that if the invocation should not be delayed, the process logic 
> in DelayFault exits without calling asynResponse.success("success");



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to