]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6012 Issues on files on removed modules should contain the module key 163/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 20 Mar 2015 13:15:38 +0000 (14:15 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 20 Mar 2015 13:15:38 +0000 (14:15 +0100)
13 files changed:
server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java
server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java
server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java
server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java
server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml
sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java
sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java
sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml
sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml
sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java

index 147d7d899f2df3be8e5d6b39789b14a3d2a83240..c19c985787e3d709baa6aaba81abbbdc39ca967d 100644 (file)
@@ -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());
       }
index 50576f75bf47e7ffa47847cd7d7e99633b50b91a..0ebebdac72af8f79220c6d3c66a884053c3a28d3 100644 (file)
@@ -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);
     }
index 27cd270de816f51e356f25b4d16918bb5c97ad4d..652e34631b914fd0c4eec799428eee6faccd5aa8 100644 (file)
@@ -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) {
index bc6f501be0b82983be84fdb943cbabe1a2e4431f..1b8a12356b3e81bb56868d29c8d5da7548a89117 100644 (file)
@@ -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);
index ed1efae697c5ea6ffe07973ac053742fcffb2687..9186253b320d97de31824f15e70a4e2b11cae89b 100644 (file)
@@ -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();
   }
 
index 1c62b09058eb3782a6b00541d4fcc99984f9374c..8c55ee6ce1d7846c08449566bf55c42074e8c159 100644 (file)
@@ -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
index 6f68d6d45cd17438c6ee24825520c6834f21faf3..76ac0b9862f5696a159a53b6a7dd8773856b41b6 100644 (file)
              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>
index 1f057c62dc843c5ead3bf7a1e20b71f9b0b36ba2..648f2a7cf9dd91425c222572348bee81e24aca4b 100644 (file)
@@ -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
index 3f080f74bebc9884fa9503223a04a560c3e2f84e..e32589f1b0cd801f26f337f983504e1c6c8c9cbf 100644 (file)
@@ -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) {
index 4124d23e46d7bb480e2f3369ac65c8ea4713cbfb..b2368e69f9812b5644b9bfef0a09258dda4bd1b4 100644 (file)
@@ -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);
 
index 547092e5076dd44611b27a856fdeb29acb37777a..91a3bc460a6bf8ce3cc9986585a11ae8b64b038f 100644 (file)
     </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"/>
 
   <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>
     </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
index 40b7eb2a38a81318dc842509247576c320145637..fb4e703d33e7bae2c257d80c1226266ea22f423b 100644 (file)
@@ -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
index c92c655006afcfc621f8c11774aa623050daa2d0..3b20680b2dc92cb2a4706cdd69e784a8ad41f1b5 100644 (file)
@@ -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