From 24cffd02b68f50b481f244c75d2c309daa863b6f Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Wed, 25 Feb 2015 15:27:46 +0100 Subject: [PATCH] Fix some quality flaws --- .../issue/tracking/LocalIssueTracking.java | 39 ++++++---- .../issue/tracking/ServerIssueValueCoder.java | 5 +- .../DefaultServerIssuesLoaderTest.java | 76 +++++++++++++++++++ 3 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java index 7d67696196e..9b5b26f730b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java @@ -44,6 +44,8 @@ import org.sonar.core.component.ComponentKeys; import org.sonar.core.issue.IssueUpdater; import org.sonar.core.issue.workflow.IssueWorkflow; +import javax.annotation.CheckForNull; + import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -111,21 +113,11 @@ public class LocalIssueTracking implements BatchComponent { } // all the issues that are not closed in db before starting this module scan, including manual issues - Collection previousIssues = new ArrayList<>(); - for (org.sonar.batch.protocol.input.BatchInput.ServerIssue previousIssue : serverIssueRepository.byComponent(component)) { - previousIssues.add(new ServerIssueFromWs(previousIssue)); - } + Collection serverIssues = loadServerIssues(component); - SourceHashHolder sourceHashHolder = null; - if (component.isFile()) { - DefaultInputFile file = (DefaultInputFile) inputPathCache.getInputPath(component); - if (file == null) { - throw new IllegalStateException("Resource " + component.resource() + " was not found in InputPath cache"); - } - sourceHashHolder = new SourceHashHolder((DefaultInputFile) file, lastLineHashes); - } + SourceHashHolder sourceHashHolder = loadSourceHashes(component); - IssueTrackingResult trackingResult = tracking.track(sourceHashHolder, previousIssues, issues); + IssueTrackingResult trackingResult = tracking.track(sourceHashHolder, serverIssues, issues); // unmatched = issues that have been resolved + issues on disabled/removed rules + manual issues addUnmatched(trackingResult.unmatched(), sourceHashHolder, issues); @@ -143,6 +135,27 @@ public class LocalIssueTracking implements BatchComponent { } } + @CheckForNull + private SourceHashHolder loadSourceHashes(BatchResource component) { + SourceHashHolder sourceHashHolder = null; + if (component.isFile()) { + DefaultInputFile file = (DefaultInputFile) inputPathCache.getInputPath(component); + if (file == null) { + throw new IllegalStateException("Resource " + component.resource() + " was not found in InputPath cache"); + } + sourceHashHolder = new SourceHashHolder((DefaultInputFile) file, lastLineHashes); + } + return sourceHashHolder; + } + + private Collection loadServerIssues(BatchResource component) { + Collection serverIssues = new ArrayList<>(); + for (org.sonar.batch.protocol.input.BatchInput.ServerIssue previousIssue : serverIssueRepository.byComponent(component)) { + serverIssues.add(new ServerIssueFromWs(previousIssue)); + } + return serverIssues; + } + @VisibleForTesting protected void mergeMatched(IssueTrackingResult result) { for (DefaultIssue issue : result.matched()) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java index 321d09a852b..d3c2ee8bb93 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java @@ -22,7 +22,6 @@ package org.sonar.batch.issue.tracking; import com.persistit.Value; import com.persistit.encoding.CoderContext; import com.persistit.encoding.ValueCoder; -import com.persistit.exception.ConversionException; import org.sonar.batch.protocol.input.BatchInput.ServerIssue; import java.io.IOException; @@ -30,13 +29,13 @@ import java.io.IOException; public class ServerIssueValueCoder implements ValueCoder { @Override - public void put(Value value, Object object, CoderContext context) throws ConversionException { + public void put(Value value, Object object, CoderContext context) { ServerIssue issue = (ServerIssue) object; value.putByteArray(issue.toByteArray()); } @Override - public Object get(Value value, Class clazz, CoderContext context) throws ConversionException { + public Object get(Value value, Class clazz, CoderContext context) { try { return ServerIssue.parseFrom(value.getByteArray()); } catch (IOException e) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java new file mode 100644 index 00000000000..4cc756ff1ce --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java @@ -0,0 +1,76 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.sonar.batch.repository; + +import com.google.common.base.Function; +import com.google.common.io.InputSupplier; +import org.junit.Before; +import org.junit.Test; +import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.protocol.input.BatchInput; +import org.sonar.batch.protocol.input.BatchInput.ServerIssue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DefaultServerIssuesLoaderTest { + private DefaultServerIssuesLoader loader; + private ServerClient serverClient; + + @Before + public void prepare() { + serverClient = mock(ServerClient.class); + loader = new DefaultServerIssuesLoader(serverClient); + } + + @Test + public void loadFromWs() throws Exception { + InputSupplier is = mock(InputSupplier.class); + when(serverClient.doRequest("/batch/issues?key=foo", "GET", null)).thenReturn(is); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + ServerIssue.newBuilder().setKey("ab1").build() + .writeDelimitedTo(bos); + ServerIssue.newBuilder().setKey("ab2").build() + .writeDelimitedTo(bos); + + when(is.getInput()).thenReturn(new ByteArrayInputStream(bos.toByteArray())); + + final List result = new ArrayList<>(); + loader.load("foo", new Function() { + + @Override + public Void apply(ServerIssue input) { + result.add(input); + return null; + } + }, false); + + assertThat(result).extracting("key").containsExactly("ab1", "ab2"); + } +} -- 2.39.5