]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9973 add IT ensuring resilience of Ce Workers to exceptions
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 31 Oct 2017 15:39:22 +0000 (16:39 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Fri, 3 Nov 2017 13:29:16 +0000 (14:29 +0100)
including errors

12 files changed:
tests/plugins/fake-governance-plugin/src/main/java/FakeGovernancePlugin.java
tests/plugins/fake-governance-plugin/src/main/java/ce/BombConfig.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/ComponentBombReportAnalysisComponentProvider.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/IseTaskProcessor.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/OOMGenerator.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/OkTaskProcessor.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/OomTaskProcessor.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/ws/BombActivatorAction.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGoVWsAction.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGovWs.java [new file with mode: 0644]
tests/plugins/fake-governance-plugin/src/main/java/ce/ws/SubmitAction.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/ce/CeWorkersTest.java

index 19f6fdf68c38857c8b4d0722f83b33c52aea63a9..b37e201d61f9fc9189adf843da3bd0157a708135 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
+import ce.BombConfig;
+import ce.ComponentBombReportAnalysisComponentProvider;
+import ce.IseTaskProcessor;
+import ce.OkTaskProcessor;
+import ce.OomTaskProcessor;
+import ce.ws.BombActivatorAction;
+import ce.ws.FakeGovWs;
+import ce.ws.SubmitAction;
 import org.sonar.api.Plugin;
 import systemPasscode.SystemPasscodeWebService;
 import workerCount.FakeWorkerCountProviderImpl;
@@ -36,6 +44,20 @@ public class FakeGovernancePlugin implements Plugin {
       context.addExtension(LatchControllerWorkerMeasureComputer.class);
       context.addExtension(RefreshWorkerCountAction.class);
       context.addExtension(SystemPasscodeWebService.class);
+
+      // WS api/fake_gov
+      context.addExtension(FakeGovWs.class);
+
+      // failing CE tasks
+      context.addExtension(SubmitAction.class);
+      context.addExtension(OomTaskProcessor.class);
+      context.addExtension(IseTaskProcessor.class);
+      context.addExtension(OkTaskProcessor.class);
+
+      // component bombs injection into the Report Analysis processing container in the CE
+      context.addExtension(BombConfig.class);
+      context.addExtension(ComponentBombReportAnalysisComponentProvider.class);
+      context.addExtension(BombActivatorAction.class);
     }
   }
 
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/BombConfig.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/BombConfig.java
new file mode 100644 (file)
index 0000000..5220706
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce;
+
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.server.ServerSide;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+
+@ServerSide
+@ComputeEngineSide
+public class BombConfig {
+  private static final String OOM_STOP_BOMB_KEY = "oomStopBomb";
+  private static final String ISE_STOP_BOMB_KEY = "iseStopBomb";
+
+  private final DbClient dbClient;
+
+  public BombConfig(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  public boolean isOomStopBomb() {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      return dbClient.internalPropertiesDao().selectByKey(dbSession, OOM_STOP_BOMB_KEY).map(Boolean::valueOf).orElse(false);
+    }
+  }
+
+  public void setOomStopBomb(boolean oomStopBomb) {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      dbClient.internalPropertiesDao().save(dbSession, OOM_STOP_BOMB_KEY, String.valueOf(oomStopBomb));
+      dbSession.commit();
+    }
+  }
+
+  public boolean isIseStopBomb() {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      return dbClient.internalPropertiesDao().selectByKey(dbSession, ISE_STOP_BOMB_KEY).map(Boolean::valueOf).orElse(false);
+    }
+  }
+
+  public void setIseStopBomb(boolean iseStopBomb) {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      dbClient.internalPropertiesDao().save(dbSession, ISE_STOP_BOMB_KEY, String.valueOf(iseStopBomb));
+      dbSession.commit();
+    }
+  }
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/ComponentBombReportAnalysisComponentProvider.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/ComponentBombReportAnalysisComponentProvider.java
new file mode 100644 (file)
index 0000000..a5fe3ee
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce;
+
+import java.util.List;
+import org.picocontainer.Startable;
+import org.sonar.plugin.ce.ReportAnalysisComponentProvider;
+import org.sonar.server.computation.task.container.EagerStart;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
+public class ComponentBombReportAnalysisComponentProvider implements ReportAnalysisComponentProvider {
+  private final BombConfig bombConfig;
+
+  public ComponentBombReportAnalysisComponentProvider(BombConfig bombConfig) {
+    this.bombConfig = bombConfig;
+  }
+
+  @Override
+  public List<Object> getComponents() {
+    if (bombConfig.isOomStopBomb()) {
+      return singletonList(OOMFailingStopComponent.class);
+    }
+    if (bombConfig.isIseStopBomb()) {
+      return singletonList(ISEFailingStopComponent.class);
+    }
+    return emptyList();
+  }
+
+  @EagerStart
+  public static final class OOMFailingStopComponent implements Startable {
+
+    @Override
+    public void start() {
+      // nothing to do
+    }
+
+    @Override
+    public void stop() {
+      OOMGenerator.consumeAvailableMemory();
+    }
+  }
+
+  @EagerStart
+  public static final class ISEFailingStopComponent implements Startable {
+
+    @Override
+    public void start() {
+      // nothing to do
+    }
+
+    @Override
+    public void stop() {
+      throw new IllegalStateException("Faking an IllegalStateException thrown by a stoppable component in the Analysis Report processing container");
+    }
+  }
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/IseTaskProcessor.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/IseTaskProcessor.java
new file mode 100644 (file)
index 0000000..a6960d1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce;
+
+import java.util.Collections;
+import java.util.Set;
+import org.sonar.ce.queue.CeTask;
+import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.ce.taskprocessor.CeTaskProcessor;
+
+public class IseTaskProcessor implements CeTaskProcessor {
+  @Override
+  public Set<String> getHandledCeTaskTypes() {
+    return Collections.singleton("ISE");
+  }
+
+  @Override
+  public CeTaskResult process(CeTask task) {
+    throw new IllegalStateException("Faking an IllegalStateException thrown processing a task");
+  }
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/OOMGenerator.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/OOMGenerator.java
new file mode 100644 (file)
index 0000000..4fcef07
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class OOMGenerator {
+  private OOMGenerator() {
+    // prevents instantiation
+  }
+
+  public static List<Object> consumeAvailableMemory() {
+    List<Object> holder = new ArrayList<>();
+    while (true) {
+      holder.add(new byte[128 * 1024]);
+    }
+  }
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/OkTaskProcessor.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/OkTaskProcessor.java
new file mode 100644 (file)
index 0000000..92e0503
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce;
+
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+import org.sonar.ce.queue.CeTask;
+import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.ce.taskprocessor.CeTaskProcessor;
+
+public class OkTaskProcessor implements CeTaskProcessor {
+  @Override
+  public Set<String> getHandledCeTaskTypes() {
+    return Collections.singleton("OK");
+  }
+
+  @Override
+  public CeTaskResult process(CeTask task) {
+    return Optional::empty;
+  }
+
+
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/OomTaskProcessor.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/OomTaskProcessor.java
new file mode 100644 (file)
index 0000000..384d320
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce;
+
+import java.util.Collections;
+import java.util.Set;
+import org.sonar.ce.queue.CeTask;
+import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.ce.taskprocessor.CeTaskProcessor;
+
+public class OomTaskProcessor implements CeTaskProcessor {
+  @Override
+  public Set<String> getHandledCeTaskTypes() {
+    return Collections.singleton("OOM");
+  }
+
+  @Override
+  public CeTaskResult process(CeTask task) {
+    OOMGenerator.consumeAvailableMemory();
+    return null;
+  }
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/BombActivatorAction.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/BombActivatorAction.java
new file mode 100644 (file)
index 0000000..2ab0192
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce.ws;
+
+import ce.BombConfig;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+
+public class BombActivatorAction implements FakeGoVWsAction {
+
+  private static final String PARAM_BOMB_TYPE = "type";
+
+  private final BombConfig bombConfig;
+
+  public BombActivatorAction(BombConfig bombConfig) {
+    this.bombConfig = bombConfig;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    WebService.NewAction action = controller.createAction("activate_bomb")
+      .setPost(true)
+      .setHandler(this);
+    action.createParam(PARAM_BOMB_TYPE)
+      .setRequired(true)
+      .setPossibleValues("OOM", "ISE", "NONE");
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    BombType bombType = BombType.valueOf(request.mandatoryParam(PARAM_BOMB_TYPE));
+
+    bombConfig.setIseStopBomb(false);
+    bombConfig.setOomStopBomb(false);
+    switch (bombType) {
+      case ISE:
+        bombConfig.setIseStopBomb(true);
+        break;
+      case OOM:
+        bombConfig.setOomStopBomb(true);
+        break;
+      case NONE:
+        break;
+      default:
+        throw new IllegalArgumentException("Unsupported bomb type " + bombType);
+    }
+
+    response.noContent();
+  }
+
+  enum BombType {
+    NONE, OOM, ISE
+
+  }
+
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGoVWsAction.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGoVWsAction.java
new file mode 100644 (file)
index 0000000..bd361f9
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce.ws;
+
+import org.sonar.server.ws.WsAction;
+
+public interface FakeGoVWsAction extends WsAction {
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGovWs.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGovWs.java
new file mode 100644 (file)
index 0000000..9d89cfb
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce.ws;
+
+import java.util.Arrays;
+import org.sonar.api.server.ws.WebService;
+
+public class FakeGovWs implements WebService {
+  private final FakeGoVWsAction[] actions;
+
+  public FakeGovWs(FakeGoVWsAction[] actions) {
+    this.actions = actions;
+  }
+
+  @Override
+  public void define(Context context) {
+    NewController controller = context.createController("api/fake_gov");
+    Arrays.stream(actions).forEach(action -> action.define(controller));
+    controller.done();
+  }
+}
diff --git a/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/SubmitAction.java b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/SubmitAction.java
new file mode 100644 (file)
index 0000000..9eb607a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package ce.ws;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.ce.queue.CeQueue;
+import org.sonar.ce.queue.CeTask;
+import org.sonar.ce.queue.CeTaskSubmit;
+
+public class SubmitAction implements FakeGoVWsAction {
+
+  private static final String PARAM_TYPE = "type";
+
+  private final CeQueue ceQueue;
+
+  public SubmitAction(CeQueue ceQueue) {
+    this.ceQueue = ceQueue;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    WebService.NewAction action = controller.createAction("submit")
+      .setPost(true)
+      .setHandler(this);
+    action.createParam(PARAM_TYPE)
+      .setRequired(true)
+      .setPossibleValues("OOM", "OK", "ISE");
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    String type = request.mandatoryParam(PARAM_TYPE);
+
+    CeTaskSubmit.Builder submit = ceQueue.prepareSubmit();
+    submit.setType(type);
+
+    CeTask ceTask = ceQueue.submit(submit.build());
+    response.noContent();
+  }
+}
index 491c671a3ce559723fec3350b8d3cc4209a6df60..dc555b5a719f5a9a87d135c8721e191dbc3388b3 100644 (file)
@@ -44,6 +44,7 @@ import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonarqube.ws.WsCe;
+import org.sonarqube.ws.client.PostRequest;
 import org.sonarqube.ws.client.WsClient;
 import org.sonarqube.ws.client.ce.ActivityWsRequest;
 import util.ItUtils;
@@ -81,6 +82,8 @@ public class CeWorkersTest {
     OrchestratorBuilder builder = Orchestrator.builderEnv()
       .addPlugin(pluginArtifact("fake-governance-plugin"))
       .setServerProperty("fakeGoverance.workerLatch.sharedMemoryFile", sharedMemory.getAbsolutePath())
+      // overwrite default value to display heap dump on OOM and reduce max heap
+      .setServerProperty("sonar.ce.javaOpts", "-Xmx256m -Xms128m")
       .addPlugin(xooPlugin());
     orchestrator = builder.build();
     orchestrator.start();
@@ -96,6 +99,99 @@ public class CeWorkersTest {
     }
   }
 
+  @Test
+  public void ce_worker_is_resilient_to_OOM_and_ISE_during_processing_of_a_task() throws InterruptedException {
+    submitFakeTask("OOM");
+
+    waitForEmptyQueue();
+
+    assertThat(adminWsClient.ce().activity(new ActivityWsRequest()
+      .setType("OOM")
+      .setStatus(ImmutableList.of("FAILED")))
+      .getTasksCount())
+        .isEqualTo(1);
+
+    submitFakeTask("OK");
+
+    waitForEmptyQueue();
+
+    assertThat(adminWsClient.ce().activity(new ActivityWsRequest()
+      .setType("OK")
+      .setStatus(ImmutableList.of("SUCCESS")))
+      .getTasksCount())
+        .isEqualTo(1);
+
+    submitFakeTask("ISE");
+
+    waitForEmptyQueue();
+
+    assertThat(adminWsClient.ce().activity(new ActivityWsRequest()
+      .setType("ISE")
+      .setStatus(ImmutableList.of("FAILED")))
+      .getTasksCount())
+        .isEqualTo(1);
+
+    submitFakeTask("OK");
+
+    waitForEmptyQueue();
+
+    assertThat(adminWsClient.ce().activity(new ActivityWsRequest()
+      .setType("OK")
+      .setStatus(ImmutableList.of("SUCCESS")))
+      .getTasksCount())
+        .isEqualTo(2);
+  }
+
+  private void submitFakeTask(String type) {
+    adminWsClient.wsConnector().call(new PostRequest("api/fake_gov/submit")
+      .setParam("type", type))
+      .failIfNotSuccessful();
+  }
+
+  @Test
+  public void ce_worker_is_resilient_to_OOM_and_RuntimeException_when_stopping_analysis_report_container() throws IOException {
+
+    RandomAccessFile randomAccessFile = null;
+    try {
+      randomAccessFile = new RandomAccessFile(sharedMemory, "rw");
+      MappedByteBuffer mappedByteBuffer = initMappedByteBuffer(randomAccessFile);
+      releaseAnyAnalysisWithFakeGovernancePlugin(mappedByteBuffer);
+
+      SonarScanner sonarRunner = SonarScanner.create(ItUtils.projectDir("shared/xoo-sample"));
+      orchestrator.executeBuild(sonarRunner, true);
+
+      enableComponentBomb("OOM");
+
+      orchestrator.executeBuild(sonarRunner, true);
+
+      enableComponentBomb("NONE");
+
+      orchestrator.executeBuild(sonarRunner, true);
+
+      enableComponentBomb("ISE");
+
+      orchestrator.executeBuild(sonarRunner, true);
+
+      enableComponentBomb("NONE");
+
+      orchestrator.executeBuild(sonarRunner, true);
+
+      assertThat(adminWsClient.ce().activity(new ActivityWsRequest()
+        .setType("REPORT")
+        .setStatus(ImmutableList.of("SUCCESS")))
+        .getTasksCount())
+          .isEqualTo(5);
+    } finally {
+      close(randomAccessFile);
+    }
+  }
+
+  private void enableComponentBomb(String type) {
+    adminWsClient.wsConnector().call(new PostRequest("api/fake_gov/activate_bomb")
+      .setParam("type", type))
+      .failIfNotSuccessful();
+  }
+
   @Test
   public void enabled_worker_count_is_initially_1_and_can_be_changed_dynamically_by_plugin() throws IOException {
     assertThat(Files.lines(orchestrator.getServer().getCeLogs().toPath())
@@ -109,7 +205,7 @@ public class CeWorkersTest {
 
       verifyAnalysesRunInParallel(mappedByteBuffer, 1);
 
-      /* 2 <= newWorkerCount <= 7 */
+      /* 4 <= newWorkerCount <= 7 */
       int newWorkerCount = 4 + new Random().nextInt(4);
       updateWorkerCount(newWorkerCount);
 
@@ -234,4 +330,14 @@ public class CeWorkersTest {
       e.printStackTrace();
     }
   }
+
+  private void waitForEmptyQueue() throws InterruptedException {
+    int tasksCount;
+    do {
+      Thread.sleep(100);
+      tasksCount = adminWsClient.ce().activity(new ActivityWsRequest()
+        .setStatus(ImmutableList.of("PENDING", "IN_PROGRESS")))
+        .getTasksCount();
+    } while (tasksCount > 0);
+  }
 }