]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5685 Fail to restore profile with duplicated rule keys
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Thu, 16 Apr 2015 15:44:52 +0000 (17:44 +0200)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Fri, 17 Apr 2015 14:54:28 +0000 (16:54 +0200)
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackuper.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperMediumTest.java
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileBackuperMediumTest/duplicates-xml-backup.xml [new file with mode: 0644]

index 5110006f25c8e145810fea5439757b0c3c2c8d44..87e0ab6929a0170f6e86ef787a347d84bf099c74 100644 (file)
  */
 package org.sonar.server.qualityprofile;
 
+import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
 import org.codehaus.staxmate.SMInputFactory;
@@ -44,6 +46,7 @@ import java.io.Writer;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 public class QProfileBackuper implements ServerComponent {
 
@@ -51,6 +54,8 @@ public class QProfileBackuper implements ServerComponent {
   private final DbClient db;
   private final IndexClient index;
 
+  private static final Joiner RULEKEY_JOINER = Joiner.on(", ").skipNulls();
+
   public QProfileBackuper(QProfileReset reset, DbClient db, IndexClient index) {
     this.reset = reset;
     this.db = db;
@@ -134,6 +139,8 @@ public class QProfileBackuper implements ServerComponent {
 
   private List<RuleActivation> parseRuleActivations(SMInputCursor rulesCursor) throws XMLStreamException {
     List<RuleActivation> activations = Lists.newArrayList();
+    Set<RuleKey> activatedKeys = Sets.newHashSet();
+    List<RuleKey> duplicatedKeys = Lists.newArrayList();
     while (rulesCursor.getNext() != null) {
       SMInputCursor ruleCursor = rulesCursor.childElementCursor();
       String repositoryKey = null, key = null, severity = null;
@@ -155,11 +162,19 @@ public class QProfileBackuper implements ServerComponent {
         }
       }
       RuleKey ruleKey = RuleKey.of(repositoryKey, key);
+      if (activatedKeys.contains(ruleKey)) {
+        duplicatedKeys.add(ruleKey);
+      }
+      activatedKeys.add(ruleKey);
       RuleActivation activation = new RuleActivation(ruleKey);
       activation.setSeverity(severity);
       activation.setParameters(parameters);
       activations.add(activation);
     }
+    if (!duplicatedKeys.isEmpty()) {
+      throw new IllegalArgumentException("The quality profile cannot be restored as it contains duplicates for the following rules: " +
+        RULEKEY_JOINER.join(duplicatedKeys));
+    }
     return activations;
   }
 
index 0debd26b199179c099b167927fe17b93c9fca020..489de2a04055dc3072971f8a68f75244df796183 100644 (file)
@@ -269,6 +269,17 @@ public class QProfileBackuperMediumTest {
     }
   }
 
+  @Test
+  public void fail_to_restore_if_duplicate_rule() throws Exception {
+    try {
+      tester.get(QProfileBackuper.class).restore(new StringReader(
+        Resources.toString(getClass().getResource("QProfileBackuperMediumTest/duplicates-xml-backup.xml"), Charsets.UTF_8)), null);
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("The quality profile cannot be restored as it contains duplicates for the following rules: xoo:x1, xoo:x2");
+    }
+  }
+
   @Test
   public void restore_and_override_profile_name() throws Exception {
     tester.get(QProfileBackuper.class).restore(new StringReader(
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileBackuperMediumTest/duplicates-xml-backup.xml b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileBackuperMediumTest/duplicates-xml-backup.xml
new file mode 100644 (file)
index 0000000..4a41aa0
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<profile>
+  <name>P1</name>
+  <language>xoo</language>
+  <rules>
+    <rule>
+      <repositoryKey>xoo</repositoryKey>
+      <key>x1</key>
+      <priority>BLOCKER</priority>
+      <parameters>
+        <parameter>
+          <key>max</key>
+          <value>7</value>
+        </parameter>
+      </parameters>
+    </rule>
+    <rule>
+      <repositoryKey>xoo</repositoryKey>
+      <key>x2</key>
+      <priority>CRITICAL</priority>
+    </rule>
+    <rule>
+      <repositoryKey>xoo</repositoryKey>
+      <key>x1</key>
+      <priority>MAJOR</priority>
+      <parameters>
+        <parameter>
+          <key>max</key>
+          <value>5</value>
+        </parameter>
+      </parameters>
+    </rule>
+    <rule>
+      <repositoryKey>xoo</repositoryKey>
+      <key>x2</key>
+      <priority>MINOR</priority>
+    </rule>
+    
+  </rules>
+</profile>