From f93a0750234389011b387a1ee90e87f3f875c6ec Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Tue, 31 Oct 2017 16:39:22 +0100 Subject: [PATCH] SONAR-9973 add IT ensuring resilience of Ce Workers to exceptions including errors --- .../src/main/java/FakeGovernancePlugin.java | 22 ++++ .../src/main/java/ce/BombConfig.java | 64 +++++++++++ ...ntBombReportAnalysisComponentProvider.java | 75 ++++++++++++ .../src/main/java/ce/IseTaskProcessor.java | 38 ++++++ .../src/main/java/ce/OOMGenerator.java | 36 ++++++ .../src/main/java/ce/OkTaskProcessor.java | 41 +++++++ .../src/main/java/ce/OomTaskProcessor.java | 39 +++++++ .../main/java/ce/ws/BombActivatorAction.java | 74 ++++++++++++ .../src/main/java/ce/ws/FakeGoVWsAction.java | 25 ++++ .../src/main/java/ce/ws/FakeGovWs.java | 38 ++++++ .../src/main/java/ce/ws/SubmitAction.java | 59 ++++++++++ .../org/sonarqube/tests/ce/CeWorkersTest.java | 108 +++++++++++++++++- 12 files changed, 618 insertions(+), 1 deletion(-) create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/BombConfig.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/ComponentBombReportAnalysisComponentProvider.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/IseTaskProcessor.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/OOMGenerator.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/OkTaskProcessor.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/OomTaskProcessor.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/ws/BombActivatorAction.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGoVWsAction.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGovWs.java create mode 100644 tests/plugins/fake-governance-plugin/src/main/java/ce/ws/SubmitAction.java diff --git a/tests/plugins/fake-governance-plugin/src/main/java/FakeGovernancePlugin.java b/tests/plugins/fake-governance-plugin/src/main/java/FakeGovernancePlugin.java index 19f6fdf68c3..b37e201d61f 100644 --- a/tests/plugins/fake-governance-plugin/src/main/java/FakeGovernancePlugin.java +++ b/tests/plugins/fake-governance-plugin/src/main/java/FakeGovernancePlugin.java @@ -18,6 +18,14 @@ * 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 index 00000000000..52207065d1a --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/BombConfig.java @@ -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 index 00000000000..a5fe3ee89c4 --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/ComponentBombReportAnalysisComponentProvider.java @@ -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 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 index 00000000000..a6960d1b049 --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/IseTaskProcessor.java @@ -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 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 index 00000000000..4fcef07cb80 --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/OOMGenerator.java @@ -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 consumeAvailableMemory() { + List 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 index 00000000000..92e05032fa0 --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/OkTaskProcessor.java @@ -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 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 index 00000000000..384d3201daa --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/OomTaskProcessor.java @@ -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 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 index 00000000000..2ab01924f0a --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/BombActivatorAction.java @@ -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 index 00000000000..bd361f92961 --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGoVWsAction.java @@ -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 index 00000000000..9d89cfbb795 --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/FakeGovWs.java @@ -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 index 00000000000..9eb607ab789 --- /dev/null +++ b/tests/plugins/fake-governance-plugin/src/main/java/ce/ws/SubmitAction.java @@ -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(); + } +} diff --git a/tests/src/test/java/org/sonarqube/tests/ce/CeWorkersTest.java b/tests/src/test/java/org/sonarqube/tests/ce/CeWorkersTest.java index 491c671a3ce..dc555b5a719 100644 --- a/tests/src/test/java/org/sonarqube/tests/ce/CeWorkersTest.java +++ b/tests/src/test/java/org/sonarqube/tests/ce/CeWorkersTest.java @@ -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); + } } -- 2.39.5