]> source.dussan.org Git - sonarqube.git/commitdiff
Fix quality flaws
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 13 May 2015 13:40:24 +0000 (15:40 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 13 May 2015 13:49:00 +0000 (15:49 +0200)
20 files changed:
server/sonar-server/src/main/java/org/sonar/server/plugins/package-info.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentLinksStepTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationMeasuresStepTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/add_links_on_project_and_module-result.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/delete_link.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/empty.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/not_delete_custom_link.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/nothing_to_do_when_link_already_exists.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/update_link-result.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/update_link.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/add_links_on_project_and_module-result.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/delete_link.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/empty.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/not_delete_custom_link.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/nothing_to_do_when_link_already_exists.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/update_link-result.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/update_link.xml [new file with mode: 0644]
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/ProtobufUtil.java

diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/package-info.java
new file mode 100644 (file)
index 0000000..f4d64e0
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.plugins;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentLinksStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentLinksStepTest.java
deleted file mode 100644 (file)
index 6677e55..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * 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.server.computation.step;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.i18n.I18n;
-import org.sonar.batch.protocol.Constants;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReportReader;
-import org.sonar.batch.protocol.output.BatchReportWriter;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.DbTester;
-import org.sonar.server.component.db.ComponentLinkDao;
-import org.sonar.server.computation.ComputationContext;
-import org.sonar.server.db.DbClient;
-import org.sonar.test.DbTests;
-
-import java.io.File;
-import java.util.Locale;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-@Category(DbTests.class)
-public class PersistComponentLinksStepTest extends BaseStepTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @ClassRule
-  public static DbTester dbTester = new DbTester();
-
-  DbSession session;
-
-  ComponentLinkDao dao;
-
-  I18n i18n;
-
-  PersistProjectLinksStep step;
-
-  @Before
-  public void setup() {
-    session = dbTester.myBatis().openSession(false);
-    dao = new ComponentLinkDao();
-    DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), dao);
-
-    i18n = mock(I18n.class);
-    when(i18n.message(Locale.ENGLISH, "project_links.homepage", null)).thenReturn("Home");
-    when(i18n.message(Locale.ENGLISH, "project_links.scm", null)).thenReturn("Sources");
-    when(i18n.message(Locale.ENGLISH, "project_links.scm_dev", null)).thenReturn("Developer connection");
-    when(i18n.message(Locale.ENGLISH, "project_links.ci", null)).thenReturn("Continuous integration");
-    when(i18n.message(Locale.ENGLISH, "project_links.issue", null)).thenReturn("Issues");
-
-    step = new PersistProjectLinksStep(dbClient, i18n);
-  }
-
-  @Override
-  protected ComputationStep step() {
-    return step;
-  }
-
-  @After
-  public void tearDown() {
-    session.close();
-  }
-
-  @Test
-  public void execute_only_on_projects() {
-    assertThat(step.supportedProjectQualifiers()).containsOnly("TRK");
-  }
-
-  @Test
-  public void add_links_on_project_and_module() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "empty.xml");
-
-    File reportDir = temp.newFolder();
-    // project and 1 module
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey("PROJECT_KEY")
-      .setAnalysisDate(150000000L)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setUuid("ABCD")
-      .addChildRef(2)
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar").build())
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM_DEV).setHref("scm:git:git@github.com:SonarSource/sonar.git/sonar").build())
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.ISSUE).setHref("http://jira.sonarsource.com/").build())
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.CI).setHref("http://bamboo.ci.codehaus.org/browse/SONAR").build())
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setUuid("BCDE")
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar/server").build())
-      .build());
-
-    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
-
-    dbTester.assertDbUnit(getClass(), "add_links_on_project_and_module-result.xml", "project_links");
-  }
-
-  @Test
-  public void nothing_to_do_when_link_already_exists() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "nothing_to_do_when_link_already_exists.xml");
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey("PROJECT_KEY")
-      .setAnalysisDate(150000000L)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setUuid("ABCD")
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
-      .build());
-
-    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
-
-    dbTester.assertDbUnit(getClass(), "nothing_to_do_when_link_already_exists.xml", "project_links");
-  }
-
-  @Test
-  public void do_not_add_links_on_file() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "empty.xml");
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey("PROJECT_KEY")
-      .setAnalysisDate(150000000L)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.FILE)
-      .setUuid("ABCD")
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
-      .build());
-
-    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
-
-    assertThat(dbTester.countRowsOfTable("project_links")).isEqualTo(0);
-  }
-
-  @Test
-  public void update_link() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "update_link.xml");
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey("PROJECT_KEY")
-      .setAnalysisDate(150000000L)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setUuid("ABCD")
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
-      .build());
-
-    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
-
-    dbTester.assertDbUnit(getClass(), "update_link-result.xml", "project_links");
-  }
-
-  @Test
-  public void delete_link() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "delete_link.xml");
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey("PROJECT_KEY")
-      .setAnalysisDate(150000000L)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setUuid("ABCD")
-      .build());
-
-    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
-
-    assertThat(dbTester.countRowsOfTable("project_links")).isEqualTo(0);
-  }
-
-  @Test
-  public void not_delete_custom_link() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "not_delete_custom_link.xml");
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey("PROJECT_KEY")
-      .setAnalysisDate(150000000L)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setUuid("ABCD")
-      .build());
-
-    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
-
-    dbTester.assertDbUnit(getClass(), "not_delete_custom_link.xml", "project_links");
-  }
-
-  @Test
-  public void fail_when_trying_to_add_same_link_type_multiple_times() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "empty.xml");
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey("PROJECT_KEY")
-      .setAnalysisDate(150000000L)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setUuid("ABCD")
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
-      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
-      .build());
-
-    try {
-      step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
-      failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessage("Link of type 'homepage' has already been declared on component 'ABCD'");
-    }
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationMeasuresStepTest.java
deleted file mode 100644 (file)
index aa88b17..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * 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.server.computation.step;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.batch.protocol.Constants;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReport.Range;
-import org.sonar.batch.protocol.output.BatchReportReader;
-import org.sonar.batch.protocol.output.BatchReportWriter;
-import org.sonar.core.measure.db.MetricDto;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.DbTester;
-import org.sonar.server.component.ComponentTesting;
-import org.sonar.server.computation.ComputationContext;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.measure.persistence.MeasureDao;
-import org.sonar.server.measure.persistence.MetricDao;
-import org.sonar.test.DbTests;
-
-import java.io.File;
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@Category(DbTests.class)
-public class
-  PersistDuplicationMeasuresStepTest extends BaseStepTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  File reportDir;
-
-  @ClassRule
-  public static DbTester dbTester = new DbTester();
-
-  DbSession session;
-
-  DbClient dbClient;
-
-  PersistDuplicationsStep sut;
-
-  @Before
-  public void setup() throws Exception {
-    dbTester.truncateTables();
-    session = dbTester.myBatis().openSession(false);
-    dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MeasureDao(), new MetricDao());
-
-    reportDir = temp.newFolder();
-
-    sut = new PersistDuplicationsStep(dbClient);
-  }
-
-  @Override
-  protected ComputationStep step() {
-    return sut;
-  }
-
-  @After
-  public void tearDown() {
-    session.close();
-  }
-
-  @Test
-  public void nothing_to_do_when_no_duplication() {
-    saveDuplicationMetric();
-    initReportWithProjectAndFile();
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(0);
-  }
-
-  @Test
-  public void persist_duplications_on_same_file() {
-    MetricDto duplicationMetric = saveDuplicationMetric();
-
-    BatchReportWriter writer = initReportWithProjectAndFile();
-
-    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
-      .setOriginPosition(Range.newBuilder()
-        .setStartLine(1)
-        .setEndLine(5)
-        .build())
-      .addDuplicate(BatchReport.Duplicate.newBuilder()
-        .setOtherFileRef(2)
-        .setRange(Range.newBuilder()
-          .setStartLine(6)
-          .setEndLine(10)
-          .build())
-        .build())
-      .build();
-    writer.writeComponentDuplications(2, newArrayList(duplication));
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
-
-    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", metric_id as \"metricId\", text_value as \"textValue\" from project_measures");
-    assertThat(dto.get("snapshotId")).isEqualTo(11L);
-    assertThat(dto.get("metricId")).isEqualTo(duplicationMetric.getId().longValue());
-    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file\"/></g></duplications>");
-  }
-
-  @Test
-  public void persist_duplications_on_same_file_linked_on_a_module() throws Exception {
-    saveDuplicationMetric();
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey("PROJECT_KEY")
-      .setSnapshotId(10L)
-      .addChildRef(2)
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .setSnapshotId(11L)
-      .addChildRef(3)
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.FILE)
-      .setSnapshotId(12L)
-      .setPath("file")
-      .build());
-
-    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
-      .setOriginPosition(Range.newBuilder()
-        .setStartLine(1)
-        .setEndLine(5)
-        .build())
-      .addDuplicate(BatchReport.Duplicate.newBuilder()
-        .setOtherFileRef(3)
-        .setRange(Range.newBuilder()
-          .setStartLine(6)
-          .setEndLine(10)
-          .build())
-        .build())
-      .build();
-    writer.writeComponentDuplications(3, newArrayList(duplication));
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
-
-    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
-    assertThat(dto.get("snapshotId")).isEqualTo(12L);
-    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"MODULE_KEY:file\"/><b s=\"6\" l=\"5\" r=\"MODULE_KEY:file\"/></g></duplications>");
-  }
-
-  @Test
-  public void persist_duplications_on_same_file_linked_on_a_folder() {
-    saveDuplicationMetric();
-
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey("PROJECT_KEY")
-      .setSnapshotId(10L)
-      .addChildRef(2)
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setSnapshotId(11L)
-      .addChildRef(3)
-      .setPath("dir")
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.FILE)
-      .setSnapshotId(12L)
-      .setPath("file")
-      .build());
-
-    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
-      .setOriginPosition(Range.newBuilder()
-        .setStartLine(1)
-        .setEndLine(5)
-        .build())
-      .addDuplicate(BatchReport.Duplicate.newBuilder()
-        .setOtherFileRef(3)
-        .setRange(Range.newBuilder()
-          .setStartLine(6)
-          .setEndLine(10)
-          .build())
-        .build())
-      .build();
-    writer.writeComponentDuplications(3, newArrayList(duplication));
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
-
-    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
-    assertThat(dto.get("snapshotId")).isEqualTo(12L);
-    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file\"/></g></duplications>");
-  }
-
-  @Test
-  public void persist_duplications_on_same_file_linked_on_sub_folder() {
-    saveDuplicationMetric();
-
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey("PROJECT_KEY")
-      .setSnapshotId(10L)
-      .addChildRef(2)
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setSnapshotId(11L)
-      .addChildRef(3)
-      .setPath("dir")
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setSnapshotId(12L)
-      .addChildRef(10)
-      .setPath("dir2")
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(10)
-      .setType(Constants.ComponentType.FILE)
-      .setSnapshotId(20L)
-      .setPath("file")
-      .build());
-
-    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
-      .setOriginPosition(Range.newBuilder()
-        .setStartLine(1)
-        .setEndLine(5)
-        .build())
-      .addDuplicate(BatchReport.Duplicate.newBuilder()
-        .setOtherFileRef(10)
-        .setRange(Range.newBuilder()
-          .setStartLine(6)
-          .setEndLine(10)
-          .build())
-        .build())
-      .build();
-    writer.writeComponentDuplications(10, newArrayList(duplication));
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
-
-    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
-    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file\"/></g></duplications>");
-  }
-
-  @Test
-  public void persist_duplications_on_same_file_when_a_branch_is_used() throws Exception {
-    saveDuplicationMetric();
-
-    File reportDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setBranch("origin/master")
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey("PROJECT_KEY")
-      .setSnapshotId(10L)
-      .addChildRef(2)
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.FILE)
-      .setSnapshotId(11L)
-      .setPath("file")
-      .build());
-
-    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
-      .setOriginPosition(Range.newBuilder()
-        .setStartLine(1)
-        .setEndLine(5)
-        .build())
-      .addDuplicate(BatchReport.Duplicate.newBuilder()
-        .setOtherFileRef(2)
-        .setRange(Range.newBuilder()
-          .setStartLine(6)
-          .setEndLine(10)
-          .build())
-        .build())
-      .build();
-    writer.writeComponentDuplications(2, newArrayList(duplication));
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
-
-    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
-    assertThat(dto.get("snapshotId")).isEqualTo(11L);
-    assertThat(dto.get("textValue")).isEqualTo(
-      "<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file:origin/master\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file:origin/master\"/></g></duplications>");
-  }
-
-  @Test
-  public void persist_duplications_on_different_files() {
-    saveDuplicationMetric();
-    BatchReportWriter writer = initReportWithProjectAndFile();
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.FILE)
-      .setSnapshotId(12L)
-      .setPath("file2")
-      .build());
-
-    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
-      .setOriginPosition(Range.newBuilder()
-        .setStartLine(1)
-        .setEndLine(5)
-        .build())
-      .addDuplicate(BatchReport.Duplicate.newBuilder()
-        .setOtherFileRef(3)
-        .setRange(Range.newBuilder()
-          .setStartLine(6)
-          .setEndLine(10)
-          .build())
-        .build())
-      .build();
-    writer.writeComponentDuplications(2, newArrayList(duplication));
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
-
-    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
-    assertThat(dto.get("snapshotId")).isEqualTo(11L);
-    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file2\"/></g></duplications>");
-  }
-
-  @Test
-  public void persist_duplications_on_different_projects() {
-    saveDuplicationMetric();
-    BatchReportWriter writer = initReportWithProjectAndFile();
-
-    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
-      .setOriginPosition(Range.newBuilder()
-        .setStartLine(1)
-        .setEndLine(5)
-        .build())
-      .addDuplicate(BatchReport.Duplicate.newBuilder()
-        .setOtherFileKey("PROJECT2_KEY:file2")
-        .setRange(Range.newBuilder()
-          .setStartLine(6)
-          .setEndLine(10)
-          .build())
-        .build())
-      .build();
-    writer.writeComponentDuplications(2, newArrayList(duplication));
-
-    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
-
-    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
-
-    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
-    assertThat(dto.get("snapshotId")).isEqualTo(11L);
-    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT2_KEY:file2\"/></g></duplications>");
-  }
-
-  private BatchReportWriter initReportWithProjectAndFile() {
-    BatchReportWriter writer = new BatchReportWriter(reportDir);
-    writer.writeMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey("PROJECT_KEY")
-      .setSnapshotId(10L)
-      .addChildRef(2)
-      .build());
-    writer.writeComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.FILE)
-      .setSnapshotId(11L)
-      .setPath("file")
-      .build());
-
-    return writer;
-  }
-
-  private MetricDto saveDuplicationMetric() {
-    MetricDto duplicationMetric = new MetricDto().setKey(CoreMetrics.DUPLICATIONS_DATA_KEY)
-      .setOptimizedBestValue(false)
-      .setDeleteHistoricalData(false)
-      .setHidden(false);
-    dbClient.metricDao().insert(session, duplicationMetric);
-    session.commit();
-    return duplicationMetric;
-  }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java
new file mode 100644 (file)
index 0000000..e93deaf
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ * 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.server.computation.step;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.batch.protocol.Constants;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReport.Range;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.core.measure.db.MetricDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.computation.ComputationContext;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.measure.persistence.MeasureDao;
+import org.sonar.server.measure.persistence.MetricDao;
+import org.sonar.test.DbTests;
+
+import java.io.File;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Category(DbTests.class)
+public class PersistDuplicationsStepTest extends BaseStepTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  File reportDir;
+
+  @ClassRule
+  public static DbTester dbTester = new DbTester();
+
+  DbSession session;
+
+  DbClient dbClient;
+
+  PersistDuplicationsStep sut;
+
+  @Before
+  public void setup() throws Exception {
+    dbTester.truncateTables();
+    session = dbTester.myBatis().openSession(false);
+    dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MeasureDao(), new MetricDao());
+
+    reportDir = temp.newFolder();
+
+    sut = new PersistDuplicationsStep(dbClient);
+  }
+
+  @Override
+  protected ComputationStep step() {
+    return sut;
+  }
+
+  @After
+  public void tearDown() {
+    session.close();
+  }
+
+  @Test
+  public void nothing_to_do_when_no_duplication() {
+    saveDuplicationMetric();
+    initReportWithProjectAndFile();
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(0);
+  }
+
+  @Test
+  public void persist_duplications_on_same_file() {
+    MetricDto duplicationMetric = saveDuplicationMetric();
+
+    BatchReportWriter writer = initReportWithProjectAndFile();
+
+    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
+      .setOriginPosition(Range.newBuilder()
+        .setStartLine(1)
+        .setEndLine(5)
+        .build())
+      .addDuplicate(BatchReport.Duplicate.newBuilder()
+        .setOtherFileRef(2)
+        .setRange(Range.newBuilder()
+          .setStartLine(6)
+          .setEndLine(10)
+          .build())
+        .build())
+      .build();
+    writer.writeComponentDuplications(2, newArrayList(duplication));
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
+
+    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", metric_id as \"metricId\", text_value as \"textValue\" from project_measures");
+    assertThat(dto.get("snapshotId")).isEqualTo(11L);
+    assertThat(dto.get("metricId")).isEqualTo(duplicationMetric.getId().longValue());
+    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file\"/></g></duplications>");
+  }
+
+  @Test
+  public void persist_duplications_on_same_file_linked_on_a_module() throws Exception {
+    saveDuplicationMetric();
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey("PROJECT_KEY")
+      .setSnapshotId(10L)
+      .addChildRef(2)
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.MODULE)
+      .setKey("MODULE_KEY")
+      .setSnapshotId(11L)
+      .addChildRef(3)
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(3)
+      .setType(Constants.ComponentType.FILE)
+      .setSnapshotId(12L)
+      .setPath("file")
+      .build());
+
+    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
+      .setOriginPosition(Range.newBuilder()
+        .setStartLine(1)
+        .setEndLine(5)
+        .build())
+      .addDuplicate(BatchReport.Duplicate.newBuilder()
+        .setOtherFileRef(3)
+        .setRange(Range.newBuilder()
+          .setStartLine(6)
+          .setEndLine(10)
+          .build())
+        .build())
+      .build();
+    writer.writeComponentDuplications(3, newArrayList(duplication));
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
+
+    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
+    assertThat(dto.get("snapshotId")).isEqualTo(12L);
+    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"MODULE_KEY:file\"/><b s=\"6\" l=\"5\" r=\"MODULE_KEY:file\"/></g></duplications>");
+  }
+
+  @Test
+  public void persist_duplications_on_same_file_linked_on_a_folder() {
+    saveDuplicationMetric();
+
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey("PROJECT_KEY")
+      .setSnapshotId(10L)
+      .addChildRef(2)
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.DIRECTORY)
+      .setSnapshotId(11L)
+      .addChildRef(3)
+      .setPath("dir")
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(3)
+      .setType(Constants.ComponentType.FILE)
+      .setSnapshotId(12L)
+      .setPath("file")
+      .build());
+
+    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
+      .setOriginPosition(Range.newBuilder()
+        .setStartLine(1)
+        .setEndLine(5)
+        .build())
+      .addDuplicate(BatchReport.Duplicate.newBuilder()
+        .setOtherFileRef(3)
+        .setRange(Range.newBuilder()
+          .setStartLine(6)
+          .setEndLine(10)
+          .build())
+        .build())
+      .build();
+    writer.writeComponentDuplications(3, newArrayList(duplication));
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
+
+    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
+    assertThat(dto.get("snapshotId")).isEqualTo(12L);
+    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file\"/></g></duplications>");
+  }
+
+  @Test
+  public void persist_duplications_on_same_file_linked_on_sub_folder() {
+    saveDuplicationMetric();
+
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey("PROJECT_KEY")
+      .setSnapshotId(10L)
+      .addChildRef(2)
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.DIRECTORY)
+      .setSnapshotId(11L)
+      .addChildRef(3)
+      .setPath("dir")
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(3)
+      .setType(Constants.ComponentType.DIRECTORY)
+      .setSnapshotId(12L)
+      .addChildRef(10)
+      .setPath("dir2")
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(10)
+      .setType(Constants.ComponentType.FILE)
+      .setSnapshotId(20L)
+      .setPath("file")
+      .build());
+
+    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
+      .setOriginPosition(Range.newBuilder()
+        .setStartLine(1)
+        .setEndLine(5)
+        .build())
+      .addDuplicate(BatchReport.Duplicate.newBuilder()
+        .setOtherFileRef(10)
+        .setRange(Range.newBuilder()
+          .setStartLine(6)
+          .setEndLine(10)
+          .build())
+        .build())
+      .build();
+    writer.writeComponentDuplications(10, newArrayList(duplication));
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
+
+    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
+    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file\"/></g></duplications>");
+  }
+
+  @Test
+  public void persist_duplications_on_same_file_when_a_branch_is_used() throws Exception {
+    saveDuplicationMetric();
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setBranch("origin/master")
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey("PROJECT_KEY")
+      .setSnapshotId(10L)
+      .addChildRef(2)
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.FILE)
+      .setSnapshotId(11L)
+      .setPath("file")
+      .build());
+
+    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
+      .setOriginPosition(Range.newBuilder()
+        .setStartLine(1)
+        .setEndLine(5)
+        .build())
+      .addDuplicate(BatchReport.Duplicate.newBuilder()
+        .setOtherFileRef(2)
+        .setRange(Range.newBuilder()
+          .setStartLine(6)
+          .setEndLine(10)
+          .build())
+        .build())
+      .build();
+    writer.writeComponentDuplications(2, newArrayList(duplication));
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
+
+    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
+    assertThat(dto.get("snapshotId")).isEqualTo(11L);
+    assertThat(dto.get("textValue")).isEqualTo(
+      "<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file:origin/master\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file:origin/master\"/></g></duplications>");
+  }
+
+  @Test
+  public void persist_duplications_on_different_files() {
+    saveDuplicationMetric();
+    BatchReportWriter writer = initReportWithProjectAndFile();
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(3)
+      .setType(Constants.ComponentType.FILE)
+      .setSnapshotId(12L)
+      .setPath("file2")
+      .build());
+
+    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
+      .setOriginPosition(Range.newBuilder()
+        .setStartLine(1)
+        .setEndLine(5)
+        .build())
+      .addDuplicate(BatchReport.Duplicate.newBuilder()
+        .setOtherFileRef(3)
+        .setRange(Range.newBuilder()
+          .setStartLine(6)
+          .setEndLine(10)
+          .build())
+        .build())
+      .build();
+    writer.writeComponentDuplications(2, newArrayList(duplication));
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
+
+    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
+    assertThat(dto.get("snapshotId")).isEqualTo(11L);
+    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file2\"/></g></duplications>");
+  }
+
+  @Test
+  public void persist_duplications_on_different_projects() {
+    saveDuplicationMetric();
+    BatchReportWriter writer = initReportWithProjectAndFile();
+
+    BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
+      .setOriginPosition(Range.newBuilder()
+        .setStartLine(1)
+        .setEndLine(5)
+        .build())
+      .addDuplicate(BatchReport.Duplicate.newBuilder()
+        .setOtherFileKey("PROJECT2_KEY:file2")
+        .setRange(Range.newBuilder()
+          .setStartLine(6)
+          .setEndLine(10)
+          .build())
+        .build())
+      .build();
+    writer.writeComponentDuplications(2, newArrayList(duplication));
+
+    sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));
+
+    assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);
+
+    Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
+    assertThat(dto.get("snapshotId")).isEqualTo(11L);
+    assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT2_KEY:file2\"/></g></duplications>");
+  }
+
+  private BatchReportWriter initReportWithProjectAndFile() {
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey("PROJECT_KEY")
+      .setSnapshotId(10L)
+      .addChildRef(2)
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.FILE)
+      .setSnapshotId(11L)
+      .setPath("file")
+      .build());
+
+    return writer;
+  }
+
+  private MetricDto saveDuplicationMetric() {
+    MetricDto duplicationMetric = new MetricDto().setKey(CoreMetrics.DUPLICATIONS_DATA_KEY)
+      .setOptimizedBestValue(false)
+      .setDeleteHistoricalData(false)
+      .setHidden(false);
+    dbClient.metricDao().insert(session, duplicationMetric);
+    session.commit();
+    return duplicationMetric;
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java
new file mode 100644 (file)
index 0000000..d12038b
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * 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.server.computation.step;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.i18n.I18n;
+import org.sonar.batch.protocol.Constants;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.db.ComponentLinkDao;
+import org.sonar.server.computation.ComputationContext;
+import org.sonar.server.db.DbClient;
+import org.sonar.test.DbTests;
+
+import java.io.File;
+import java.util.Locale;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@Category(DbTests.class)
+public class PersistProjectLinksStepTest extends BaseStepTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @ClassRule
+  public static DbTester dbTester = new DbTester();
+
+  DbSession session;
+
+  ComponentLinkDao dao;
+
+  I18n i18n;
+
+  PersistProjectLinksStep step;
+
+  @Before
+  public void setup() {
+    session = dbTester.myBatis().openSession(false);
+    dao = new ComponentLinkDao();
+    DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), dao);
+
+    i18n = mock(I18n.class);
+    when(i18n.message(Locale.ENGLISH, "project_links.homepage", null)).thenReturn("Home");
+    when(i18n.message(Locale.ENGLISH, "project_links.scm", null)).thenReturn("Sources");
+    when(i18n.message(Locale.ENGLISH, "project_links.scm_dev", null)).thenReturn("Developer connection");
+    when(i18n.message(Locale.ENGLISH, "project_links.ci", null)).thenReturn("Continuous integration");
+    when(i18n.message(Locale.ENGLISH, "project_links.issue", null)).thenReturn("Issues");
+
+    step = new PersistProjectLinksStep(dbClient, i18n);
+  }
+
+  @Override
+  protected ComputationStep step() {
+    return step;
+  }
+
+  @After
+  public void tearDown() {
+    session.close();
+  }
+
+  @Test
+  public void execute_only_on_projects() {
+    assertThat(step.supportedProjectQualifiers()).containsOnly("TRK");
+  }
+
+  @Test
+  public void add_links_on_project_and_module() throws Exception {
+    dbTester.prepareDbUnit(getClass(), "empty.xml");
+
+    File reportDir = temp.newFolder();
+    // project and 1 module
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setProjectKey("PROJECT_KEY")
+      .setAnalysisDate(150000000L)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setUuid("ABCD")
+      .addChildRef(2)
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar").build())
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM_DEV).setHref("scm:git:git@github.com:SonarSource/sonar.git/sonar").build())
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.ISSUE).setHref("http://jira.sonarsource.com/").build())
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.CI).setHref("http://bamboo.ci.codehaus.org/browse/SONAR").build())
+      .build());
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.MODULE)
+      .setUuid("BCDE")
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar/server").build())
+      .build());
+
+    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
+
+    dbTester.assertDbUnit(getClass(), "add_links_on_project_and_module-result.xml", "project_links");
+  }
+
+  @Test
+  public void nothing_to_do_when_link_already_exists() throws Exception {
+    dbTester.prepareDbUnit(getClass(), "nothing_to_do_when_link_already_exists.xml");
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setProjectKey("PROJECT_KEY")
+      .setAnalysisDate(150000000L)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setUuid("ABCD")
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
+      .build());
+
+    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
+
+    dbTester.assertDbUnit(getClass(), "nothing_to_do_when_link_already_exists.xml", "project_links");
+  }
+
+  @Test
+  public void do_not_add_links_on_file() throws Exception {
+    dbTester.prepareDbUnit(getClass(), "empty.xml");
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setProjectKey("PROJECT_KEY")
+      .setAnalysisDate(150000000L)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.FILE)
+      .setUuid("ABCD")
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
+      .build());
+
+    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
+
+    assertThat(dbTester.countRowsOfTable("project_links")).isEqualTo(0);
+  }
+
+  @Test
+  public void update_link() throws Exception {
+    dbTester.prepareDbUnit(getClass(), "update_link.xml");
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setProjectKey("PROJECT_KEY")
+      .setAnalysisDate(150000000L)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setUuid("ABCD")
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
+      .build());
+
+    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
+
+    dbTester.assertDbUnit(getClass(), "update_link-result.xml", "project_links");
+  }
+
+  @Test
+  public void delete_link() throws Exception {
+    dbTester.prepareDbUnit(getClass(), "delete_link.xml");
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setProjectKey("PROJECT_KEY")
+      .setAnalysisDate(150000000L)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setUuid("ABCD")
+      .build());
+
+    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
+
+    assertThat(dbTester.countRowsOfTable("project_links")).isEqualTo(0);
+  }
+
+  @Test
+  public void not_delete_custom_link() throws Exception {
+    dbTester.prepareDbUnit(getClass(), "not_delete_custom_link.xml");
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setProjectKey("PROJECT_KEY")
+      .setAnalysisDate(150000000L)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setUuid("ABCD")
+      .build());
+
+    step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
+
+    dbTester.assertDbUnit(getClass(), "not_delete_custom_link.xml", "project_links");
+  }
+
+  @Test
+  public void fail_when_trying_to_add_same_link_type_multiple_times() throws Exception {
+    dbTester.prepareDbUnit(getClass(), "empty.xml");
+
+    File reportDir = temp.newFolder();
+    BatchReportWriter writer = new BatchReportWriter(reportDir);
+    writer.writeMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(1)
+      .setProjectKey("PROJECT_KEY")
+      .setAnalysisDate(150000000L)
+      .build());
+
+    writer.writeComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setUuid("ABCD")
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
+      .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
+      .build());
+
+    try {
+      step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
+      failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Link of type 'homepage' has already been declared on component 'ABCD'");
+    }
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/add_links_on_project_and_module-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/add_links_on_project_and_module-result.xml
deleted file mode 100644 (file)
index 008f804..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<dataset>
-
-  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
-  <project_links id="2" component_uuid="ABCD" link_type="scm" name="Sources" href="https://github.com/SonarSource/sonar"/>
-  <project_links id="3" component_uuid="ABCD" link_type="scm_dev" name="Developer connection" href="scm:git:git@github.com:SonarSource/sonar.git/sonar"/>
-  <project_links id="4" component_uuid="ABCD" link_type="issue" name="Issues" href="http://jira.sonarsource.com/"/>
-  <project_links id="5" component_uuid="ABCD" link_type="ci" name="Continuous integration" href="http://bamboo.ci.codehaus.org/browse/SONAR"/>
-
-  <project_links id="6" component_uuid="BCDE" link_type="scm" name="Sources" href="https://github.com/SonarSource/sonar/server"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/delete_link.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/delete_link.xml
deleted file mode 100644 (file)
index 8b89e72..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<dataset>
-
-  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/empty.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/empty.xml
deleted file mode 100644 (file)
index 871dedc..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<dataset>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/not_delete_custom_link.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/not_delete_custom_link.xml
deleted file mode 100644 (file)
index 78c6c1d..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<dataset>
-
-  <project_links id="1" component_uuid="ABCD" link_type="custom" name="custom" href="http://www.custom.org"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/nothing_to_do_when_link_already_exists.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/nothing_to_do_when_link_already_exists.xml
deleted file mode 100644 (file)
index 8b89e72..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<dataset>
-
-  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/update_link-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/update_link-result.xml
deleted file mode 100644 (file)
index 8b89e72..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<dataset>
-
-  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/update_link.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistComponentLinksStepTest/update_link.xml
deleted file mode 100644 (file)
index d402810..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<dataset>
-
-  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonar.org"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/add_links_on_project_and_module-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/add_links_on_project_and_module-result.xml
new file mode 100644 (file)
index 0000000..008f804
--- /dev/null
@@ -0,0 +1,11 @@
+<dataset>
+
+  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
+  <project_links id="2" component_uuid="ABCD" link_type="scm" name="Sources" href="https://github.com/SonarSource/sonar"/>
+  <project_links id="3" component_uuid="ABCD" link_type="scm_dev" name="Developer connection" href="scm:git:git@github.com:SonarSource/sonar.git/sonar"/>
+  <project_links id="4" component_uuid="ABCD" link_type="issue" name="Issues" href="http://jira.sonarsource.com/"/>
+  <project_links id="5" component_uuid="ABCD" link_type="ci" name="Continuous integration" href="http://bamboo.ci.codehaus.org/browse/SONAR"/>
+
+  <project_links id="6" component_uuid="BCDE" link_type="scm" name="Sources" href="https://github.com/SonarSource/sonar/server"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/delete_link.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/delete_link.xml
new file mode 100644 (file)
index 0000000..8b89e72
--- /dev/null
@@ -0,0 +1,5 @@
+<dataset>
+
+  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/empty.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/empty.xml
new file mode 100644 (file)
index 0000000..871dedc
--- /dev/null
@@ -0,0 +1,3 @@
+<dataset>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/not_delete_custom_link.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/not_delete_custom_link.xml
new file mode 100644 (file)
index 0000000..78c6c1d
--- /dev/null
@@ -0,0 +1,5 @@
+<dataset>
+
+  <project_links id="1" component_uuid="ABCD" link_type="custom" name="custom" href="http://www.custom.org"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/nothing_to_do_when_link_already_exists.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/nothing_to_do_when_link_already_exists.xml
new file mode 100644 (file)
index 0000000..8b89e72
--- /dev/null
@@ -0,0 +1,5 @@
+<dataset>
+
+  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/update_link-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/update_link-result.xml
new file mode 100644 (file)
index 0000000..8b89e72
--- /dev/null
@@ -0,0 +1,5 @@
+<dataset>
+
+  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonarqube.org"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/update_link.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/PersistProjectLinksStepTest/update_link.xml
new file mode 100644 (file)
index 0000000..d402810
--- /dev/null
@@ -0,0 +1,5 @@
+<dataset>
+
+  <project_links id="1" component_uuid="ABCD" link_type="homepage" name="Home" href="http://www.sonar.org"/>
+
+</dataset>
index 3b85d604365a4760f5f0716418481499d8add1ef..3962cfd4ed1c750cc0a4f54f1b2553a6d2981d5a 100644 (file)
@@ -21,8 +21,16 @@ package org.sonar.batch.protocol;
 
 import com.google.protobuf.Message;
 import com.google.protobuf.Parser;
+import org.apache.commons.io.IOUtils;
 
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
 public class ProtobufUtil {
   private ProtobufUtil() {
@@ -30,36 +38,52 @@ public class ProtobufUtil {
   }
 
   public static <T extends Message> T readFile(File file, Parser<T> parser) {
-    try (InputStream input = new BufferedInputStream(new FileInputStream(file))) {
+    InputStream input = null;
+    try {
+      input = new BufferedInputStream(new FileInputStream(file));
       return parser.parseFrom(input);
     } catch (IOException e) {
       throw new IllegalStateException("Failed to read file: " + file, e);
+    } finally {
+      IOUtils.closeQuietly(input);
     }
   }
 
   public static void writeToFile(Message message, File toFile) {
-    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(toFile, false))) {
+    OutputStream out = null;
+    try {
+      out = new BufferedOutputStream(new FileOutputStream(toFile, false));
       message.writeTo(out);
     } catch (IOException e) {
       throw new IllegalStateException("Unable to write protocol buffer data to file " + toFile, e);
+    } finally {
+      IOUtils.closeQuietly(out);
     }
   }
 
   public static void appendToFile(Message message, File toFile) {
-    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(toFile, true))) {
+    OutputStream out = null;
+    try {
+      out = new BufferedOutputStream(new FileOutputStream(toFile, true));
       message.writeDelimitedTo(out);
     } catch (IOException e) {
       throw new IllegalStateException("Unable to append protocol buffer data to file " + toFile, e);
+    } finally {
+      IOUtils.closeQuietly(out);
     }
   }
 
   public static <MESSAGE extends Message> void writeMessagesToFile(Iterable<MESSAGE> messages, File file) {
-    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {
+    OutputStream out = null;
+    try {
+      out = new BufferedOutputStream(new FileOutputStream(file, true));
       for (MESSAGE message : messages) {
         message.writeDelimitedTo(out);
       }
     } catch (IOException e) {
       throw new IllegalStateException("Failed to read file: " + file, e);
+    } finally {
+      IOUtils.closeQuietly(out);
     }
   }