Skip to content

Commit

Permalink
SONAR-6012 Issues on files on removed modules should contain the modu…
Browse files Browse the repository at this point in the history
…le key
  • Loading branch information
julienlancelot committed Mar 20, 2015
1 parent 4010dad commit 49c7ed8
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 38 deletions.
Expand Up @@ -135,7 +135,7 @@ private void handleIssue(IssueDoc issue, BatchInput.ServerIssue.Builder issueBui
private Map<String, String> keysByUUid(DbSession session, ComponentDto component) { private Map<String, String> keysByUUid(DbSession session, ComponentDto component) {
Map<String, String> keysByUUid = newHashMap(); Map<String, String> keysByUUid = newHashMap();
if (Scopes.PROJECT.equals(component.scope())) { 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) { for (ComponentDto componentDto : modulesTree) {
keysByUUid.put(componentDto.uuid(), componentDto.key()); keysByUUid.put(componentDto.uuid(), componentDto.key());
} }
Expand Down
Expand Up @@ -102,11 +102,11 @@ public ProjectRepositories load(ProjectRepositoryQuery query) {
projectKey = project.key(); 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, String> moduleUuidsByKey = moduleUuidsByKey(module, modulesTree);
Map<String, Long> moduleIdsByKey = moduleIdsByKey(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); TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, modulesTree, modulesTreeSettings, module);


addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session); addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session);
Expand Down Expand Up @@ -288,7 +288,7 @@ private void addFileData(DbSession session, ProjectRepositories ref, List<Compon
moduleKeysByUuid.put(module.uuid(), module.key()); 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); FileData fileData = new FileData(file.getSrcHash(), false, null, null, null);
ref.addFileData(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData); ref.addFileData(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData);
} }
Expand Down
Expand Up @@ -95,12 +95,16 @@ public List<ComponentDto> findSubProjectsByComponentUuids(DbSession session, Col
return mapper(session).findSubProjectsByComponentUuids(keys); return mapper(session).findSubProjectsByComponentUuids(keys);
} }


public List<ComponentDto> selectModulesTree(DbSession session, String rootComponentUuid) { public List<ComponentDto> selectDescendantModules(DbSession session, String rootComponentUuid) {
return mapper(session).selectModulesTree(rootComponentUuid, Scopes.PROJECT); return mapper(session).selectDescendantModules(rootComponentUuid, Scopes.PROJECT, false);
} }


public List<FilePathWithHashDto> selectModuleFilesTree(DbSession session, String rootComponentUuid) { public List<ComponentDto> selectEnabledDescendantModules(DbSession session, String rootComponentUuid) {
return mapper(session).selectModuleFilesTree(rootComponentUuid, Scopes.FILE); 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) { public List<ComponentDto> getByIds(final DbSession session, Collection<Long> ids) {
Expand Down
Expand Up @@ -82,7 +82,7 @@ public void index(String rootViewUuid) {
DbSession dbSession = dbClient.openSession(false); DbSession dbSession = dbClient.openSession(false);
try { try {
Map<String, String> viewAndProjectViewUuidMap = newHashMap(); 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()); viewAndProjectViewUuidMap.put(viewOrSubView.uuid(), viewOrSubView.projectUuid());
} }
index(dbSession, viewAndProjectViewUuidMap, true); index(dbSession, viewAndProjectViewUuidMap, true);
Expand Down
Expand Up @@ -298,11 +298,40 @@ public void issues_attached_on_module() throws Exception {
assertThat(previousIssue.getAssigneeLogin()).isEqualTo("john"); 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) @Test(expected = ForbiddenException.class)
public void fail_without_preview_permission() throws Exception { public void fail_without_preview_permission() throws Exception {
MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PROVISIONING); 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(); request.execute();
} }


Expand Down
Expand Up @@ -346,55 +346,71 @@ public void find_sub_projects_by_component_keys() throws Exception {
} }


@Test @Test
public void select_modules_tree() throws Exception { public void select_enabled_modules_tree() throws Exception {
setupData("multi-modules"); setupData("multi-modules");


// From root project // 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"); assertThat(modules).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI");


// From module // From module
modules = dao.selectModulesTree(session, "EFGH"); modules = dao.selectEnabledDescendantModules(session, "EFGH");
assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI"); assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI");


// From sub module // From sub module
modules = dao.selectModulesTree(session, "FGHI"); modules = dao.selectEnabledDescendantModules(session, "FGHI");
assertThat(modules).extracting("uuid").containsOnly("FGHI"); assertThat(modules).extracting("uuid").containsOnly("FGHI");


// Folder // Folder
assertThat(dao.selectModulesTree(session, "GHIJ")).isEmpty(); assertThat(dao.selectEnabledDescendantModules(session, "GHIJ")).isEmpty();
assertThat(dao.selectModulesTree(session, "unknown")).isEmpty(); assertThat(dao.selectEnabledDescendantModules(session, "unknown")).isEmpty();
} }


@Test @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"); setupData("select_module_files_tree");


// From root project // 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("uuid").containsOnly("EFGHI", "HIJK");
assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI"); assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI");
assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK"); assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK");
assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java"); assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java");


// From module // From module
files = dao.selectModuleFilesTree(session, "EFGH"); files = dao.selectEnabledDescendantFiles(session, "EFGH");
assertThat(files).extracting("uuid").containsOnly("EFGHI", "HIJK"); assertThat(files).extracting("uuid").containsOnly("EFGHI", "HIJK");
assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI"); assertThat(files).extracting("moduleUuid").containsOnly("EFGH", "FGHI");
assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK"); assertThat(files).extracting("srcHash").containsOnly("srcEFGHI", "srcHIJK");
assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java"); assertThat(files).extracting("path").containsOnly("src/org/struts/pom.xml", "src/org/struts/RequestContext.java");


// From sub module // From sub module
files = dao.selectModuleFilesTree(session, "FGHI"); files = dao.selectEnabledDescendantFiles(session, "FGHI");
assertThat(files).extracting("uuid").containsOnly("HIJK"); assertThat(files).extracting("uuid").containsOnly("HIJK");
assertThat(files).extracting("moduleUuid").containsOnly("FGHI"); assertThat(files).extracting("moduleUuid").containsOnly("FGHI");
assertThat(files).extracting("srcHash").containsOnly("srcHIJK"); assertThat(files).extracting("srcHash").containsOnly("srcHIJK");
assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java"); assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java");


// From directory // 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 @Test
Expand Down
Expand Up @@ -87,4 +87,24 @@
depth="[null]" scope="FIL" qualifier="CLA" created_at="1228222680000" build_date="1228222680000" depth="[null]" scope="FIL" qualifier="CLA" created_at="1228222680000" build_date="1228222680000"
version="[null]" path="1.2.3.4."/> 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> </dataset>
Expand Up @@ -68,14 +68,16 @@ public interface ComponentMapper {
List<String> findProjectUuids(); 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 * Return uuids and project uuids from list of qualifiers
Expand Down
Expand Up @@ -157,8 +157,8 @@ public List<PropertyDto> selectProjectProperties(String resourceKey) {
} }
} }


public List<PropertyDto> selectModulePropertiesTree(String moduleUuid, SqlSession session) { public List<PropertyDto> selectEnabledDescendantModuleProperties(String moduleUuid, SqlSession session) {
return session.getMapper(PropertiesMapper.class).selectModulePropertiesTree(moduleUuid, Scopes.PROJECT); return session.getMapper(PropertiesMapper.class).selectDescendantModuleProperties(moduleUuid, Scopes.PROJECT, true);
} }


public PropertyDto selectProjectProperty(long resourceId, String propertyKey) { public PropertyDto selectProjectProperty(long resourceId, String propertyKey) {
Expand Down
Expand Up @@ -44,7 +44,8 @@ public interface PropertiesMapper {


List<PropertyDto> selectByQuery(@Param("query") PropertyQuery query); 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); void update(PropertyDto property);


Expand Down
Expand Up @@ -136,17 +136,19 @@
</where> </where>
</select> </select>


<select id="selectModulesTree" parameterType="map" resultType="Component"> <select id="selectDescendantModules" parameterType="map" resultType="Component">
SELECT <include refid="componentColumns"/> SELECT <include refid="componentColumns"/>
FROM projects p FROM projects p
<include refid="modulesTreeQuery"/> <include refid="modulesTreeQuery"/>
</select> </select>


<sql id="modulesTreeQuery"> <sql id="modulesTreeQuery">
INNER JOIN projects root_project ON root_project.uuid = p.project_uuid AND root_project.enabled = ${_true} 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> <where>
p.enabled = ${_true} <if test="excludeDisabled">
p.enabled = ${_true}
</if>
AND p.scope = #{scope} AND p.scope = #{scope}
AND AND
<choose> <choose>
Expand All @@ -163,7 +165,7 @@
</where> </where>
</sql> </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 SELECT p.uuid, p.path, p.module_uuid as moduleUuid, fs.src_hash as srcHash
FROM projects p FROM projects p
INNER JOIN file_sources fs ON fs.file_uuid=p.uuid INNER JOIN file_sources fs ON fs.file_uuid=p.uuid
Expand Down
Expand Up @@ -45,7 +45,7 @@
where p.resource_id=#{resourceId} and p.user_id is null where p.resource_id=#{resourceId} and p.user_id is null
</select> </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 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 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 INNER JOIN (SELECT p.id FROM projects p<include refid="org.sonar.core.component.db.ComponentMapper.modulesTreeQuery"/>) modules on modules.id=prop.resource_id
Expand Down
Expand Up @@ -178,20 +178,20 @@ public void selectProjectPropertiesByResourceId() {
public void select_module_properties_tree() throws Exception { public void select_module_properties_tree() throws Exception {
setupData("select_module_properties_tree"); 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.size(), is(4));
assertThat(properties).extracting("key").containsOnly("struts.one", "core.one", "core.two", "data.one"); assertThat(properties).extracting("key").containsOnly("struts.one", "core.one", "core.two", "data.one");
assertThat(properties).extracting("value").containsOnly("one", "two"); assertThat(properties).extracting("value").containsOnly("one", "two");


properties = dao.selectModulePropertiesTree("EFGH", session); properties = dao.selectEnabledDescendantModuleProperties("EFGH", session);
assertThat(properties.size(), is(3)); assertThat(properties.size(), is(3));
assertThat(properties).extracting("key").containsOnly("core.one", "core.two", "data.one"); 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.size(), is(1));
assertThat(properties).extracting("key").containsOnly("data.one"); assertThat(properties).extracting("key").containsOnly("data.one");


assertThat(dao.selectModulePropertiesTree("unknown", session).size(), is(0)); assertThat(dao.selectEnabledDescendantModuleProperties("unknown", session).size(), is(0));
} }


@Test @Test
Expand Down

0 comments on commit 49c7ed8

Please sign in to comment.