diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-03-20 14:15:38 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-03-20 14:15:38 +0100 |
commit | 49c7ed8d6a92fd697c8c9e0522300b13b52074c6 (patch) | |
tree | cb73974cc78b9c50fa84f3bba1f2b30716b4c015 | |
parent | 4010dadc61187e390d044408873cdce1af4829f6 (diff) | |
download | sonarqube-49c7ed8d6a92fd697c8c9e0522300b13b52074c6.tar.gz sonarqube-49c7ed8d6a92fd697c8c9e0522300b13b52074c6.zip |
SONAR-6012 Issues on files on removed modules should contain the module key
13 files changed, 112 insertions, 38 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java index 147d7d899f2..c19c985787e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java @@ -135,7 +135,7 @@ public class IssuesAction implements RequestHandler { private Map<String, String> keysByUUid(DbSession session, ComponentDto component) { Map<String, String> keysByUUid = newHashMap(); if (Scopes.PROJECT.equals(component.scope())) { - List<ComponentDto> modulesTree = dbClient.componentDao().selectModulesTree(session, component.uuid()); + List<ComponentDto> modulesTree = dbClient.componentDao().selectDescendantModules(session, component.uuid()); for (ComponentDto componentDto : modulesTree) { keysByUUid.put(componentDto.uuid(), componentDto.key()); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java index 50576f75bf4..0ebebdac72a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java @@ -102,11 +102,11 @@ public class ProjectRepositoryLoader implements ServerComponent { projectKey = project.key(); } - List<ComponentDto> modulesTree = dbClient.componentDao().selectModulesTree(session, module.uuid()); + List<ComponentDto> modulesTree = dbClient.componentDao().selectEnabledDescendantModules(session, module.uuid()); Map<String, String> moduleUuidsByKey = moduleUuidsByKey(module, modulesTree); Map<String, Long> moduleIdsByKey = moduleIdsByKey(module, modulesTree); - List<PropertyDto> modulesTreeSettings = dbClient.propertiesDao().selectModulePropertiesTree(module.uuid(), session); + List<PropertyDto> modulesTreeSettings = dbClient.propertiesDao().selectEnabledDescendantModuleProperties(module.uuid(), session); TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, modulesTree, modulesTreeSettings, module); addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session); @@ -288,7 +288,7 @@ public class ProjectRepositoryLoader implements ServerComponent { moduleKeysByUuid.put(module.uuid(), module.key()); } - for (FilePathWithHashDto file : dbClient.componentDao().selectModuleFilesTree(session, moduleKey)) { + for (FilePathWithHashDto file : dbClient.componentDao().selectEnabledDescendantFiles(session, moduleKey)) { FileData fileData = new FileData(file.getSrcHash(), false, null, null, null); ref.addFileData(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java index 27cd270de81..652e34631b9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java @@ -95,12 +95,16 @@ public class ComponentDao extends BaseDao<ComponentMapper, ComponentDto, String> return mapper(session).findSubProjectsByComponentUuids(keys); } - public List<ComponentDto> selectModulesTree(DbSession session, String rootComponentUuid) { - return mapper(session).selectModulesTree(rootComponentUuid, Scopes.PROJECT); + public List<ComponentDto> selectDescendantModules(DbSession session, String rootComponentUuid) { + return mapper(session).selectDescendantModules(rootComponentUuid, Scopes.PROJECT, false); } - public List<FilePathWithHashDto> selectModuleFilesTree(DbSession session, String rootComponentUuid) { - return mapper(session).selectModuleFilesTree(rootComponentUuid, Scopes.FILE); + public List<ComponentDto> selectEnabledDescendantModules(DbSession session, String rootComponentUuid) { + return mapper(session).selectDescendantModules(rootComponentUuid, Scopes.PROJECT, true); + } + + public List<FilePathWithHashDto> selectEnabledDescendantFiles(DbSession session, String rootComponentUuid) { + return mapper(session).selectDescendantFiles(rootComponentUuid, Scopes.FILE, true); } public List<ComponentDto> getByIds(final DbSession session, Collection<Long> ids) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java index bc6f501be0b..1b8a12356b3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java @@ -82,7 +82,7 @@ public class ViewIndexer extends BaseIndexer { DbSession dbSession = dbClient.openSession(false); try { Map<String, String> viewAndProjectViewUuidMap = newHashMap(); - for (ComponentDto viewOrSubView : dbClient.componentDao().selectModulesTree(dbSession, rootViewUuid)) { + for (ComponentDto viewOrSubView : dbClient.componentDao().selectEnabledDescendantModules(dbSession, rootViewUuid)) { viewAndProjectViewUuidMap.put(viewOrSubView.uuid(), viewOrSubView.projectUuid()); } index(dbSession, viewAndProjectViewUuidMap, true); diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java index ed1efae697c..9186253b320 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java @@ -298,11 +298,40 @@ public class IssuesActionTest { assertThat(previousIssue.getAssigneeLogin()).isEqualTo("john"); } + @Test + public void project_issues_attached_file_on_removed_module() throws Exception { + ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY); + // File and module are removed + ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY).setEnabled(false); + ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java").setEnabled(false); + componentDao.insert(session, project, module, file); + session.commit(); + + indexIssues(IssueTesting.newDoc("EFGH", file) + .setRuleKey("squid:AvoidCycle") + .setSeverity("BLOCKER") + .setStatus("RESOLVED") + .setResolution("FALSE-POSITIVE") + .setManualSeverity(false) + .setMessage("Do not use this method") + .setLine(200) + .setChecksum("123456") + .setAssignee("john")); + + MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION); + + WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", PROJECT_KEY); + ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output())); + assertThat(serverIssue.getKey()).isEqualTo("EFGH"); + // Module key of removed file should be returned + assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY); + } + @Test(expected = ForbiddenException.class) public void fail_without_preview_permission() throws Exception { MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PROVISIONING); - WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", MODULE_KEY); + WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", PROJECT_KEY); request.execute(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java index 1c62b09058e..8c55ee6ce1d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java @@ -346,55 +346,71 @@ public class ComponentDaoTest extends AbstractDaoTestCase { } @Test - public void select_modules_tree() throws Exception { + public void select_enabled_modules_tree() throws Exception { setupData("multi-modules"); // From root project - List<ComponentDto> modules = dao.selectModulesTree(session, "ABCD"); + List<ComponentDto> modules = dao.selectEnabledDescendantModules(session, "ABCD"); assertThat(modules).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI"); // From module - modules = dao.selectModulesTree(session, "EFGH"); + modules = dao.selectEnabledDescendantModules(session, "EFGH"); assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI"); // From sub module - modules = dao.selectModulesTree(session, "FGHI"); + modules = dao.selectEnabledDescendantModules(session, "FGHI"); assertThat(modules).extracting("uuid").containsOnly("FGHI"); // Folder - assertThat(dao.selectModulesTree(session, "GHIJ")).isEmpty(); - assertThat(dao.selectModulesTree(session, "unknown")).isEmpty(); + assertThat(dao.selectEnabledDescendantModules(session, "GHIJ")).isEmpty(); + assertThat(dao.selectEnabledDescendantModules(session, "unknown")).isEmpty(); } @Test - public void select_module_files_tree() throws Exception { + public void select_all_modules_tree() throws Exception { + setupData("multi-modules"); + + // From root project, disabled sub module is returned + List<ComponentDto> modules = dao.selectDescendantModules(session, "ABCD"); + assertThat(modules).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI", "IHGF"); + + // From module, disabled sub module is returned + modules = dao.selectDescendantModules(session, "EFGH"); + assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI", "IHGF"); + + // From removed sub module -> should not be returned + assertThat(dao.selectDescendantModules(session, "IHGF")).isEmpty(); + } + + @Test + public void select_enabled_module_files_tree() throws Exception { setupData("select_module_files_tree"); // From root project - List<FilePathWithHashDto> files = dao.selectModuleFilesTree(session, "ABCD"); + List<FilePathWithHashDto> files = dao.selectEnabledDescendantFiles(session, "ABCD"); assertThat(files).extracting("uuid").containsOnly("EFGHI", "HIJK"); assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI"); assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK"); assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java"); // From module - files = dao.selectModuleFilesTree(session, "EFGH"); + files = dao.selectEnabledDescendantFiles(session, "EFGH"); assertThat(files).extracting("uuid").containsOnly("EFGHI", "HIJK"); assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI"); assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK"); assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java"); // From sub module - files = dao.selectModuleFilesTree(session, "FGHI"); + files = dao.selectEnabledDescendantFiles(session, "FGHI"); assertThat(files).extracting("uuid").containsOnly("HIJK"); assertThat(files).extracting("moduleUuid").containsOnly("FGHI"); assertThat(files).extracting("srcHash").containsOnly("srcHIJK"); assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java"); // From directory - assertThat(dao.selectModuleFilesTree(session, "GHIJ")).isEmpty(); + assertThat(dao.selectEnabledDescendantFiles(session, "GHIJ")).isEmpty(); - assertThat(dao.selectModuleFilesTree(session, "unknown")).isEmpty(); + assertThat(dao.selectEnabledDescendantFiles(session, "unknown")).isEmpty(); } @Test diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml index 6f68d6d45cd..76ac0b9862f 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml @@ -87,4 +87,24 @@ depth="[null]" scope="FIL" qualifier="CLA" created_at="1228222680000" build_date="1228222680000" version="[null]" path="1.2.3.4."/> + <!-- removed sub module --> + <projects id="10" root_id="1" kee="org.struts:struts-data" name="Struts Data" + uuid="IHGF" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH.IHGF." + scope="PRJ" qualifier="BRC" long_name="Struts Data" + description="[null]" enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" /> + + <!-- removed directory --> + <projects long_name="org.struts" id="11" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" + uuid="JIHG" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.IHGF." + name="src/org/struts" root_id="10" + description="[null]" + enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" /> + + <!-- removed file --> + <projects long_name="org.struts.RequestContext" id="12" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java" + uuid="KJIH" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.IHGF." + name="RequestContext.java" root_id="10" + description="[null]" + enabled="[false]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" /> + </dataset> diff --git a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java index 1f057c62dc8..648f2a7cf9d 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java @@ -68,14 +68,16 @@ public interface ComponentMapper { List<String> findProjectUuids(); /** - * Return all modules tree (child, grand child, etc. including itself) from a module uuid + * Return all descendant modules (including itself) from a given component uuid and scope */ - List<ComponentDto> selectModulesTree(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope); + List<ComponentDto> selectDescendantModules(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope, + @Param(value = "excludeDisabled") boolean excludeDisabled); /** - * Return all files children from a module uuid + * Return all descendant files from a given component uuid and scope */ - List<FilePathWithHashDto> selectModuleFilesTree(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope); + List<FilePathWithHashDto> selectDescendantFiles(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope, + @Param(value = "excludeDisabled") boolean excludeDisabled); /** * Return uuids and project uuids from list of qualifiers diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java index 3f080f74beb..e32589f1b0c 100644 --- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java +++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java @@ -157,8 +157,8 @@ public class PropertiesDao implements BatchComponent, ServerComponent, DaoCompon } } - public List<PropertyDto> selectModulePropertiesTree(String moduleUuid, SqlSession session) { - return session.getMapper(PropertiesMapper.class).selectModulePropertiesTree(moduleUuid, Scopes.PROJECT); + public List<PropertyDto> selectEnabledDescendantModuleProperties(String moduleUuid, SqlSession session) { + return session.getMapper(PropertiesMapper.class).selectDescendantModuleProperties(moduleUuid, Scopes.PROJECT, true); } public PropertyDto selectProjectProperty(long resourceId, String propertyKey) { diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java index 4124d23e46d..b2368e69f98 100644 --- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java @@ -44,7 +44,8 @@ public interface PropertiesMapper { List<PropertyDto> selectByQuery(@Param("query") PropertyQuery query); - List<PropertyDto> selectModulePropertiesTree(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope); + List<PropertyDto> selectDescendantModuleProperties(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope, + @Param(value = "excludeDisabled") boolean excludeDisabled); void update(PropertyDto property); diff --git a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml index 547092e5076..91a3bc460a6 100644 --- a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml @@ -136,7 +136,7 @@ </where> </select> - <select id="selectModulesTree" parameterType="map" resultType="Component"> + <select id="selectDescendantModules" parameterType="map" resultType="Component"> SELECT <include refid="componentColumns"/> FROM projects p <include refid="modulesTreeQuery"/> @@ -144,9 +144,11 @@ <sql id="modulesTreeQuery"> INNER JOIN projects root_project ON root_project.uuid = p.project_uuid AND root_project.enabled = ${_true} - INNER JOIN projects module ON module.project_uuid = root_project.uuid AND module.enabled = ${_true} AND module.uuid = #{moduleUuid} AND module.scope='PRJ' + INNER JOIN projects module ON module.project_uuid = root_project.uuid AND module.uuid = #{moduleUuid} AND module.scope='PRJ' AND module.enabled = ${_true} <where> - p.enabled = ${_true} + <if test="excludeDisabled"> + p.enabled = ${_true} + </if> AND p.scope = #{scope} AND <choose> @@ -163,7 +165,7 @@ </where> </sql> - <select id="selectModuleFilesTree" parameterType="map" resultType="FilePathWithHash"> + <select id="selectDescendantFiles" parameterType="map" resultType="FilePathWithHash"> SELECT p.uuid, p.path, p.module_uuid as moduleUuid, fs.src_hash as srcHash FROM projects p INNER JOIN file_sources fs ON fs.file_uuid=p.uuid diff --git a/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml b/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml index 40b7eb2a38a..fb4e703d33e 100644 --- a/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml @@ -45,7 +45,7 @@ where p.resource_id=#{resourceId} and p.user_id is null </select> - <select id="selectModulePropertiesTree" parameterType="String" resultType="Property"> + <select id="selectDescendantModuleProperties" parameterType="String" resultType="Property"> SELECT prop.id as id, prop.prop_key as "key", prop.text_value as value, prop.resource_id as resourceId, prop.user_id as userId FROM properties prop INNER JOIN (SELECT p.id FROM projects p<include refid="org.sonar.core.component.db.ComponentMapper.modulesTreeQuery"/>) modules on modules.id=prop.resource_id diff --git a/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java b/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java index c92c655006a..3b20680b2dc 100644 --- a/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java @@ -178,20 +178,20 @@ public class PropertiesDaoTest extends AbstractDaoTestCase { public void select_module_properties_tree() throws Exception { setupData("select_module_properties_tree"); - List<PropertyDto> properties = dao.selectModulePropertiesTree("ABCD", session); + List<PropertyDto> properties = dao.selectEnabledDescendantModuleProperties("ABCD", session); assertThat(properties.size(), is(4)); assertThat(properties).extracting("key").containsOnly("struts.one", "core.one", "core.two", "data.one"); assertThat(properties).extracting("value").containsOnly("one", "two"); - properties = dao.selectModulePropertiesTree("EFGH", session); + properties = dao.selectEnabledDescendantModuleProperties("EFGH", session); assertThat(properties.size(), is(3)); assertThat(properties).extracting("key").containsOnly("core.one", "core.two", "data.one"); - properties = dao.selectModulePropertiesTree("FGHI", session); + properties = dao.selectEnabledDescendantModuleProperties("FGHI", session); assertThat(properties.size(), is(1)); assertThat(properties).extracting("key").containsOnly("data.one"); - assertThat(dao.selectModulePropertiesTree("unknown", session).size(), is(0)); + assertThat(dao.selectEnabledDescendantModuleProperties("unknown", session).size(), is(0)); } @Test |