]> source.dussan.org Git - sonarqube.git/blob
1b4a04e3d5d87a6ce30d1377801361cfc6fc5637
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.ce.task.projectanalysis.pushevent;
21
22 import java.util.Date;
23 import java.util.List;
24 import org.junit.Before;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.sonar.api.rule.RuleKey;
28 import org.sonar.api.rules.RuleType;
29 import org.sonar.api.utils.DateUtils;
30 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
31 import org.sonar.ce.task.projectanalysis.analysis.TestBranch;
32 import org.sonar.ce.task.projectanalysis.component.Component.Type;
33 import org.sonar.ce.task.projectanalysis.component.MutableTreeRootHolderRule;
34 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
35 import org.sonar.ce.task.projectanalysis.locations.flow.FlowGenerator;
36 import org.sonar.core.issue.DefaultIssue;
37 import org.sonar.core.issue.FieldDiffs;
38 import org.sonar.db.protobuf.DbCommons;
39 import org.sonar.db.protobuf.DbIssues;
40 import org.sonar.server.issue.TaintChecker;
41
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.mockito.ArgumentMatchers.any;
44 import static org.mockito.Mockito.mock;
45 import static org.mockito.Mockito.when;
46
47 public class PushEventFactoryTest {
48
49   private final TaintChecker taintChecker = mock(TaintChecker.class);
50   @Rule
51   public MutableTreeRootHolderRule treeRootHolder = new MutableTreeRootHolderRule();
52   @Rule
53   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
54     .setBranch(new TestBranch("develop"));
55
56   private final FlowGenerator flowGenerator = new FlowGenerator(treeRootHolder);
57   private final PushEventFactory underTest = new PushEventFactory(treeRootHolder, analysisMetadataHolder, taintChecker, flowGenerator);
58
59   @Before
60   public void setUp() {
61     when(taintChecker.getTaintRepositories()).thenReturn(List.of("roslyn.sonaranalyzer.security.cs",
62       "javasecurity", "jssecurity", "tssecurity", "phpsecurity", "pythonsecurity"));
63     when(taintChecker.isTaintVulnerability(any())).thenReturn(true);
64     buildComponentTree();
65   }
66
67   @Test
68   public void raise_event_to_repository_if_taint_vulnerability_is_new() {
69     DefaultIssue defaultIssue = createDefaultIssue()
70       .setNew(true);
71
72     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue))
73       .isNotEmpty()
74       .hasValueSatisfying(pushEventDto -> {
75         assertThat(pushEventDto.getName()).isEqualTo("TaintVulnerabilityRaised");
76         assertThat(pushEventDto.getPayload()).isNotNull();
77         assertThat(pushEventDto.getLanguage()).isEqualTo("java");
78         assertThat(pushEventDto.getProjectUuid()).isEqualTo("some-project-uuid");
79       });
80
81   }
82
83   @Test
84   public void raise_event_to_repository_if_taint_vulnerability_is_reopened() {
85     DefaultIssue defaultIssue = createDefaultIssue()
86       .setChanged(true)
87       .setNew(false)
88       .setCopied(false)
89       .setCurrentChange(new FieldDiffs().setDiff("status", "CLOSED", "OPEN"));
90
91     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue))
92       .isNotEmpty()
93       .hasValueSatisfying(pushEventDto -> {
94         assertThat(pushEventDto.getName()).isEqualTo("TaintVulnerabilityRaised");
95         assertThat(pushEventDto.getPayload()).isNotNull();
96       });
97   }
98
99   @Test
100   public void skip_event_if_taint_vulnerability_status_change() {
101     DefaultIssue defaultIssue = createDefaultIssue()
102       .setChanged(true)
103       .setNew(false)
104       .setCopied(false)
105       .setCurrentChange(new FieldDiffs().setDiff("status", "OPEN", "FIXED"));
106
107     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue)).isEmpty();
108   }
109
110   @Test
111   public void raise_event_to_repository_if_taint_vulnerability_is_copied() {
112     DefaultIssue defaultIssue = createDefaultIssue()
113       .setCopied(true);
114
115     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue))
116       .isNotEmpty()
117       .hasValueSatisfying(pushEventDto -> {
118         assertThat(pushEventDto.getName()).isEqualTo("TaintVulnerabilityRaised");
119         assertThat(pushEventDto.getPayload()).isNotNull();
120       });
121   }
122
123   @Test
124   public void raise_event_to_repository_if_taint_vulnerability_is_closed() {
125     DefaultIssue defaultIssue = createDefaultIssue()
126       .setComponentUuid("")
127       .setNew(false)
128       .setCopied(false)
129       .setBeingClosed(true);
130
131     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue))
132       .isNotEmpty()
133       .hasValueSatisfying(pushEventDto -> {
134         assertThat(pushEventDto.getName()).isEqualTo("TaintVulnerabilityClosed");
135         assertThat(pushEventDto.getPayload()).isNotNull();
136       });
137   }
138
139   @Test
140   public void skip_issue_if_issue_changed() {
141     DefaultIssue defaultIssue = new DefaultIssue()
142       .setComponentUuid("issue-component-uuid")
143       .setNew(false)
144       .setCopied(false)
145       .setChanged(true)
146       .setType(RuleType.VULNERABILITY)
147       .setCreationDate(DateUtils.parseDate("2022-01-01"))
148       .setRuleKey(RuleKey.of("javasecurity", "S123"));
149
150     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue)).isEmpty();
151   }
152
153   @Test
154   public void skip_if_issue_not_from_taint_vulnerability_repository() {
155     DefaultIssue defaultIssue = new DefaultIssue()
156       .setComponentUuid("issue-component-uuid")
157       .setChanged(true)
158       .setType(RuleType.VULNERABILITY)
159       .setRuleKey(RuleKey.of("weirdrepo", "S123"));
160
161     when(taintChecker.isTaintVulnerability(any())).thenReturn(false);
162
163     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue)).isEmpty();
164
165     defaultIssue = new DefaultIssue()
166       .setComponentUuid("issue-component-uuid")
167       .setChanged(false)
168       .setNew(false)
169       .setBeingClosed(true)
170       .setType(RuleType.VULNERABILITY)
171       .setRuleKey(RuleKey.of("weirdrepo", "S123"));
172
173     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue)).isEmpty();
174   }
175
176   @Test
177   public void skip_if_issue_is_a_hotspot() {
178     DefaultIssue defaultIssue = new DefaultIssue()
179       .setComponentUuid("issue-component-uuid")
180       .setChanged(true)
181       .setType(RuleType.SECURITY_HOTSPOT)
182       .setRuleKey(RuleKey.of("javasecurity", "S123"));
183
184     when(taintChecker.isTaintVulnerability(any())).thenReturn(false);
185
186     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue)).isEmpty();
187   }
188
189   @Test
190   public void skip_if_issue_does_not_have_locations() {
191     DefaultIssue defaultIssue = new DefaultIssue()
192       .setComponentUuid("issue-component-uuid")
193       .setChanged(true)
194       .setType(RuleType.VULNERABILITY)
195       .setRuleKey(RuleKey.of("javasecurity", "S123"));
196
197     when(taintChecker.isTaintVulnerability(any())).thenReturn(false);
198
199     assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue)).isEmpty();
200   }
201
202   private void buildComponentTree() {
203     treeRootHolder.setRoot(ReportComponent.builder(Type.PROJECT, 1)
204       .setUuid("uuid_1")
205       .addChildren(ReportComponent.builder(Type.FILE, 2)
206         .setUuid("issue-component-uuid")
207         .build())
208       .addChildren(ReportComponent.builder(Type.FILE, 3)
209         .setUuid("location-component-uuid")
210         .build())
211       .build());
212   }
213
214   private DefaultIssue createDefaultIssue() {
215     return new DefaultIssue()
216       .setComponentUuid("issue-component-uuid")
217       .setType(RuleType.VULNERABILITY)
218       .setLanguage("java")
219       .setCreationDate(new Date())
220       .setLocations(DbIssues.Locations.newBuilder()
221         .addFlow(DbIssues.Flow.newBuilder()
222           .addLocation(DbIssues.Location.newBuilder()
223             .setChecksum("checksum")
224             .setComponentId("location-component-uuid")
225             .build())
226           .build())
227         .setTextRange(DbCommons.TextRange.newBuilder()
228           .setStartLine(1)
229           .build())
230         .build())
231       .setRuleKey(RuleKey.of("javasecurity", "S123"));
232   }
233
234 }