]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19560 Silence hz inactive exception in scheduler
authorJacek Poreda <jacek.poreda@sonarsource.com>
Tue, 18 Jul 2023 08:58:16 +0000 (10:58 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 18 Jul 2023 20:03:23 +0000 (20:03 +0000)
server/sonar-ce/src/main/java/org/sonar/ce/CeDistributedInformationImpl.java
server/sonar-ce/src/test/java/org/sonar/ce/CeDistributedInformationImplTest.java
server/sonar-process/src/main/java/org/sonar/process/cluster/health/HealthStateRefresher.java
server/sonar-process/src/test/java/org/sonar/process/cluster/health/HealthStateRefresherTest.java

index c6d23f4e94aacbdf4cd25375e2d3d1b693bae050..4ac9b89f85b3cb12214059742b4f786d443fb5de 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.ce;
 
+import com.hazelcast.core.HazelcastInstanceNotActiveException;
 import com.hazelcast.spi.exception.RetryableHazelcastException;
 import java.util.Map;
 import java.util.Set;
@@ -82,8 +83,8 @@ public class CeDistributedInformationImpl implements CeDistributedInformation, S
     try {
       // Removing the worker UUIDs
       getClusteredWorkerUUIDs().remove(hazelcastMember.getUuid());
-    } catch (RetryableHazelcastException e) {
-      LOGGER.debug("Unable to remove worker UUID from the list of active workers", e.getMessage());
+    } catch (HazelcastInstanceNotActiveException | RetryableHazelcastException e) {
+      LOGGER.debug("Hazelcast is not active anymore", e);
     }
   }
 
index 9e473a539a08908d55385557eae3bb8e69e584ce..adde2711ffdf0c6490fc5ed586fcf43404dcc1c8 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.ce;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.hazelcast.core.HazelcastInstanceNotActiveException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -28,18 +29,25 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import org.junit.Rule;
 import org.junit.Test;
+import org.slf4j.event.Level;
+import org.sonar.api.testfixtures.log.LogTester;
 import org.sonar.ce.taskprocessor.CeWorker;
 import org.sonar.ce.taskprocessor.CeWorkerFactory;
 import org.sonar.process.cluster.hz.HazelcastMember;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.data.MapEntry.entry;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.sonar.process.cluster.hz.HazelcastObjects.WORKER_UUIDS;
 
 public class CeDistributedInformationImplTest {
+  @Rule
+  public final LogTester logTester = new LogTester();
+
   private final UUID clientUUID1 = UUID.randomUUID();
   private final UUID clientUUID2 = UUID.randomUUID();
   private final UUID clientUUID3 = UUID.randomUUID();
@@ -101,7 +109,7 @@ public class CeDistributedInformationImplTest {
     try {
       ceDistributedInformation.broadcastWorkerUUIDs();
       assertThat(modifiableWorkerMap).containsExactly(
-        entry(clientUUID1, ImmutableSet.of("a10", "a11")));
+        entry(clientUUID1, Set.of("a10", "a11")));
     } finally {
       ceDistributedInformation.stop();
     }
@@ -122,6 +130,19 @@ public class CeDistributedInformationImplTest {
     CeDistributedInformationImpl ceDistributedInformation = new CeDistributedInformationImpl(hzClientWrapper, mock(CeWorkerFactory.class));
     ceDistributedInformation.stop();
     assertThat(modifiableWorkerMap).containsExactlyInAnyOrderEntriesOf(
-      ImmutableMap.of(clientUUID2, ImmutableSet.of(w3), clientUUID3, ImmutableSet.of(w4, w5, w6)));
+      Map.of(clientUUID2, Set.of(w3), clientUUID3, ImmutableSet.of(w4, w5, w6)));
   }
+
+  @Test
+  public void stop_whenThrowHazelcastInactiveException_shouldSilenceError() {
+    logTester.setLevel(Level.DEBUG);
+    when(hzClientWrapper.getReplicatedMap(any())).thenThrow(new HazelcastInstanceNotActiveException("Hazelcast is not active"));
+
+    CeDistributedInformationImpl ceDistributedInformation = new CeDistributedInformationImpl(hzClientWrapper, mock(CeWorkerFactory.class));
+    ceDistributedInformation.stop();
+
+    assertThat(logTester.logs(Level.DEBUG)).contains("Hazelcast is not active anymore");
+    assertThat(logTester.logs(Level.ERROR)).isEmpty();
+  }
+
 }
index 235b8e318178ab9ff0d8255b0212f2e9b96b67e8..20cd21498c5e3a8b26cfa1348a3c0a5319d91e33 100644 (file)
@@ -51,13 +51,17 @@ public class HealthStateRefresher implements Startable {
       NodeHealth nodeHealth = nodeHealthProvider.get();
       sharedHealthState.writeMine(nodeHealth);
     } catch (HazelcastInstanceNotActiveException | RetryableHazelcastException e) {
-      LOG.debug("Hazelcast is no more active", e);
+      LOG.debug("Hazelcast is not active anymore", e);
     } catch (Throwable t) {
       LOG.error("An error occurred while attempting to refresh HealthState of the current node in the shared state:", t);
     }
   }
 
   public void stop() {
-    sharedHealthState.clearMine();
+    try {
+      sharedHealthState.clearMine();
+    } catch (HazelcastInstanceNotActiveException | RetryableHazelcastException e) {
+      LOG.debug("Hazelcast is not active anymore", e);
+    }
   }
 }
index eafe00a8a76fa25a191d57abb5fe29ace55817a8..93e47ffa42b8a152222f590a04fd9738a2f77f84 100644 (file)
@@ -28,7 +28,7 @@ import org.mockito.ArgumentCaptor;
 import org.sonar.process.LoggingRule;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
+import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doThrow;
@@ -41,15 +41,15 @@ import static org.slf4j.event.Level.ERROR;
 
 public class HealthStateRefresherTest {
   @Rule
-  public LoggingRule logging = new LoggingRule(HealthStateRefresher.class);
+  public final LoggingRule logging = new LoggingRule(HealthStateRefresher.class);
 
-  private Random random = new Random();
-  private NodeDetailsTestSupport testSupport = new NodeDetailsTestSupport(random);
+  private final Random random = new Random();
+  private final NodeDetailsTestSupport testSupport = new NodeDetailsTestSupport(random);
 
-  private HealthStateRefresherExecutorService executorService = mock(HealthStateRefresherExecutorService.class);
-  private NodeHealthProvider nodeHealthProvider = mock(NodeHealthProvider.class);
-  private SharedHealthState sharedHealthState = mock(SharedHealthState.class);
-  private HealthStateRefresher underTest = new HealthStateRefresher(executorService, nodeHealthProvider, sharedHealthState);
+  private final HealthStateRefresherExecutorService executorService = mock(HealthStateRefresherExecutorService.class);
+  private final NodeHealthProvider nodeHealthProvider = mock(NodeHealthProvider.class);
+  private final SharedHealthState sharedHealthState = mock(SharedHealthState.class);
+  private final HealthStateRefresher underTest = new HealthStateRefresher(executorService, nodeHealthProvider, sharedHealthState);
 
   @Test
   public void start_adds_runnable_with_10_second_delay_and_initial_delay_putting_NodeHealth_from_provider_into_SharedHealthState() {
@@ -79,15 +79,12 @@ public class HealthStateRefresherTest {
     verify(sharedHealthState).writeMine(nodeHealths[1]);
     verify(sharedHealthState).writeMine(nodeHealths[2]);
 
-    try {
-      runnable.run();
-    } catch (IllegalStateException e) {
-      fail("Runnable should catch any Throwable");
-    }
+    assertThatCode(runnable::run)
+      .doesNotThrowAnyException();
   }
 
   @Test
-  public void stop_has_no_effect() {
+  public void stop_whenCalled_hasNoEffect() {
     underTest.stop();
 
     verify(sharedHealthState).clearMine();
@@ -95,7 +92,19 @@ public class HealthStateRefresherTest {
   }
 
   @Test
-  public void do_not_log_errors_when_hazelcast_is_not_active() {
+  public void stop_whenThrowHazelcastInactiveException_shouldSilenceError() {
+    logging.setLevel(DEBUG);
+    SharedHealthState sharedHealthStateMock = mock(SharedHealthState.class);
+    doThrow(HazelcastInstanceNotActiveException.class).when(sharedHealthStateMock).clearMine();
+    HealthStateRefresher underTest = new HealthStateRefresher(executorService, nodeHealthProvider, sharedHealthStateMock);
+    underTest.stop();
+
+    assertThat(logging.getLogs(ERROR)).isEmpty();
+    assertThat(logging.hasLog(DEBUG, "Hazelcast is not active anymore")).isTrue();
+  }
+
+  @Test
+  public void start_whenHazelcastIsNotActive_shouldNotLogErrors() {
     logging.setLevel(DEBUG);
     doThrow(new HazelcastInstanceNotActiveException()).when(sharedHealthState).writeMine(any());
 
@@ -107,6 +116,6 @@ public class HealthStateRefresherTest {
     runnable.run();
 
     assertThat(logging.getLogs(ERROR)).isEmpty();
-    assertThat(logging.hasLog(DEBUG, "Hazelcast is no more active")).isTrue();
+    assertThat(logging.hasLog(DEBUG, "Hazelcast is not active anymore")).isTrue();
   }
 }