]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16029 integration test for push endpoint
authorLukasz Jarocki <lukasz.jarocki@sonarsource.com>
Wed, 16 Feb 2022 11:43:46 +0000 (08:43 -0300)
committersonartech <sonartech@sonarsource.com>
Fri, 18 Feb 2022 15:48:04 +0000 (15:48 +0000)
server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/ServerPushClient.java
server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientsRegistry.java
server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/ServerPushClientTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java
sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java
sonar-ws/src/main/java/org/sonarqube/ws/client/push/SonarLintServerPushService.java [new file with mode: 0644]

index 458b716a3aff939bf576aefab361e4bf44b6310f..6d8b552e24a225f0bee8dc5eeffa822ba96dd135 100644 (file)
@@ -52,10 +52,15 @@ public abstract class ServerPushClient {
   }
 
   public void writeAndFlush(String payload) throws IOException {
+    payload = ensureCorrectMessageEnding(payload);
     output().write(payload.getBytes(StandardCharsets.UTF_8));
     flush();
   }
 
+  private static String ensureCorrectMessageEnding(String payload) {
+    return payload.endsWith("\n\n") ? payload : (payload + "\n\n");
+  }
+
   public void writeAndFlush(char character) {
     write(character);
     flush();
index 10af5984615b387c758f5e9c88df4b1886d3e7b0..008fdb0c3f9cbe1f3a6738c1fc74c8988be445ad 100644 (file)
@@ -49,14 +49,13 @@ public class SonarLintClientsRegistry implements RuleActivationListener {
 
   private final RuleActivatorEventsDistributor ruleActivatorEventsDistributor;
   private final SonarLintClientPermissionsValidator sonarLintClientPermissionsValidator;
+  private final List<SonarLintClient> clients = new CopyOnWriteArrayList<>();
 
   public SonarLintClientsRegistry(RuleActivatorEventsDistributor ruleActivatorEventsDistributor, SonarLintClientPermissionsValidator permissionsValidator) {
     this.ruleActivatorEventsDistributor = ruleActivatorEventsDistributor;
     this.sonarLintClientPermissionsValidator = permissionsValidator;
   }
 
-  private final List<SonarLintClient> clients = new CopyOnWriteArrayList<>();
-
   public void registerClient(SonarLintClient sonarLintClient) {
     clients.add(sonarLintClient);
     sonarLintClient.scheduleHeartbeat();
index 47de0e39b9ea2a7a2427fc44fbb920da60638824..e7eca1cf790a087a54a6554537fb9b0c9a841c2c 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.pushapi;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
@@ -33,7 +34,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.doThrow;
@@ -69,6 +69,22 @@ public class ServerPushClientTest {
       .schedule(any(HeartbeatTask.class), anyLong(), any());
   }
 
+  @Test
+  public void writeAndFlush_payloadAlwaysEndsWithSlashNSlashN() throws IOException {
+    underTest.writeAndFlush("payload");
+
+    verify(outputStream, Mockito.times(1)).flush();
+    verify(outputStream, Mockito.times(1)).write("payload\n\n".getBytes(StandardCharsets.UTF_8));
+  }
+
+  @Test
+  public void writeAndFlush_payloadAlwaysEndsWithASingleSlashNSlashN_whenMessageAlreadyContainsIt() throws IOException {
+    underTest.writeAndFlush("payload\n\n");
+
+    verify(outputStream, Mockito.times(1)).flush();
+    verify(outputStream, Mockito.times(1)).write("payload\n\n".getBytes(StandardCharsets.UTF_8));
+  }
+
   @Test
   public void writeAndFlush_writeIsCalledOnceAndFlushIsCalledOnce() throws IOException {
     underTest.writeAndFlush('a');
index 9a3432d45c55df18e98299429a0d1dd247ece295..39c97e4b4bad930a28e05f207267c2ecf5661531 100644 (file)
@@ -55,6 +55,7 @@ import org.sonarqube.ws.client.projectpullrequests.ProjectPullRequestsService;
 import org.sonarqube.ws.client.projects.ProjectsService;
 import org.sonarqube.ws.client.projecttags.ProjectTagsService;
 import org.sonarqube.ws.client.properties.PropertiesService;
+import org.sonarqube.ws.client.push.SonarLintServerPushService;
 import org.sonarqube.ws.client.qualitygates.QualitygatesService;
 import org.sonarqube.ws.client.qualityprofiles.QualityprofilesService;
 import org.sonarqube.ws.client.roots.RootsService;
@@ -140,6 +141,7 @@ class DefaultWsClient implements WsClient {
   private final WebservicesService webservicesService;
   private final BatchService batchService;
   private final SecurityReportsService securityReportsService;
+  private final SonarLintServerPushService sonarLintPushService;
 
   DefaultWsClient(WsConnector wsConnector) {
     this.wsConnector = wsConnector;
@@ -198,6 +200,7 @@ class DefaultWsClient implements WsClient {
     this.webservicesService = new WebservicesService(wsConnector);
     this.batchService = new BatchService(wsConnector);
     this.securityReportsService = new SecurityReportsService(wsConnector);
+    this.sonarLintPushService = new SonarLintServerPushService(wsConnector);
   }
 
   @Override
@@ -306,6 +309,11 @@ class DefaultWsClient implements WsClient {
     return monitoringService;
   }
 
+  @Override
+  public SonarLintServerPushService sonarLintPush() {
+    return sonarLintPushService;
+  }
+
   @Override
   public NavigationService navigation() {
     return navigationService;
index e18bd387c7ae5a86a76b0730daeaf80d93e57291..23f90cfd7ad3a19a09bc958ecf8d07cd3fa7dae6 100644 (file)
@@ -55,6 +55,7 @@ import org.sonarqube.ws.client.projectpullrequests.ProjectPullRequestsService;
 import org.sonarqube.ws.client.projects.ProjectsService;
 import org.sonarqube.ws.client.projecttags.ProjectTagsService;
 import org.sonarqube.ws.client.properties.PropertiesService;
+import org.sonarqube.ws.client.push.SonarLintServerPushService;
 import org.sonarqube.ws.client.qualitygates.QualitygatesService;
 import org.sonarqube.ws.client.qualityprofiles.QualityprofilesService;
 import org.sonarqube.ws.client.roots.RootsService;
@@ -205,4 +206,6 @@ public interface WsClient {
   SecurityReportsService securityReports();
 
   MonitoringService monitoring();
+
+  SonarLintServerPushService sonarLintPush();
 }
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/push/SonarLintServerPushService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/push/SonarLintServerPushService.java
new file mode 100644 (file)
index 0000000..6e4842d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 org.sonarqube.ws.client.push;
+
+import org.sonarqube.ws.client.BaseService;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsConnector;
+import org.sonarqube.ws.client.WsResponse;
+
+public class SonarLintServerPushService extends BaseService {
+  public SonarLintServerPushService(WsConnector wsConnector) {
+    super(wsConnector, "api/push");
+  }
+
+  public WsResponse connect(String projectKeys, String languages) {
+    return call(
+      new GetRequest(path("sonarlint_events"))
+        .setParam("projectKeys", projectKeys)
+        .setParam("languages", languages)
+        .setHeader("accept", "text/event-stream"));
+  }
+}