From 55a9be1fa31394aec3093bc27cd9c501f0f0cc60 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 26 Mar 2014 11:50:57 +0100 Subject: [PATCH] SONAR-5056 Refactoring of restore feature --- .../sonar/server/debt/DebtModelBackup.java | 136 ++++++------ .../server/debt/DebtModelOperations.java | 6 +- .../server/debt/DebtModelBackupTest.java | 193 +++++++++++++----- 3 files changed, 225 insertions(+), 110 deletions(-) diff --git a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java index 7c6ae137ce2..068294006f1 100644 --- a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java +++ b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java @@ -124,107 +124,119 @@ public class DebtModelBackup implements ServerComponent { } /** - * Restore from provided model + * Restore from provided model (characteristics and rule debt are restored) */ public void restore() { - restoreProvided(loadModelFromPlugin(DebtModelPluginRepository.DEFAULT_MODEL), null); + checkPermission(); + + Date updateDate = new Date(system2.now()); + SqlSession session = mybatis.openSession(); + try { + restoreCharacteristics(loadModelFromPlugin(DebtModelPluginRepository.DEFAULT_MODEL), updateDate, session); + restoreProvidedModel(ruleDao.selectEnablesAndNonManual(session), updateDate, session); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } } /** - * Restore from plugins providing rules for a given language + * Restore from plugins providing rules for a given language (only debt of rules on given language are restored) */ - public void restore(String languageKey) { - restoreProvided(loadModelFromPlugin(DebtModelPluginRepository.DEFAULT_MODEL), languageKey); - } - - private void restoreProvided(DebtModel modelToImport, @Nullable String languageKey) { + public void restore(final String languageKey) { checkPermission(); Date updateDate = new Date(system2.now()); SqlSession session = mybatis.openSession(); try { - restoreCharacteristics(modelToImport, updateDate, session); - for (RuleDto rule : ruleDao.selectEnablesAndNonManual(session)) { - if (languageKey == null || languageKey.equals(rule.getLanguage())) { - rule.setCharacteristicId(null); - rule.setRemediationFunction(null); - rule.setRemediationFactor(null); - rule.setRemediationOffset(null); - rule.setUpdatedAt(updateDate); - ruleDao.update(rule, session); - // TODO index rules in E/S + List rules = newArrayList(Iterables.filter(ruleDao.selectEnablesAndNonManual(session), new Predicate() { + @Override + public boolean apply(RuleDto input) { + return languageKey.equals(input.getLanguage()); } - } + })); + restoreProvidedModel(rules, updateDate, session); session.commit(); } finally { MyBatis.closeQuietly(session); } } + private void restoreProvidedModel(List rules, Date updateDate, SqlSession session) { + for (RuleDto rule : rules) { + disabledRuleDebt(rule, updateDate, session); + } + } + /** - * Restore model from a given XML model + * Restore model from a given XML model (characteristics and rule debt are restored from XML) */ public ValidationMessages restoreFromXml(String xml) { - DebtModel debtModel = characteristicsXMLImporter.importXML(xml); + checkPermission(); + ValidationMessages validationMessages = ValidationMessages.create(); - List ruleDebts = rulesXMLImporter.importXML(xml, validationMessages); - restore(debtModel, ruleDebts, null, validationMessages); + Date updateDate = new Date(system2.now()); + SqlSession session = mybatis.openSession(); + try { + List characteristicDtos = restoreCharacteristics(characteristicsXMLImporter.importXML(xml), updateDate, session); + restoreRules(characteristicDtos, ruleDao.selectEnablesAndNonManual(session), rulesXMLImporter.importXML(xml, validationMessages), validationMessages, updateDate, session); + + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } return validationMessages; } /** - * Restore model from a given XML model and a given language + * Restore model from a given XML model and a given language (only debt of rules on given language are restored from XML) */ - public ValidationMessages restoreFromXml(String xml, String languageKey) { - DebtModel debtModel = characteristicsXMLImporter.importXML(xml); - ValidationMessages validationMessages = ValidationMessages.create(); - List ruleDebts = rulesXMLImporter.importXML(xml, validationMessages); - restore(debtModel, ruleDebts, languageKey, validationMessages); - return validationMessages; - } - - private void restore(DebtModel modelToImport, List ruleDebts, @Nullable String languageKey, ValidationMessages validationMessages) { + public ValidationMessages restoreFromXml(String xml, final String languageKey) { checkPermission(); + ValidationMessages validationMessages = ValidationMessages.create(); Date updateDate = new Date(system2.now()); SqlSession session = mybatis.openSession(); try { - List characteristicDtos = restoreCharacteristics(modelToImport, updateDate, session); - restoreRules(characteristicDtos, languageKey, ruleDebts, validationMessages, updateDate, session); + List characteristicDtos = dao.selectEnabledCharacteristics(session); + List rules = newArrayList(Iterables.filter(ruleDao.selectEnablesAndNonManual(session), new Predicate() { + @Override + public boolean apply(RuleDto input) { + return languageKey.equals(input.getLanguage()); + } + })); + restoreRules(characteristicDtos, rules, rulesXMLImporter.importXML(xml, validationMessages), validationMessages, updateDate, session); session.commit(); } finally { MyBatis.closeQuietly(session); } + return validationMessages; } - private void restoreRules(List characteristicDtos, @Nullable String languageKey, List ruleDebts, + private void restoreRules(List characteristicDtos, List rules, List ruleDebts, ValidationMessages validationMessages, Date updateDate, SqlSession session) { - for (RuleDto rule : ruleDao.selectEnablesAndNonManual(session)) { - if (languageKey == null || languageKey.equals(rule.getLanguage())) { - RuleDebt ruleDebt = ruleDebtByRule(rule, ruleDebts); - if (ruleDebt == null) { - rule.setCharacteristicId(rule.getDefaultCharacteristicId() != null ? RuleDto.DISABLED_CHARACTERISTIC_ID : null); - rule.setRemediationFunction(null); - rule.setRemediationFactor(null); - rule.setRemediationOffset(null); + for (RuleDto rule : rules) { + RuleDebt ruleDebt = ruleDebtByRule(rule, ruleDebts); + if (ruleDebt == null) { + disabledRuleDebt(rule, updateDate, session); + } else { + CharacteristicDto characteristicDto = characteristicByKey(ruleDebt.characteristicKey(), characteristicDtos); + if (characteristicDto == null) { + disabledRuleDebt(rule, updateDate, session); } else { - CharacteristicDto characteristicDto = characteristicByKey(ruleDebt.characteristicKey(), characteristicDtos, false); - // Characteristic cannot be null as it has been created just before - boolean isSameCharacteristic = characteristicDto.getId().equals(rule.getDefaultCharacteristicId()); boolean isSameFunction = isSameRemediationFunction(ruleDebt, rule); rule.setCharacteristicId((!isSameCharacteristic ? characteristicDto.getId() : null)); rule.setRemediationFunction((!isSameFunction ? ruleDebt.function().name() : null)); rule.setRemediationFactor((!isSameFunction ? ruleDebt.factor() : null)); rule.setRemediationOffset((!isSameFunction ? ruleDebt.offset() : null)); + rule.setUpdatedAt(updateDate); + ruleDao.update(rule, session); + // TODO index rules in E/S } - - ruleDebts.remove(ruleDebt); - rule.setUpdatedAt(updateDate); - ruleDao.update(rule, session); - // TODO index rules in E/S } + ruleDebts.remove(ruleDebt); } for (RuleDebt ruleDebt : ruleDebts) { @@ -257,7 +269,7 @@ public class DebtModelBackup implements ServerComponent { private CharacteristicDto restoreCharacteristic(DebtCharacteristic targetCharacteristic, @Nullable Integer parentId, List sourceCharacteristics, Date updateDate, SqlSession session) { - CharacteristicDto sourceCharacteristic = characteristicByKey(targetCharacteristic.key(), sourceCharacteristics, true); + CharacteristicDto sourceCharacteristic = characteristicByKey(targetCharacteristic.key(), sourceCharacteristics); if (sourceCharacteristic == null) { CharacteristicDto newCharacteristic = toDto(targetCharacteristic, parentId).setCreatedAt(updateDate); dao.insert(newCharacteristic, session); @@ -283,6 +295,15 @@ public class DebtModelBackup implements ServerComponent { .isEquals(); } + private void disabledRuleDebt(RuleDto rule, Date updateDate, SqlSession session){ + rule.setCharacteristicId(rule.getDefaultCharacteristicId() != null ? RuleDto.DISABLED_CHARACTERISTIC_ID : null); + rule.setRemediationFunction(null); + rule.setRemediationFactor(null); + rule.setRemediationOffset(null); + rule.setUpdatedAt(updateDate); + ruleDao.update(rule, session); + } + private DebtModel loadModelFromPlugin(String pluginKey) { Reader xmlFileReader = null; try { @@ -306,17 +327,14 @@ public class DebtModelBackup implements ServerComponent { }, null); } - private static CharacteristicDto characteristicByKey(final String key, List characteristicDtos, boolean canByNull) { - CharacteristicDto dto = Iterables.find(characteristicDtos, new Predicate() { + @CheckForNull + private static CharacteristicDto characteristicByKey(final String key, List characteristicDtos) { + return Iterables.find(characteristicDtos, new Predicate() { @Override public boolean apply(CharacteristicDto input) { return key.equals(input.getKey()); } }, null); - if (dto == null && !canByNull) { - throw new IllegalStateException(String.format("Characteristic with key '%s' has not been found ", key)); - } - return dto; } private static List subCharacteristics(final Integer parentId, List allCharacteristics) { diff --git a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java index cbd9c4bcd63..521322cc48c 100644 --- a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java +++ b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java @@ -183,12 +183,12 @@ public class DebtModelOperations implements ServerComponent { if (characteristicOrSubCharacteristic.getParentId() == null) { List subCharacteristics = dao.selectCharacteristicsByParentId(characteristicOrSubCharacteristic.getId(), session); for (CharacteristicDto subCharacteristic : subCharacteristics) { - disableSubChracteristic(subCharacteristic, updateDate, session); + disableSubCharacteristic(subCharacteristic, updateDate, session); } disableCharacteristic(characteristicOrSubCharacteristic, updateDate, session); } else { // When sub characteristic, disable rule debt on the sub characteristic then disable it - disableSubChracteristic(characteristicOrSubCharacteristic, updateDate, session); + disableSubCharacteristic(characteristicOrSubCharacteristic, updateDate, session); } session.commit(); } finally { @@ -196,7 +196,7 @@ public class DebtModelOperations implements ServerComponent { } } - private void disableSubChracteristic(CharacteristicDto subCharacteristic, Date updateDate, SqlSession session) { + private void disableSubCharacteristic(CharacteristicDto subCharacteristic, Date updateDate, SqlSession session) { disableDebtRules(ruleDao.selectBySubCharacteristicId(subCharacteristic.getId(), session), updateDate, session); disableCharacteristic(subCharacteristic, updateDate, session); } diff --git a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java index dbad6dea2ec..f96bfdbfab1 100644 --- a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java +++ b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java @@ -105,8 +105,8 @@ public class DebtModelBackupTest { int currentId; - DebtModel debtModel = new DebtModel(); - List rules = newArrayList(); + DebtModel xmlDebtModel = new DebtModel(); + List xmlDebtRules = newArrayList(); DebtModelBackup debtModelBackup; @@ -131,9 +131,9 @@ public class DebtModelBackupTest { Reader defaultModelReader = mock(Reader.class); when(debtModelPluginRepository.createReaderForXMLFile("technical-debt")).thenReturn(defaultModelReader); - when(characteristicsXMLImporter.importXML(eq(defaultModelReader))).thenReturn(debtModel); - when(characteristicsXMLImporter.importXML(anyString())).thenReturn(debtModel); - when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(rules); + when(characteristicsXMLImporter.importXML(any(Reader.class))).thenReturn(xmlDebtModel); +// when(characteristicsXMLImporter.importXML(anyString())).thenReturn(xmlDebtModel); +// when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(xmlDebtRules); debtModelBackup = new DebtModelBackup(myBatis, dao, ruleDao, debtModelOperations, debtModelPluginRepository, characteristicsXMLImporter, rulesXMLImporter, debtModelXMLExporter, system2); @@ -320,9 +320,9 @@ public class DebtModelBackupTest { @Test public void restore_from_provided_model() throws Exception { - debtModel + when(characteristicsXMLImporter.importXML(any(Reader.class))).thenReturn(new DebtModel() .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setOrder(2).setCreatedAt(oldDate), @@ -356,53 +356,79 @@ public class DebtModelBackupTest { @Test public void restore_from_language() throws Exception { - debtModel - .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( + new RuleDto().setId(1).setRepositoryKey("squid").setLanguage("java") + .setCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationFactor("2h").setRemediationOffset("15min") + .setCreatedAt(oldDate).setUpdatedAt(oldDate), + // Should be ignored because linked on another language + new RuleDto().setId(2).setRepositoryKey("checkstyle").setLanguage("java2") + .setCharacteristicId(2).setRemediationFunction("LINEAR").setRemediationFactor("2h") + .setCreatedAt(oldDate).setUpdatedAt(oldDate) + )); + + debtModelBackup.restore("java"); + + verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); + verify(ruleDao).selectEnablesAndNonManual(session); + verify(ruleDao).update(ruleArgument.capture(), eq(session)); + verifyNoMoreInteractions(ruleDao); + + RuleDto rule = ruleArgument.getValue(); + assertThat(rule.getId()).isEqualTo(1); + assertThat(rule.getCharacteristicId()).isNull(); + assertThat(rule.getRemediationFunction()).isNull(); + assertThat(rule.getRemediationFactor()).isNull(); + assertThat(rule.getRemediationOffset()).isNull(); + assertThat(rule.getUpdatedAt()).isEqualTo(now); + + verify(session).commit(); + } + + @Test + public void restore_from_language_with_rule_linked_on_disabled_default_characteristic() throws Exception { when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setOrder(2).setCreatedAt(oldDate), new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler updated").setParentId(1).setCreatedAt(oldDate) )); when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( - new RuleDto().setId(1).setRepositoryKey("squid").setLanguage("java") + // Linked on a disabled default characteristic -> Rule debt should be disabled + new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck").setLanguage("java") + .setDefaultCharacteristicId(3).setDefaultRemediationFunction("LINEAR").setDefaultRemediationFactor("2h") .setCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationFactor("2h").setRemediationOffset("15min") - .setCreatedAt(oldDate).setUpdatedAt(oldDate), - // Should be ignored - new RuleDto().setId(2).setRepositoryKey("checkstyle").setLanguage("java2") - .setCharacteristicId(3).setRemediationFunction("LINEAR").setRemediationFactor("2h") .setCreatedAt(oldDate).setUpdatedAt(oldDate) )); debtModelBackup.restore("java"); - verify(dao).selectEnabledCharacteristics(session); - verify(dao, times(2)).update(any(CharacteristicDto.class), eq(session)); - verifyNoMoreInteractions(dao); - verify(ruleDao).selectEnablesAndNonManual(session); verify(ruleDao).update(ruleArgument.capture(), eq(session)); verifyNoMoreInteractions(ruleDao); RuleDto rule = ruleArgument.getValue(); assertThat(rule.getId()).isEqualTo(1); + assertThat(rule.getCharacteristicId()).isEqualTo(-1); + assertThat(rule.getRemediationFunction()).isNull(); + assertThat(rule.getRemediationFactor()).isNull(); + assertThat(rule.getRemediationOffset()).isNull(); + assertThat(rule.getUpdatedAt()).isEqualTo(now); verify(session).commit(); } @Test public void restore_from_xml_with_different_characteristic_and_same_function() throws Exception { - debtModel + when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel() .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1).setCreatedAt(oldDate), new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler").setParentId(1).setCreatedAt(oldDate))); - rules.add(new RuleDebt() - .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR).setFactor("2h")); + when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(newArrayList(new RuleDebt() + .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR).setFactor("2h"))); when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck") @@ -429,16 +455,16 @@ public class DebtModelBackupTest { @Test public void restore_from_xml_with_same_characteristic_and_different_function() throws Exception { - debtModel + when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel() .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1).setCreatedAt(oldDate), new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler").setParentId(1).setCreatedAt(oldDate))); - rules.add(new RuleDebt() - .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR_OFFSET).setFactor("12h").setOffset("11min")); + when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(newArrayList(new RuleDebt() + .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR_OFFSET).setFactor("12h").setOffset("11min"))); when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck") @@ -465,16 +491,16 @@ public class DebtModelBackupTest { @Test public void restore_from_xml_with_same_characteristic_and_same_function() throws Exception { - debtModel + when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel() .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1).setCreatedAt(oldDate), new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler").setParentId(1).setCreatedAt(oldDate))); - rules.add(new RuleDebt() - .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR_OFFSET).setFactor("2h").setOffset("15min")); + when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(newArrayList(new RuleDebt() + .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR_OFFSET).setFactor("2h").setOffset("15min"))); when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck") @@ -501,9 +527,9 @@ public class DebtModelBackupTest { @Test public void restore_from_xml_disable_rule_debt_when_not_in_xml_and_rule_have_default_debt_values() throws Exception { - debtModel + when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel() .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1).setCreatedAt(oldDate), @@ -534,9 +560,9 @@ public class DebtModelBackupTest { @Test public void restore_from_xml_set_no_rule_debt_when_not_in_xml_and_rule_has_no_default_debt_values() throws Exception { - debtModel + when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel() .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1).setCreatedAt(oldDate), @@ -567,16 +593,12 @@ public class DebtModelBackupTest { @Test public void restore_from_xml_and_language() throws Exception { - debtModel - .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); - when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1).setCreatedAt(oldDate), new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler").setParentId(1).setCreatedAt(oldDate))); - rules.add(new RuleDebt() - .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR).setFactor("2h")); + when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(newArrayList(new RuleDebt() + .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR).setFactor("2h"))); when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck").setLanguage("java") @@ -590,6 +612,9 @@ public class DebtModelBackupTest { debtModelBackup.restoreFromXml("", "java"); + verify(characteristicsXMLImporter, never()).importXML(anyString()); + verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); + verify(ruleDao).selectEnablesAndNonManual(session); verify(ruleDao).update(ruleArgument.capture(), eq(session)); verifyNoMoreInteractions(ruleDao); @@ -600,24 +625,96 @@ public class DebtModelBackupTest { verify(session).commit(); } + @Test + public void restore_from_xml_and_language_with_rule_not_in_xml_and_linked_on_disabled_default_characteristic() throws Exception { + when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( + new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setOrder(2).setCreatedAt(oldDate), + new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler updated").setParentId(1).setCreatedAt(oldDate) + )); + + when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(Collections.emptyList()); + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( + // Linked on a default disabled characteristic -> Rule debt should be disabled + new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck").setLanguage("java") + .setDefaultCharacteristicId(3).setDefaultRemediationFunction("LINEAR").setDefaultRemediationFactor("2h") + .setCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationFactor("2h").setRemediationOffset("15min") + .setCreatedAt(oldDate).setUpdatedAt(oldDate) + )); + + debtModelBackup.restoreFromXml("", "java"); + + verify(characteristicsXMLImporter, never()).importXML(anyString()); + verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); + + verify(ruleDao).selectEnablesAndNonManual(session); + verify(ruleDao).update(ruleArgument.capture(), eq(session)); + verifyNoMoreInteractions(ruleDao); + + RuleDto rule = ruleArgument.getValue(); + assertThat(rule.getId()).isEqualTo(1); + assertThat(rule.getCharacteristicId()).isEqualTo(-1); + assertThat(rule.getRemediationFunction()).isNull(); + assertThat(rule.getRemediationFactor()).isNull(); + assertThat(rule.getRemediationOffset()).isNull(); + assertThat(rule.getUpdatedAt()).isEqualTo(now); + + verify(session).commit(); + } + + @Test + public void restore_from_xml_and_language_with_rule_linked_on_disabled_characteristic2() throws Exception { + when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( + new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setOrder(2).setCreatedAt(oldDate), + new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler updated").setParentId(1).setCreatedAt(oldDate) + )); + + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( + new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck").setLanguage("java") + .setDefaultCharacteristicId(3).setDefaultRemediationFunction("LINEAR").setDefaultRemediationFactor("2h") + .setCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationFactor("2h").setRemediationOffset("15min") + .setCreatedAt(oldDate).setUpdatedAt(oldDate) + )); + + when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(newArrayList(new RuleDebt() + // Linked on a default disabled characteristic -> Rule debt should be disabled + .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("HARDWARE").setFunction(DebtRemediationFunction.Type.LINEAR).setFactor("2h"))); + + debtModelBackup.restoreFromXml("", "java"); + + verify(characteristicsXMLImporter, never()).importXML(anyString()); + verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); + + verify(ruleDao).selectEnablesAndNonManual(session); + verify(ruleDao).update(ruleArgument.capture(), eq(session)); + verifyNoMoreInteractions(ruleDao); + + RuleDto rule = ruleArgument.getValue(); + assertThat(rule.getId()).isEqualTo(1); + assertThat(rule.getCharacteristicId()).isEqualTo(-1); + assertThat(rule.getRemediationFunction()).isNull(); + assertThat(rule.getRemediationFactor()).isNull(); + assertThat(rule.getRemediationOffset()).isNull(); + assertThat(rule.getUpdatedAt()).isEqualTo(now); + + verify(session).commit(); + } + @Test public void add_warning_message_when_rule_from_xml_is_not_found() throws Exception { - debtModel + when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel() .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) - .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"); + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1).setCreatedAt(oldDate), new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler").setParentId(1).setCreatedAt(oldDate))); - rules.add(new RuleDebt() - .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR).setFactor("2h")); + when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))).thenReturn(newArrayList(new RuleDebt() + .setRuleKey(RuleKey.of("squid", "UselessImportCheck")).setCharacteristicKey("COMPILER").setFunction(DebtRemediationFunction.Type.LINEAR).setFactor("2h"))); when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(Collections.emptyList()); - ValidationMessages validationMessages = debtModelBackup.restoreFromXml(""); - - assertThat(validationMessages.getWarnings()).hasSize(1); + assertThat(debtModelBackup.restoreFromXml("").getWarnings()).hasSize(1); verify(ruleDao).selectEnablesAndNonManual(session); verifyNoMoreInteractions(ruleDao); -- 2.39.5