diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2013-05-03 10:10:25 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2013-05-03 10:10:33 +0200 |
commit | df944a9893b904c318d5663d4999f9b3cc60cd91 (patch) | |
tree | d45ba27ed99de9c167cff3707ac2da024b281d14 | |
parent | 53c455995c5d49b2876f334a98ddc86bbdf1c896 (diff) | |
download | sonarqube-df944a9893b904c318d5663d4999f9b3cc60cd91.tar.gz sonarqube-df944a9893b904c318d5663d4999f9b3cc60cd91.zip |
SONAR-3755 fix NPE when file does not exist anymore
4 files changed, 127 insertions, 4 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueStorage.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueStorage.java index d5c00ab12d9..124d5f2137b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueStorage.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueStorage.java @@ -26,22 +26,33 @@ import org.sonar.batch.index.SnapshotCache; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.db.IssueStorage; import org.sonar.core.persistence.MyBatis; +import org.sonar.core.resource.ResourceDao; +import org.sonar.core.resource.ResourceDto; +import org.sonar.core.resource.ResourceQuery; public class ScanIssueStorage extends IssueStorage implements BatchComponent { private final SnapshotCache snapshotCache; + private final ResourceDao resourceDao; - public ScanIssueStorage(MyBatis mybatis, RuleFinder ruleFinder, SnapshotCache snapshotCache) { + public ScanIssueStorage(MyBatis mybatis, RuleFinder ruleFinder, SnapshotCache snapshotCache, ResourceDao resourceDao) { super(mybatis, ruleFinder); this.snapshotCache = snapshotCache; + this.resourceDao = resourceDao; } @Override protected int componentId(DefaultIssue issue) { Snapshot snapshot = snapshotCache.get(issue.componentKey()); - if (snapshot == null) { - throw new IllegalStateException("Component does not exist: " + issue.componentKey()); + if (snapshot != null) { + return snapshot.getResourceId(); } - return snapshot.getResourceId(); + + // Load from db when component does not exist in cache (deleted file for example) + ResourceDto resourceDto = resourceDao.getResource(ResourceQuery.create().setKey(issue.componentKey())); + if (resourceDto == null) { + throw new IllegalStateException("Unknown component: " + issue.componentKey()); + } + return resourceDto.getId().intValue(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ScanIssueStorageTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ScanIssueStorageTest.java new file mode 100644 index 00000000000..e805a06b68c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ScanIssueStorageTest.java @@ -0,0 +1,108 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.issue; + +import org.junit.Test; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RuleFinder; +import org.sonar.api.rules.RuleQuery; +import org.sonar.batch.index.SnapshotCache; +import org.sonar.core.issue.DefaultIssue; +import org.sonar.core.persistence.AbstractDaoTestCase; +import org.sonar.core.resource.ResourceDao; + +import java.util.Collection; + +import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Fail.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ScanIssueStorageTest extends AbstractDaoTestCase { + @Test + public void should_load_component_id_from_cache() throws Exception { + SnapshotCache snapshotCache = mock(SnapshotCache.class); + when(snapshotCache.get("struts:Action.java")).thenReturn(new Snapshot().setResourceId(123)); + + ScanIssueStorage storage = new ScanIssueStorage(getMyBatis(), new FakeRuleFinder(), snapshotCache, new ResourceDao(getMyBatis())); + int componentId = storage.componentId(new DefaultIssue().setComponentKey("struts:Action.java")); + + assertThat(componentId).isEqualTo(123); + } + + @Test + public void should_load_component_id_from_db() throws Exception { + setupData("should_load_component_id_from_db"); + SnapshotCache snapshotCache = mock(SnapshotCache.class); + when(snapshotCache.get("struts:Action.java")).thenReturn(null); + + ScanIssueStorage storage = new ScanIssueStorage(getMyBatis(), new FakeRuleFinder(), snapshotCache, new ResourceDao(getMyBatis())); + int componentId = storage.componentId(new DefaultIssue().setComponentKey("struts:Action.java")); + + assertThat(componentId).isEqualTo(123); + } + + @Test + public void should_fail_if_unknown_component() throws Exception { + setupData("should_fail_if_unknown_component"); + SnapshotCache snapshotCache = mock(SnapshotCache.class); + when(snapshotCache.get("struts:Action.java")).thenReturn(null); + + ScanIssueStorage storage = new ScanIssueStorage(getMyBatis(), new FakeRuleFinder(), snapshotCache, new ResourceDao(getMyBatis())); + try { + storage.componentId(new DefaultIssue().setComponentKey("struts:Action.java")); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("Unknown component: struts:Action.java"); + } + } + + static class FakeRuleFinder implements RuleFinder { + + @Override + public Rule findById(int ruleId) { + return null; + } + + @Override + public Rule findByKey(String repositoryKey, String key) { + return null; + } + + @Override + public Rule findByKey(RuleKey key) { + Rule rule = new Rule().setRepositoryKey(key.repository()).setKey(key.rule()); + rule.setId(200); + return rule; + } + + @Override + public Rule find(RuleQuery query) { + return null; + } + + @Override + public Collection<Rule> findAll(RuleQuery query) { + return null; + } + } +} diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_fail_if_unknown_component.xml b/sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_fail_if_unknown_component.xml new file mode 100644 index 00000000000..5ed00ba028b --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_fail_if_unknown_component.xml @@ -0,0 +1 @@ +<dataset></dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_load_component_id_from_db.xml b/sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_load_component_id_from_db.xml new file mode 100644 index 00000000000..cf7e75fd7f7 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_load_component_id_from_db.xml @@ -0,0 +1,3 @@ +<dataset> + <projects id="123" kee="struts:Action.java" /> +</dataset>
\ No newline at end of file |