summaryrefslogtreecommitdiffstats
path: root/sonar-server/src
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@gmail.com>2013-09-25 18:54:57 +0200
committerJulien Lancelot <julien.lancelot@gmail.com>2013-09-25 18:54:57 +0200
commit4e3786d295d26ab8a1cd94e95e807b011826a102 (patch)
treeff2debb8c195ced200451f6a1133c6dbbb5b3ac2 /sonar-server/src
parentc97ca353626ee2b55e95590e4dbbdb4d3a6f7ce4 (diff)
downloadsonarqube-4e3786d295d26ab8a1cd94e95e807b011826a102.tar.gz
sonarqube-4e3786d295d26ab8a1cd94e95e807b011826a102.zip
SONAR-4357 Reset technical debt model
Diffstat (limited to 'sonar-server/src')
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java13
-rw-r--r--sonar-server/src/main/java/org/sonar/server/startup/RegisterTechnicalDebtModel.java (renamed from sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelDefinition.java)19
-rw-r--r--sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtManager.java90
-rw-r--r--sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinder.java24
-rw-r--r--sonar-server/src/main/java/org/sonar/server/technicaldebt/XMLImporter.java6
-rw-r--r--sonar-server/src/main/resources/com/sonar/sqale/technical-debt-model.xml (renamed from sonar-server/src/main/java/com/sonar/sqale/technical-debt-model.xml)0
-rw-r--r--sonar-server/src/test/java/org/sonar/server/startup/RegisterTechnicalDebtModelTest.java (renamed from sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelDefinitionTest.java)12
-rw-r--r--sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtManagerTest.java168
-rw-r--r--sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinderTest.java9
-rw-r--r--sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelTest.java9
-rw-r--r--sonar-server/src/test/java/org/sonar/server/technicaldebt/XMLImporterTest.java3
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution-result.xml16
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution.xml2
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution-result.xml34
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution.xml2
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model-result.xml56
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model.xml38
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model-with-additionnale-characteristic.xml80
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model.xml18
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge-result.xml19
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge.xml12
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore-result.xml21
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore.xml15
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/reset_model.xml3
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/warn_when_restoring_unknown_rule-result.xml2
25 files changed, 387 insertions, 284 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index 9949cb18e2e..6e2f73aaae1 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -75,10 +75,10 @@ import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
import org.sonar.server.configuration.Backup;
import org.sonar.server.configuration.ProfilesManager;
-import org.sonar.server.db.migrations.DatabaseMigration;
-import org.sonar.server.db.migrations.DatabaseMigrator;
import org.sonar.server.db.EmbeddedDatabaseFactory;
+import org.sonar.server.db.migrations.DatabaseMigration;
import org.sonar.server.db.migrations.DatabaseMigrations;
+import org.sonar.server.db.migrations.DatabaseMigrator;
import org.sonar.server.issue.*;
import org.sonar.server.notifications.NotificationCenter;
import org.sonar.server.notifications.NotificationService;
@@ -90,6 +90,9 @@ import org.sonar.server.rule.RubyRuleService;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
import org.sonar.server.startup.*;
+import org.sonar.server.technicaldebt.TechnicalDebtManager;
+import org.sonar.server.technicaldebt.TechnicalDebtModelFinder;
+import org.sonar.server.technicaldebt.XMLImporter;
import org.sonar.server.text.MacroInterpreter;
import org.sonar.server.text.RubyTextService;
import org.sonar.server.ui.*;
@@ -307,6 +310,11 @@ public final class Platform {
// rules
servicesContainer.addSingleton(RubyRuleService.class);
+ // technical debt
+ servicesContainer.addSingleton(TechnicalDebtManager.class);
+ servicesContainer.addSingleton(TechnicalDebtModelFinder.class);
+ servicesContainer.addSingleton(XMLImporter.class);
+
// text
servicesContainer.addSingleton(MacroInterpreter.class);
servicesContainer.addSingleton(RubyTextService.class);
@@ -337,6 +345,7 @@ public final class Platform {
startupContainer.addSingleton(RegisterNewProfiles.class);
startupContainer.addSingleton(JdbcDriverDeployer.class);
startupContainer.addSingleton(RegisterQualityModels.class);
+// startupContainer.addSingleton(RegisterTechnicalDebtModel.class);
startupContainer.addSingleton(DeleteDeprecatedMeasures.class);
startupContainer.addSingleton(GeneratePluginIndex.class);
startupContainer.addSingleton(GenerateBootstrapIndex.class);
diff --git a/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelDefinition.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterTechnicalDebtModel.java
index 17da4ae421c..645082c8a84 100644
--- a/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelDefinition.java
+++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterTechnicalDebtModel.java
@@ -17,30 +17,31 @@
* 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.technicaldebt;
+package org.sonar.server.startup;
-import org.sonar.api.qualitymodel.Model;
-import org.sonar.api.qualitymodel.ModelDefinition;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.utils.ValidationMessages;
+import org.sonar.server.technicaldebt.RuleCache;
+import org.sonar.server.technicaldebt.TechnicalDebtManager;
-public final class TechnicalDebtModelDefinition extends ModelDefinition {
+public final class RegisterTechnicalDebtModel {
public static final String TECHNICAL_DEBT_MODEL = "TECHNICAL_DEBT";
private final TechnicalDebtManager technicalDebtManager;
private final RuleFinder ruleFinder;
- public TechnicalDebtModelDefinition(TechnicalDebtManager technicalDebtManager, RuleFinder ruleFinder) {
- super(TECHNICAL_DEBT_MODEL);
+ /**
+ * @param registerRulesBeforeModels used only to be started after the creation of check templates
+ */
+ public RegisterTechnicalDebtModel(TechnicalDebtManager technicalDebtManager, RuleFinder ruleFinder, RegisterRules registerRulesBeforeModels) {
this.technicalDebtManager = technicalDebtManager;
this.ruleFinder = ruleFinder;
}
- @Override
- public Model createModel() {
+ public void start() {
RuleCache ruleCache = new RuleCache(ruleFinder);
- return technicalDebtManager.createInitialModel(ValidationMessages.create(), ruleCache);
+ technicalDebtManager.reset(ValidationMessages.create(), ruleCache);
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtManager.java b/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtManager.java
index e4bf7f73cf0..5387b1d9178 100644
--- a/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtManager.java
+++ b/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtManager.java
@@ -29,10 +29,10 @@ import org.sonar.api.qualitymodel.Model;
import org.sonar.api.qualitymodel.ModelFinder;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.jpa.session.DatabaseSessionFactory;
+import org.sonar.server.startup.RegisterTechnicalDebtModel;
import java.io.Reader;
import java.util.Collection;
-import java.util.List;
/**
* TODO test merge properties + property.value + text_value
@@ -42,6 +42,8 @@ public class TechnicalDebtManager implements ServerExtension {
private static final Logger LOG = LoggerFactory.getLogger(TechnicalDebtManager.class);
+ private static final int REQUIREMENT_LEVEL = 3;
+
private DatabaseSessionFactory sessionFactory;
private ModelFinder modelFinder;
private TechnicalDebtModelFinder languageModelFinder;
@@ -55,69 +57,30 @@ public class TechnicalDebtManager implements ServerExtension {
this.importer = importer;
}
- public void restore(Model model, ValidationMessages messages, RuleCache rulesCache) {
- Model persisted = modelFinder.findByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- if (persisted != null) {
- disable(persisted);
- }
- merge(model, messages, rulesCache);
- }
-
- public Model resetModel(ValidationMessages messages, RuleCache ruleCache) {
- Model persisted = modelFinder.findByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- if (persisted != null) {
- disable(persisted);
- }
+ public Model reset(ValidationMessages messages, RuleCache rulesCache) {
+ DatabaseSession session = sessionFactory.getSession();
- Model model = modelFinder.findByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- importDefaultSqaleModel(model, messages, ruleCache);
- populateModelWithInitialValues(model, messages, ruleCache);
+ resetExistingModel();
+ Model model = populateModel(messages, rulesCache);
- DatabaseSession session = sessionFactory.getSession();
session.save(model);
session.commit();
-
return model;
}
- public Model createInitialModel(ValidationMessages messages, RuleCache ruleCache) {
- Model initialModel = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- importDefaultSqaleModel(initialModel, messages, ruleCache);
- populateModelWithInitialValues(initialModel, messages, ruleCache);
- return initialModel;
- }
-
- public void merge(List<String> pluginKeys, ValidationMessages messages, RuleCache ruleCache) {
- for (String pluginKey : pluginKeys) {
- ValidationMessages currentMessages = ValidationMessages.create();
- Model model = null;
- Reader xmlFileReader = null;
- try {
- xmlFileReader = languageModelFinder.createReaderForXMLFile(pluginKey);
- model = importer.importXML(xmlFileReader, currentMessages, ruleCache);
- } finally {
- IOUtils.closeQuietly(xmlFileReader);
- }
- if (!currentMessages.hasErrors()) {
- merge(model, messages, ruleCache);
- } else {
- for (String error : currentMessages.getErrors()) {
- messages.addErrorText(error);
- }
- }
- }
+ private Model populateModel(ValidationMessages messages, RuleCache ruleCache) {
+ Model model = getModel();
+ importDefaultModel(model, messages, ruleCache);
+ populateModelWithInitialValues(model, messages, ruleCache);
+ return model;
}
- public void merge(Model with, ValidationMessages messages, RuleCache ruleCache) {
- DatabaseSession session = sessionFactory.getSession();
- Model sqale = modelFinder.findByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- if (sqale == null) {
- sqale = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- session.saveWithoutFlush(sqale);
+ private Model getModel() {
+ Model existingModel = modelFinder.findByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
+ if (existingModel == null) {
+ return Model.createByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
}
- new TechnicalDebtModel(sqale).mergeWith(with, messages, ruleCache);
- session.saveWithoutFlush(sqale);
- session.commit();
+ return existingModel;
}
private void populateModelWithInitialValues(Model initialModel, ValidationMessages messages, RuleCache ruleCache) {
@@ -126,12 +89,15 @@ public class TechnicalDebtManager implements ServerExtension {
}
}
+ private void importDefaultModel(Model initialModel, ValidationMessages messages, RuleCache ruleCache) {
+ mergePlugin(initialModel, TechnicalDebtModelFinder.DEFAULT_MODEL, messages, ruleCache);
+ }
+
private void mergePlugin(Model initialModel, String pluginKey, ValidationMessages messages, RuleCache ruleCache) {
Model model = null;
Reader xmlFileReader = null;
try {
xmlFileReader = languageModelFinder.createReaderForXMLFile(pluginKey);
-
model = importer.importXML(xmlFileReader, messages, ruleCache);
} finally {
IOUtils.closeQuietly(xmlFileReader);
@@ -143,18 +109,18 @@ public class TechnicalDebtManager implements ServerExtension {
}
}
- private void disable(Model persisted) {
- for (Characteristic root : persisted.getRootCharacteristics()) {
- persisted.removeCharacteristic(root);
+ private void resetExistingModel() {
+ Model existingModel = modelFinder.findByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
+ if (existingModel != null) {
+ for (Characteristic root : existingModel.getCharacteristicsByDepth(REQUIREMENT_LEVEL)) {
+ existingModel.removeCharacteristic(root);
+ }
+ sessionFactory.getSession().commit();
}
- sessionFactory.getSession().commit();
}
private Collection<String> getContributingPluginListWithoutSqale(){
return languageModelFinder.getContributingPluginList();
}
- private void importDefaultSqaleModel(Model initialModel, ValidationMessages messages, RuleCache ruleCache) {
- mergePlugin(initialModel, TechnicalDebtModelFinder.DEFAULT_MODEL, messages, ruleCache);
- }
}
diff --git a/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinder.java b/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinder.java
index f893f4ce6be..a90a38a65ea 100644
--- a/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinder.java
+++ b/sonar-server/src/main/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinder.java
@@ -55,10 +55,6 @@ public class TechnicalDebtModelFinder implements ServerExtension, Startable {
private PluginRepository pluginRepository;
private Map<String, ClassLoader> contributingPluginKeyToClassLoader;
- /**
- *
- * @param pluginRepository
- */
public TechnicalDebtModelFinder(PluginRepository pluginRepository) {
this.pluginRepository = pluginRepository;
this.xmlFilePrefix = XML_FILE_PREFIX;
@@ -90,20 +86,23 @@ public class TechnicalDebtModelFinder implements ServerExtension, Startable {
for (PluginMetadata metadata : pluginRepository.getMetadata()) {
String pluginKey = metadata.getKey();
ClassLoader classLoader = pluginRepository.getPlugin(pluginKey).getClass().getClassLoader();
- if (classLoader.getResource(getXMLFilePathForPlugin(pluginKey)) != null) {
+ if (classLoader.getResource(getXMLFilePath(pluginKey)) != null) {
contributingPluginKeyToClassLoader.put(pluginKey, classLoader);
}
}
+ // Add default model
+ contributingPluginKeyToClassLoader.put(DEFAULT_MODEL, getClass().getClassLoader());
}
contributingPluginKeyToClassLoader = Collections.unmodifiableMap(contributingPluginKeyToClassLoader);
}
- protected String getXMLFilePathForPlugin(String pluginKey) {
- return xmlFilePrefix + pluginKey + XML_FILE_SUFFIX;
+ @VisibleForTesting
+ String getXMLFilePath(String model) {
+ return xmlFilePrefix + model + XML_FILE_SUFFIX;
}
/**
- * Returns the list of plugins that can contribute to the SQALE model (without the default model provided by this plugin).
+ * Returns the list of plugins that can contribute to the technical debt model (without the default model).
*
* @return the list of plugin keys
*/
@@ -115,16 +114,21 @@ public class TechnicalDebtModelFinder implements ServerExtension, Startable {
/**
* Creates a new {@link java.io.Reader} for the XML file that contains the model contributed by the given plugin.
- *
+ *
* @param pluginKey the key of the plugin that contributes the XML file
* @return the reader, that must be closed once its use is finished.
*/
public Reader createReaderForXMLFile(String pluginKey) {
ClassLoader classLoader = contributingPluginKeyToClassLoader.get(pluginKey);
- String xmlFilePath = getXMLFilePathForPlugin(pluginKey);
+ String xmlFilePath = getXMLFilePath(pluginKey);
return new InputStreamReader(classLoader.getResourceAsStream(xmlFilePath));
}
+ @VisibleForTesting
+ Map<String, ClassLoader> getContributingPluginKeyToClassLoader(){
+ return contributingPluginKeyToClassLoader;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/sonar-server/src/main/java/org/sonar/server/technicaldebt/XMLImporter.java b/sonar-server/src/main/java/org/sonar/server/technicaldebt/XMLImporter.java
index 95e81e2e22a..8ffa024f8de 100644
--- a/sonar-server/src/main/java/org/sonar/server/technicaldebt/XMLImporter.java
+++ b/sonar-server/src/main/java/org/sonar/server/technicaldebt/XMLImporter.java
@@ -33,6 +33,7 @@ import org.sonar.api.qualitymodel.Characteristic;
import org.sonar.api.qualitymodel.Model;
import org.sonar.api.rules.Rule;
import org.sonar.api.utils.ValidationMessages;
+import org.sonar.server.startup.RegisterTechnicalDebtModel;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
@@ -50,7 +51,7 @@ public class XMLImporter implements ServerExtension {
}
public Model importXML(Reader xml, ValidationMessages messages, RuleCache repositoryCache) {
- Model sqale = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
+ Model sqale = Model.createByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
try {
SMInputFactory inputFactory = initStax();
SMHierarchicCursor cursor = inputFactory.rootElementCursor(xml);
@@ -81,8 +82,7 @@ public class XMLImporter implements ServerExtension {
return new SMInputFactory(xmlFactory);
}
- private Characteristic processCharacteristic(Model sqale, SMInputCursor chcCursor, ValidationMessages messages,
- RuleCache ruleCache) throws XMLStreamException {
+ private Characteristic processCharacteristic(Model sqale, SMInputCursor chcCursor, ValidationMessages messages, RuleCache ruleCache) throws XMLStreamException {
Characteristic characteristic = Characteristic.create();
SMInputCursor cursor = chcCursor.childElementCursor();
diff --git a/sonar-server/src/main/java/com/sonar/sqale/technical-debt-model.xml b/sonar-server/src/main/resources/com/sonar/sqale/technical-debt-model.xml
index 2a35e4f003f..2a35e4f003f 100644
--- a/sonar-server/src/main/java/com/sonar/sqale/technical-debt-model.xml
+++ b/sonar-server/src/main/resources/com/sonar/sqale/technical-debt-model.xml
diff --git a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelDefinitionTest.java b/sonar-server/src/test/java/org/sonar/server/startup/RegisterTechnicalDebtModelTest.java
index 5864323ad8f..e2f5596a562 100644
--- a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelDefinitionTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/startup/RegisterTechnicalDebtModelTest.java
@@ -17,25 +17,27 @@
* 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.technicaldebt;
+package org.sonar.server.startup;
import org.junit.Test;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.utils.ValidationMessages;
+import org.sonar.server.technicaldebt.RuleCache;
+import org.sonar.server.technicaldebt.TechnicalDebtManager;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
-public class TechnicalDebtModelDefinitionTest {
+public class RegisterTechnicalDebtModelTest {
@Test
public void shouldCreateModel() throws Exception {
TechnicalDebtManager technicalDebtManager = mock(TechnicalDebtManager.class);
RuleFinder ruleFinder = mock(RuleFinder.class);
- TechnicalDebtModelDefinition sqaleDefinition = new TechnicalDebtModelDefinition(technicalDebtManager, ruleFinder);
+ RegisterTechnicalDebtModel sqaleDefinition = new RegisterTechnicalDebtModel(technicalDebtManager, ruleFinder, null);
- sqaleDefinition.createModel();
+ sqaleDefinition.start();
- verify(technicalDebtManager, times(1)).createInitialModel(any(ValidationMessages.class), any(RuleCache.class));
+ verify(technicalDebtManager, times(1)).reset(any(ValidationMessages.class), any(RuleCache.class));
}
}
diff --git a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtManagerTest.java b/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtManagerTest.java
index 2472c1d3ae1..099387fa9d7 100644
--- a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtManagerTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtManagerTest.java
@@ -20,7 +20,6 @@
package org.sonar.server.technicaldebt;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import org.junit.Before;
import org.junit.Test;
@@ -45,146 +44,112 @@ import static org.mockito.Mockito.when;
public class TechnicalDebtManagerTest extends AbstractDbUnitTestCase {
private TechnicalDebtManager manager;
- private TechnicalDebtModelFinder TechnicalDebtModelFinder;
+ private TechnicalDebtModelFinder technicalDebtModelFinder = mock(TechnicalDebtModelFinder.class);
@Before
public void init() throws Exception {
- TechnicalDebtModelFinder = mock(TechnicalDebtModelFinder.class);
- when(TechnicalDebtModelFinder.getContributingPluginList()).thenReturn(ImmutableList.of("java", "technical-debt"));
- when(TechnicalDebtModelFinder.createReaderForXMLFile("java")).thenReturn(
+ technicalDebtModelFinder = mock(TechnicalDebtModelFinder.class);
+ when(technicalDebtModelFinder.getContributingPluginList()).thenReturn(ImmutableList.of("java"));
+ when(technicalDebtModelFinder.createReaderForXMLFile("java")).thenReturn(
new FileReader(Resources.getResource(TechnicalDebtManagerTest.class, "TechnicalDebtManagerTest/fake-java-model.xml").getPath()));
- // Mock default sqale model
- when(TechnicalDebtModelFinder.createReaderForXMLFile("technical-debt")).thenReturn(
+ // Mock default model
+ when(technicalDebtModelFinder.createReaderForXMLFile("technical-debt")).thenReturn(
new FileReader(Resources.getResource(TechnicalDebtManagerTest.class, "TechnicalDebtManagerTest/fake-default-model.xml").getPath()));
- manager = new TechnicalDebtManager(getSessionFactory(), new DefaultModelFinder(getSessionFactory()), TechnicalDebtModelFinder, new XMLImporter());
+ manager = new TechnicalDebtManager(getSessionFactory(), new DefaultModelFinder(getSessionFactory()), technicalDebtModelFinder, new XMLImporter());
}
@Test
- public void reset_model() {
- setupData("reset_model");
+ public void create_only_default_model_on_first_execution_when_no_plugin() throws Exception {
+ setupData("create_default_model_on_first_execution");
- Model model = manager.resetModel(ValidationMessages.create(), defaultRuleCache());
- assertThat(model.getCharacteristics().size()).isGreaterThan(3);
- assertThat(model.getCharacteristics().size()).isGreaterThan(model.getRootCharacteristics().size());
- for (Characteristic portabilityCharacteristic : model.getCharacteristicByKey("PORTABILITY").getChildren()) {
- assertThat(portabilityCharacteristic.getName()).contains("portability");
- Characteristic requirement = portabilityCharacteristic.getChildren().get(0);
- assertThat(requirement).isNotNull();
- Rule rule = requirement.getRule();
- assertThat(rule).isNotNull();
- assertThat(rule.getName()).isEqualTo("Regular exp");
- }
- assertThat(model.getCharacteristicByKey("testability")).isNull();
- assertThat(model.getCharacteristicByKey("unit_testability")).isNull();
+ TechnicalDebtModelFinder technicalDebtModelFinder = mock(TechnicalDebtModelFinder.class);
+ when(technicalDebtModelFinder.createReaderForXMLFile("technical-debt")).thenReturn(
+ new FileReader(Resources.getResource(TechnicalDebtManagerTest.class, "TechnicalDebtManagerTest/fake-default-model.xml").getPath()));
+
+ TechnicalDebtManager manager = new TechnicalDebtManager(getSessionFactory(), new DefaultModelFinder(getSessionFactory()), technicalDebtModelFinder, new XMLImporter());
+ manager.reset(ValidationMessages.create(), defaultRuleCache());
+ getSession().commit();
+
+ checkTables("create_default_model_on_first_execution", "quality_models", "characteristics", "characteristic_edges");
}
@Test
- public void provided_plugin_should_not_override_default_model_when_resetting_model() throws FileNotFoundException {
- setupData("reset_model");
+ public void create_model_with_requirements_from_plugin_on_first_execution() throws Exception {
+ setupData("create_model_with_requirements_from_plugin_on_first_execution");
- Model model = manager.resetModel(ValidationMessages.create(), defaultRuleCache());
- // Default model values
- assertThat(model.getCharacteristicByKey("PORTABILITY").getName()).isEqualTo("Portability");
- assertThat(model.getCharacteristicByKey("COMPILER_RELATED_PORTABILITY").getName()).isEqualTo("Compiler related portability");
- assertThat(model.getCharacteristicByKey("HARDWARE_RELATED_PORTABILITY").getName()).isEqualTo("Hardware related portability");
- assertThat(model.getCharacteristicByKey("MAINTAINABILITY").getName()).isEqualTo("Maintainability");
+ TechnicalDebtModelFinder technicalDebtModelFinder = mock(TechnicalDebtModelFinder.class);
- // Plugin has renamed it the value stay as defined by default model
- assertThat(model.getCharacteristicByKey("READABILITY").getName()).isEqualTo("Readability");
+ when(technicalDebtModelFinder.getContributingPluginList()).thenReturn(ImmutableList.of("java"));
+ when(technicalDebtModelFinder.createReaderForXMLFile("java")).thenReturn(
+ new FileReader(Resources.getResource(TechnicalDebtManagerTest.class, "TechnicalDebtManagerTest/fake-java-model.xml").getPath()));
+ when(technicalDebtModelFinder.createReaderForXMLFile("technical-debt")).thenReturn(
+ new FileReader(Resources.getResource(TechnicalDebtManagerTest.class, "TechnicalDebtManagerTest/fake-default-model.xml").getPath()));
+
+ RuleCache ruleCache = mock(RuleCache.class);
+ Rule rule1 = Rule.create("checkstyle", "import", "Regular expression");
+ rule1.setId(1);
+ when(ruleCache.getRule("checkstyle", "import")).thenReturn(rule1);
+ Rule rule2 = Rule.create("checkstyle", "export", "Regular expression");
+ rule2.setId(2);
+ when(ruleCache.getRule("checkstyle", "export")).thenReturn(rule2);
- // Characteristic provided only by the plugin
- assertThat(model.getCharacteristicByKey("UNDERSTANDABILITY").getName()).isEqualTo("Understandability related maintainability");
+ TechnicalDebtManager manager = new TechnicalDebtManager(getSessionFactory(), new DefaultModelFinder(getSessionFactory()), technicalDebtModelFinder, new XMLImporter());
+ manager.reset(ValidationMessages.create(), ruleCache);
+ getSession().commit();
+
+ checkTables("create_model_with_requirements_from_plugin_on_first_execution", "quality_models", "characteristics", "characteristic_edges", "characteristic_properties");
}
@Test
- public void not_fail_if_unknown_rule_when_resetting_model() {
- setupData("reset_model");
+ public void disable_characteristics_and_remove_requirements_when_resetting_model() throws Exception {
+ setupData("disable_characteristics_and_remove_requirements_when_resetting_model");
- RuleFinder ruleFinder = mock(RuleFinder.class);
- when(ruleFinder.findByKey(anyString(), anyString())).thenReturn(null);
+ TechnicalDebtModelFinder technicalDebtModelFinder = mock(TechnicalDebtModelFinder.class);
- manager = new TechnicalDebtManager(getSessionFactory(), new DefaultModelFinder(getSessionFactory()),
- TechnicalDebtModelFinder, new XMLImporter());
+ when(technicalDebtModelFinder.getContributingPluginList()).thenReturn(ImmutableList.of("java"));
+ when(technicalDebtModelFinder.createReaderForXMLFile("java")).thenReturn(
+ new FileReader(Resources.getResource(TechnicalDebtManagerTest.class, "TechnicalDebtManagerTest/fake-java-model.xml").getPath()));
+ when(technicalDebtModelFinder.createReaderForXMLFile("technical-debt")).thenReturn(
+ new FileReader(Resources.getResource(TechnicalDebtManagerTest.class, "TechnicalDebtManagerTest/fake-default-model.xml").getPath()));
- Model model = manager.resetModel(ValidationMessages.create(), new RuleCache(ruleFinder));
- assertThat(model.getCharacteristics().size()).isGreaterThanOrEqualTo(3);
- assertThat(model.getCharacteristics().size()).isGreaterThan(model.getRootCharacteristics().size());
- List<Characteristic> hardwareControls = model.getCharacteristicByKey("HARDWARE_RELATED_PORTABILITY").getChildren();
- assertThat(hardwareControls.isEmpty()).isTrue();
+ TechnicalDebtManager manager = new TechnicalDebtManager(getSessionFactory(), new DefaultModelFinder(getSessionFactory()), technicalDebtModelFinder, new XMLImporter());
+ manager.reset(ValidationMessages.create(), defaultRuleCache());
+ getSession().commit();
+
+ checkTables("disable_characteristics_and_remove_requirements_when_resetting_model", "quality_models", "characteristics", "characteristic_edges", "characteristic_properties");
}
@Test
- public void create_initial_model() {
- Model model = manager.createInitialModel(ValidationMessages.create(), defaultRuleCache());
-
+ public void provided_plugin_should_not_override_default_model_when_resetting_model() throws FileNotFoundException {
+ Model model = manager.reset(ValidationMessages.create(), defaultRuleCache());
// Default model values
assertThat(model.getCharacteristicByKey("PORTABILITY").getName()).isEqualTo("Portability");
assertThat(model.getCharacteristicByKey("COMPILER_RELATED_PORTABILITY").getName()).isEqualTo("Compiler related portability");
assertThat(model.getCharacteristicByKey("HARDWARE_RELATED_PORTABILITY").getName()).isEqualTo("Hardware related portability");
assertThat(model.getCharacteristicByKey("MAINTAINABILITY").getName()).isEqualTo("Maintainability");
- // Plugin has renamed it the value stay as defined by default model
+ // Plugin has renamed it, but the value should stay as defined by default model
assertThat(model.getCharacteristicByKey("READABILITY").getName()).isEqualTo("Readability");
-
- // Characteristic provided only by the plugin
- assertThat(model.getCharacteristicByKey("UNDERSTANDABILITY").getName()).isEqualTo("Understandability related maintainability");
- }
-
- @Test
- public void persist_merge() {
- setupData("persist_merge");
-
- Model with = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- Characteristic efficiency = with.createCharacteristicByKey("efficiency", "Efficiency");
- Characteristic ramEfficiency = with.createCharacteristicByKey("ram-efficiency", "RAM Efficiency");
- efficiency.addChild(ramEfficiency);
- ramEfficiency.addChild(with.createCharacteristicByRule(newRegexpRule()));
-
- manager.merge(with, ValidationMessages.create(), defaultRuleCache());
-
- checkTables("persist_merge", "quality_models", "characteristics", "characteristic_edges");
- }
-
- @Test
- public void persist_merge_with_plugin_files() throws Exception {
- setupData("persist_merge");
-
- manager.merge(Lists.newArrayList("java"), ValidationMessages.create(), defaultRuleCache());
-
- Model model = (new DefaultModelFinder(getSessionFactory())).findByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- assertThat(model.getCharacteristics()).contains(Characteristic.createByKey("PORTABILITY", "Portability"));
}
@Test
- public void persist_restore() {
- setupData("persist_restore");
-
- Model with = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- Characteristic efficiency = with.createCharacteristicByKey("efficiency", "Efficiency");
- Characteristic ramEfficiency = with.createCharacteristicByKey("ram-efficiency", "RAM Efficiency");
- efficiency.addChild(ramEfficiency);
- ramEfficiency.addChild(with.createCharacteristicByRule(newRegexpRule()));
-
- manager.restore(with, ValidationMessages.create(), defaultRuleCache());
-
- checkTables("persist_restore", "quality_models", "characteristics", "characteristic_edges");
- }
+ public void no_failure_on_unknown_rule_when_resetting_model() {
+ setupData("reset_model");
- @Test
- public void warn_when_restoring_unknown_rule() {
- setupData("warn_when_restoring_unknown_rule");
+ RuleFinder ruleFinder = mock(RuleFinder.class);
+ when(ruleFinder.findByKey(anyString(), anyString())).thenReturn(null);
- Model with = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
- Characteristic efficiency = with.createCharacteristicByKey("efficiency", "Efficiency");
- efficiency.addChild(with.createCharacteristicByRule(newRegexpRule()));
+ manager = new TechnicalDebtManager(getSessionFactory(), new DefaultModelFinder(getSessionFactory()), technicalDebtModelFinder, new XMLImporter());
ValidationMessages messages = ValidationMessages.create();
- manager.restore(with, messages, defaultRuleCache());
+ Model model = manager.reset(messages, new RuleCache(ruleFinder));
+ assertThat(model.getCharacteristics().size()).isGreaterThanOrEqualTo(3);
+ assertThat(model.getCharacteristics().size()).isGreaterThan(model.getRootCharacteristics().size());
+ List<Characteristic> hardwareControls = model.getCharacteristicByKey("HARDWARE_RELATED_PORTABILITY").getChildren();
+ assertThat(hardwareControls.isEmpty()).isTrue();
- checkTables("warn_when_restoring_unknown_rule", "quality_models", "characteristics", "characteristic_edges");
- assertThat(messages.getWarnings()).hasSize(1);
- assertThat(messages.getWarnings().get(0)).contains("regexp");
+ assertThat(messages.getWarnings()).hasSize(3);
}
private RuleCache defaultRuleCache() {
@@ -194,4 +159,5 @@ public class TechnicalDebtManagerTest extends AbstractDbUnitTestCase {
private Rule newRegexpRule() {
return Rule.create("checkstyle", "regexp", "Regular expression");
}
+
}
diff --git a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinderTest.java b/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinderTest.java
index 83cecc03f85..b63ac6691ee 100644
--- a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinderTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelFinderTest.java
@@ -105,7 +105,14 @@ public class TechnicalDebtModelFinderTest {
@Test
public void return_xml_file_path_for_plugin() throws Exception {
initModel();
- assertThat(modelFinder.getXMLFilePathForPlugin("foo")).isEqualTo(TEST_XML_PREFIX_PATH + "foo-model.xml");
+ assertThat(modelFinder.getXMLFilePath("foo")).isEqualTo(TEST_XML_PREFIX_PATH + "foo-model.xml");
+ }
+
+ @Test
+ public void contain_default_model() throws Exception {
+ modelFinder = new TechnicalDebtModelFinder(mock(PluginRepository.class));
+ modelFinder.start();
+ assertThat(modelFinder.getContributingPluginKeyToClassLoader().keySet()).containsOnly("technical-debt");
}
private void initModel() throws MalformedURLException {
diff --git a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelTest.java b/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelTest.java
index 747871a245e..a294496300d 100644
--- a/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/technicaldebt/TechnicalDebtModelTest.java
@@ -28,6 +28,7 @@ import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;
+import org.sonar.server.startup.RegisterTechnicalDebtModel;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
@@ -41,13 +42,13 @@ public class TechnicalDebtModelTest {
@Before
public void setUpModel() {
- model = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
+ model = Model.createByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
technicalDebtModel = new TechnicalDebtModel(model);
}
@Test
public void shouldMergeWithEmptyModel() {
- Model with = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
+ Model with = Model.createByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
Characteristic efficiency = with.createCharacteristicByKey("efficiency", "Efficiency");
efficiency.addChild(with.createCharacteristicByKey("ram-efficiency", "RAM Efficiency"));
with.createCharacteristicByKey("usability", "Usability");
@@ -66,7 +67,7 @@ public class TechnicalDebtModelTest {
public void shouldNotUpdateExistingCharacteristics() {
model.createCharacteristicByKey("efficiency", "Efficiency");
- Model with = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
+ Model with = Model.createByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
with.createCharacteristicByKey("efficiency", "New efficiency");
technicalDebtModel.mergeWith(with, ValidationMessages.create(), mockRuleCache());
@@ -78,7 +79,7 @@ public class TechnicalDebtModelTest {
@Test
public void shouldWarnOnMissingRule() {
- Model with = Model.createByName(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
+ Model with = Model.createByName(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
Characteristic efficiency = with.createCharacteristicByKey("efficiency", "Efficiency");
Rule fooRule = Rule.create("foo", "bar", "Bar");
Characteristic requirement = with.createCharacteristicByRule(fooRule);
diff --git a/sonar-server/src/test/java/org/sonar/server/technicaldebt/XMLImporterTest.java b/sonar-server/src/test/java/org/sonar/server/technicaldebt/XMLImporterTest.java
index 75ac44008a6..3cec0b311a6 100644
--- a/sonar-server/src/test/java/org/sonar/server/technicaldebt/XMLImporterTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/technicaldebt/XMLImporterTest.java
@@ -29,6 +29,7 @@ import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;
+import org.sonar.server.startup.RegisterTechnicalDebtModel;
import java.io.IOException;
@@ -102,7 +103,7 @@ public class XMLImporterTest {
private void checkXmlCorrectlyImported(Model sqale, ValidationMessages messages) {
assertThat(messages.getErrors()).isEmpty();
- assertThat(sqale.getName()).isEqualTo(TechnicalDebtModelDefinition.TECHNICAL_DEBT_MODEL);
+ assertThat(sqale.getName()).isEqualTo(RegisterTechnicalDebtModel.TECHNICAL_DEBT_MODEL);
// characteristics
assertThat(sqale.getRootCharacteristics()).hasSize(2);
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution-result.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution-result.xml
new file mode 100644
index 00000000000..10ea4bbcc65
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution-result.xml
@@ -0,0 +1,16 @@
+<dataset>
+ <quality_models id="1" name="TECHNICAL_DEBT"/>
+
+ <characteristics id="1" kee="COMPILER_RELATED_PORTABILITY" name="Compiler related portability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2"
+ description="[null]" enabled="true"/>
+ <characteristics id="2" kee="PORTABILITY" name="Portability" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="1" description="[null]" enabled="true"/>
+ <characteristics id="3" kee="HARDWARE_RELATED_PORTABILITY" name="Hardware related portability" quality_model_id="1" rule_id="[null]" characteristic_order="3" depth="2"
+ description="[null]" enabled="true"/>
+ <characteristics id="4" kee="READABILITY" name="Readability" quality_model_id="1" rule_id="[null]" characteristic_order="4" depth="2" description="[null]" enabled="true"/>
+ <characteristics id="5" kee="MAINTAINABILITY" name="Maintainability" quality_model_id="1" rule_id="[null]" characteristic_order="5" depth="1" description="[null]" enabled="true"/>
+
+ <characteristic_edges child_id="1" parent_id="2"/>
+ <characteristic_edges child_id="3" parent_id="2"/>
+ <characteristic_edges child_id="4" parent_id="5"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution.xml
new file mode 100644
index 00000000000..fb0854fccbe
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_default_model_on_first_execution.xml
@@ -0,0 +1,2 @@
+<dataset>
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution-result.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution-result.xml
new file mode 100644
index 00000000000..1872525d83a
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution-result.xml
@@ -0,0 +1,34 @@
+<dataset>
+ <quality_models id="1" name="TECHNICAL_DEBT"/>
+
+ <characteristics id="1" kee="COMPILER_RELATED_PORTABILITY" name="Compiler related portability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2"
+ description="[null]" enabled="true"/>
+
+ <!-- Requirement provided by plugin -->
+ <characteristics id="2" kee="[null]" name="[null]" quality_model_id="1" rule_id="1" characteristic_order="6" depth="3"
+ description="[null]" enabled="true"/>
+
+ <characteristics id="3" kee="PORTABILITY" name="Portability" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="1" description="[null]" enabled="true"/>
+ <characteristics id="4" kee="HARDWARE_RELATED_PORTABILITY" name="Hardware related portability" quality_model_id="1" rule_id="[null]" characteristic_order="3" depth="2"
+ description="[null]" enabled="true"/>
+
+ <!-- Requirement provided by plugin -->
+ <characteristics id="5" kee="[null]" name="[null]" quality_model_id="1" rule_id="2" characteristic_order="7" depth="3"
+ description="[null]" enabled="true"/>
+
+ <characteristics id="6" kee="READABILITY" name="Readability" quality_model_id="1" rule_id="[null]" characteristic_order="4" depth="2" description="[null]" enabled="true"/>
+ <characteristics id="7" kee="MAINTAINABILITY" name="Maintainability" quality_model_id="1" rule_id="[null]" characteristic_order="5" depth="1" description="[null]"
+ enabled="true"/>
+
+ <characteristic_edges child_id="1" parent_id="3"/>
+ <characteristic_edges child_id="2" parent_id="1"/>
+ <characteristic_edges child_id="4" parent_id="3"/>
+ <characteristic_edges child_id="5" parent_id="4"/>
+ <characteristic_edges child_id="6" parent_id="7"/>
+
+ <characteristic_properties id="1" characteristic_id="2" kee="remediationFactor" value="30.0" text_value="mn"/>
+ <characteristic_properties id="2" characteristic_id="2" kee="remediationFunction" value="[null]" text_value="linear"/>
+ <characteristic_properties id="3" characteristic_id="5" kee="remediationFactor" value="1.0" text_value="h"/>
+ <characteristic_properties id="4" characteristic_id="5" kee="remediationFunction" value="[null]" text_value="linear"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution.xml
new file mode 100644
index 00000000000..fb0854fccbe
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/create_model_with_requirements_from_plugin_on_first_execution.xml
@@ -0,0 +1,2 @@
+<dataset>
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model-result.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model-result.xml
new file mode 100644
index 00000000000..735b6f97e2b
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model-result.xml
@@ -0,0 +1,56 @@
+<dataset>
+ <quality_models id="1" name="TECHNICAL_DEBT"/>
+
+ <characteristics id="1" kee="COMPILER_RELATED_PORTABILITY" name="Compiler related portability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2"
+ description="[null]" enabled="true"/>
+
+ <!-- Disabled requirement -->
+ <characteristics id="2" kee="[null]" name="[null]" quality_model_id="1" rule_id="1" characteristic_order="6" depth="3"
+ description="[null]" enabled="false"/>
+
+ <characteristics id="3" kee="PORTABILITY" name="Portability" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="1" description="[null]" enabled="true"/>
+ <characteristics id="4" kee="HARDWARE_RELATED_PORTABILITY" name="Hardware related portability" quality_model_id="1" rule_id="[null]" characteristic_order="3" depth="2"
+ description="[null]" enabled="true"/>
+
+ <!-- Disabled requirement -->
+ <characteristics id="5" kee="[null]" name="[null]" quality_model_id="1" rule_id="2" characteristic_order="7" depth="3"
+ description="[null]" enabled="false"/>
+
+ <characteristics id="6" kee="READABILITY" name="Readability" quality_model_id="1" rule_id="[null]" characteristic_order="4" depth="2" description="[null]" enabled="true"/>
+ <characteristics id="7" kee="MAINTAINABILITY" name="Maintainability" quality_model_id="1" rule_id="[null]" characteristic_order="5" depth="1" description="[null]"
+ enabled="true"/>
+
+ <!-- Requirements provided by plugin -->
+ <characteristics id="8" kee="[null]" name="[null]" quality_model_id="1" rule_id="1" characteristic_order="8" depth="3"
+ description="[null]" enabled="true"/>
+ <characteristics id="9" kee="[null]" name="[null]" quality_model_id="1" rule_id="2" characteristic_order="9" depth="3"
+ description="[null]" enabled="true"/>
+
+ <characteristic_edges child_id="1" parent_id="3"/>
+ <!-- Linked on disabled characteristic -->
+ <characteristic_edges child_id="2" parent_id="1"/>
+ <characteristic_edges child_id="4" parent_id="3"/>
+ <!-- Linked on disabled characteristic -->
+ <characteristic_edges child_id="5" parent_id="4"/>
+ <characteristic_edges child_id="6" parent_id="7"/>
+
+ <!-- On new characteristics -->
+ <characteristic_edges child_id="8" parent_id="1"/>
+ <characteristic_edges child_id="9" parent_id="4"/>
+
+ <!-- Linked on disabled characteristic -->
+ <characteristic_properties id="1" characteristic_id="2" kee="remediationFactor" value="30.0" text_value="mn"/>
+ <characteristic_properties id="2" characteristic_id="2" kee="remediationFunction" value="[null]" text_value="linear"/>
+ <characteristic_properties id="3" characteristic_id="5" kee="remediationFactor" value="1.0" text_value="h"/>
+ <characteristic_properties id="4" characteristic_id="5" kee="remediationFunction" value="[null]" text_value="linear"/>
+
+ <!-- On new characteristics -->
+ <characteristic_properties id="5" characteristic_id="8" kee="remediationFactor" value="30.0" text_value="mn"/>
+ <characteristic_properties id="6" characteristic_id="8" kee="remediationFunction" value="[null]" text_value="linear"/>
+ <characteristic_properties id="7" characteristic_id="9" kee="remediationFactor" value="1.0" text_value="h"/>
+ <characteristic_properties id="8" characteristic_id="9" kee="remediationFunction" value="[null]" text_value="linear"/>
+
+ <rules id="1" plugin_rule_key="import" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
+ <rules id="2" plugin_rule_key="export" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model.xml
new file mode 100644
index 00000000000..be70284b5ab
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/disable_characteristics_and_remove_requirements_when_resetting_model.xml
@@ -0,0 +1,38 @@
+<dataset>
+ <quality_models id="1" name="TECHNICAL_DEBT"/>
+
+ <characteristics id="1" kee="COMPILER_RELATED_PORTABILITY" name="Compiler related portability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2"
+ description="[null]" enabled="true"/>
+
+ <!-- Requirement provided by plugin -->
+ <characteristics id="2" kee="[null]" name="[null]" quality_model_id="1" rule_id="1" characteristic_order="6" depth="3"
+ description="[null]" enabled="true"/>
+
+ <characteristics id="3" kee="PORTABILITY" name="Portability" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="1" description="[null]" enabled="true"/>
+ <characteristics id="4" kee="HARDWARE_RELATED_PORTABILITY" name="Hardware related portability" quality_model_id="1" rule_id="[null]" characteristic_order="3" depth="2"
+ description="[null]" enabled="true"/>
+
+ <!-- Requirement provided by plugin -->
+ <characteristics id="5" kee="[null]" name="[null]" quality_model_id="1" rule_id="2" characteristic_order="7" depth="3"
+ description="[null]" enabled="true"/>
+
+ <characteristics id="6" kee="READABILITY" name="Readability" quality_model_id="1" rule_id="[null]" characteristic_order="4" depth="2" description="[null]" enabled="true"/>
+ <characteristics id="7" kee="MAINTAINABILITY" name="Maintainability" quality_model_id="1" rule_id="[null]" characteristic_order="5" depth="1" description="[null]"
+ enabled="true"/>
+
+
+ <characteristic_edges child_id="1" parent_id="3"/>
+ <characteristic_edges child_id="2" parent_id="1"/>
+ <characteristic_edges child_id="4" parent_id="3"/>
+ <characteristic_edges child_id="5" parent_id="4"/>
+ <characteristic_edges child_id="6" parent_id="7"/>
+
+ <characteristic_properties id="1" characteristic_id="2" kee="remediationFactor" value="30.0" text_value="mn"/>
+ <characteristic_properties id="2" characteristic_id="2" kee="remediationFunction" value="[null]" text_value="linear"/>
+ <characteristic_properties id="3" characteristic_id="5" kee="remediationFactor" value="1.0" text_value="h"/>
+ <characteristic_properties id="4" characteristic_id="5" kee="remediationFunction" value="[null]" text_value="linear"/>
+
+ <rules id="1" plugin_rule_key="import" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
+ <rules id="2" plugin_rule_key="export" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model-with-additionnale-characteristic.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model-with-additionnale-characteristic.xml
new file mode 100644
index 00000000000..19a8642bb35
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model-with-additionnale-characteristic.xml
@@ -0,0 +1,80 @@
+<sqale>
+ <chc>
+ <key>PORTABILITY</key>
+ <name>Portability</name>
+ <chc>
+ <key>COMPILER_RELATED_PORTABILITY</key>
+ <name>Compiler related portability</name>
+ <chc>
+ <rule-repo>checkstyle</rule-repo>
+ <rule-key>import</rule-key>
+ <prop>
+ <key>remediationFactor</key>
+ <val>30.0</val>
+ <txt>mn</txt>
+ </prop>
+ <prop>
+ <key>remediationFunction</key>
+ <txt>linear</txt>
+ </prop>
+ </chc>
+ </chc>
+ <chc>
+ <key>HARDWARE_RELATED_PORTABILITY</key>
+ <name>Hardware related portability</name>
+ <chc>
+ <rule-repo>checkstyle</rule-repo>
+ <rule-key>export</rule-key>
+ <prop>
+ <key>remediationFactor</key>
+ <val>1.0</val>
+ <txt>h</txt>
+ </prop>
+ <prop>
+ <key>remediationFunction</key>
+ <txt>linear</txt>
+ </prop>
+ </chc>
+ </chc>
+ </chc>
+ <chc>
+ <key>MAINTAINABILITY</key>
+ <name>Maintainability</name>
+ <chc>
+ <key>READABILITY</key>
+ <!-- Rename default characteristic -->
+ <name>Readability related maintainability</name>
+ <chc>
+ <rule-repo>checkstyle</rule-repo>
+ <rule-key>ConstantNameCheck</rule-key>
+ <prop>
+ <key>remediationFactor</key>
+ <val>10.0</val>
+ <txt>mn</txt>
+ </prop>
+ <prop>
+ <key>remediationFunction</key>
+ <txt>linear</txt>
+ </prop>
+ </chc>
+ </chc>
+ <chc>
+ <!-- New characteristic -->
+ <key>UNDERSTANDABILITY</key>
+ <name>Understandability related maintainability</name>
+ <chc>
+ <rule-repo>checkstyle</rule-repo>
+ <rule-key>JavadocMethodCheck</rule-key>
+ <prop>
+ <key>remediationFactor</key>
+ <val>30.0</val>
+ <txt>mn</txt>
+ </prop>
+ <prop>
+ <key>remediationFunction</key>
+ <txt>linear</txt>
+ </prop>
+ </chc>
+ </chc>
+ </chc>
+</sqale>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model.xml
index 6d610083e59..46e4a228391 100644
--- a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model.xml
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/fake-java-model.xml
@@ -42,6 +42,7 @@
<name>Maintainability</name>
<chc>
<key>READABILITY</key>
+ <!-- Rename default characteristic -->
<name>Readability related maintainability</name>
<chc>
<rule-repo>checkstyle</rule-repo>
@@ -57,22 +58,5 @@
</prop>
</chc>
</chc>
- <chc>
- <key>UNDERSTANDABILITY</key>
- <name>Understandability related maintainability</name>
- <chc>
- <rule-repo>checkstyle</rule-repo>
- <rule-key>JavadocMethodCheck</rule-key>
- <prop>
- <key>remediationFactor</key>
- <val>30.0</val>
- <txt>mn</txt>
- </prop>
- <prop>
- <key>remediationFunction</key>
- <txt>linear</txt>
- </prop>
- </chc>
- </chc>
</chc>
</sqale>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge-result.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge-result.xml
deleted file mode 100644
index 3f84f54b6a0..00000000000
--- a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge-result.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<dataset>
- <!-- existing models -->
- <quality_models id="1" name="TECHNICAL_DEBT" />
- <characteristics id="1" kee="testability" name="Testability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" />
- <characteristics id="2" kee="unit_testability" name="Unit tests" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="2" description="[null]" enabled="true" />
-
- <characteristics id="3" kee="efficiency" name="Efficiency" quality_model_id="1" rule_id="[null]" characteristic_order="3" depth="1" description="[null]" enabled="true" />
- <characteristics id="4" kee="ram-efficiency" name="RAM Efficiency" quality_model_id="1" rule_id="[null]" characteristic_order="4" depth="2" description="[null]" enabled="true" />
- <characteristics id="5" kee="[null]" name="[null]" quality_model_id="1" rule_id="2" characteristic_order="5" depth="3" description="[null]" enabled="true" />
-
- <characteristic_edges child_id="2" parent_id="1"/>
- <characteristic_edges child_id="4" parent_id="3"/>
- <characteristic_edges child_id="5" parent_id="4"/>
-
- <characteristic_properties id="1" characteristic_id="1" kee="foo" value="[null]" text_value="bar" />
-
- <rules id="1" plugin_rule_key="import" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
- <rules id="2" plugin_rule_key="regexp" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
-</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge.xml
deleted file mode 100644
index 4e2fb09f44c..00000000000
--- a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_merge.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<dataset>
- <!-- existing models -->
- <quality_models id="1" name="TECHNICAL_DEBT" />
-
- <characteristics id="1" kee="testability" name="Testability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" />
- <characteristics id="2" kee="unit_testability" name="Unit tests" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="2" description="[null]" enabled="true" />
- <characteristic_edges child_id="2" parent_id="1"/>
- <characteristic_properties id="1" characteristic_id="1" kee="foo" value="[null]" text_value="bar" />
-
- <rules id="1" plugin_rule_key="import" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
- <rules id="2" plugin_rule_key="regexp" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
-</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore-result.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore-result.xml
deleted file mode 100644
index 612de620d26..00000000000
--- a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore-result.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<dataset>
- <quality_models id="1" name="TECHNICAL_DEBT" />
-
- <characteristics id="1" kee="testability" name="Testability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="false" />
- <characteristics id="2" kee="unit_testability" name="Unit tests" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="2" description="[null]" enabled="false" />
- <characteristics id="3" kee="[null]" name="[null]" quality_model_id="1" rule_id="1" characteristic_order="3" depth="3" description="[null]" enabled="false" />
-
- <characteristics id="4" kee="efficiency" name="Efficiency" quality_model_id="1" rule_id="[null]" characteristic_order="4" depth="1" description="[null]" enabled="true" />
- <characteristics id="5" kee="ram-efficiency" name="RAM Efficiency" quality_model_id="1" rule_id="[null]" characteristic_order="5" depth="2" description="[null]" enabled="true" />
- <characteristics id="6" kee="[null]" name="[null]" quality_model_id="1" rule_id="2" characteristic_order="6" depth="3" description="[null]" enabled="true" />
-
- <characteristic_edges child_id="2" parent_id="1"/>
- <characteristic_edges child_id="3" parent_id="2"/>
- <characteristic_edges child_id="5" parent_id="4"/>
- <characteristic_edges child_id="6" parent_id="5"/>
-
- <characteristic_properties id="1" characteristic_id="1" kee="foo" value="[null]" text_value="bar" />
-
- <rules id="1" plugin_rule_key="import" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
- <rules id="2" plugin_rule_key="regexp" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
-</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore.xml
deleted file mode 100644
index 1561bdb21cd..00000000000
--- a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/persist_restore.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<dataset>
- <quality_models id="1" name="TECHNICAL_DEBT" />
-
- <characteristics id="1" kee="testability" name="Testability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" />
- <characteristics id="2" kee="unit_testability" name="Unit tests" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="2" description="[null]" enabled="true" />
- <characteristics id="3" kee="[null]" name="[null]" quality_model_id="1" rule_id="1" characteristic_order="3" depth="3" description="[null]" enabled="true" />
-
- <characteristic_edges child_id="2" parent_id="1"/>
- <characteristic_edges child_id="3" parent_id="2"/>
-
- <characteristic_properties id="1" characteristic_id="1" kee="foo" value="[null]" text_value="bar" />
-
- <rules id="1" plugin_rule_key="import" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
- <rules id="2" plugin_rule_key="regexp" plugin_config_key="regexp" plugin_name="checkstyle" description="[null]" priority="3" status="READY" cardinality="SINGLE" parent_id="[null]" name="Regular exp"/>
-</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/reset_model.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/reset_model.xml
index 4c82f6e589a..ff53f92ff0a 100644
--- a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/reset_model.xml
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/reset_model.xml
@@ -1,6 +1,7 @@
<dataset>
- <!-- existing models -->
+
<quality_models id="1" name="TECHNICAL_DEBT" />
+
<characteristics id="1" kee="testability" name="Testability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" />
<characteristics id="2" kee="unit_testability" name="Unit tests" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="2" description="[null]" enabled="true" />
<characteristic_edges child_id="2" parent_id="1"/>
diff --git a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/warn_when_restoring_unknown_rule-result.xml b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/warn_when_restoring_unknown_rule-result.xml
index 7566ea2ad3c..1da76f127aa 100644
--- a/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/warn_when_restoring_unknown_rule-result.xml
+++ b/sonar-server/src/test/resources/org/sonar/server/technicaldebt/TechnicalDebtManagerTest/warn_when_restoring_unknown_rule-result.xml
@@ -1,6 +1,6 @@
<dataset>
<quality_models id="1" name="foo" />
- <quality_models id="2" name="TECHNICAL_DEBT" />
+ <quality_models id="2" name="SQALE" />
<characteristics id="1" kee="testability" name="Testability" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" />
<characteristics id="2" kee="unit_testability" name="Unit tests" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="2" description="[null]" enabled="true" />