]> source.dussan.org Git - sonarqube.git/blob
600a387656463e0a91df0f15dac86101d0675b80
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 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.server.project;
21
22 import com.tngtech.java.junit.dataprovider.DataProvider;
23 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
24 import com.tngtech.java.junit.dataprovider.UseDataProvider;
25 import java.util.Collections;
26 import java.util.Random;
27 import java.util.Set;
28 import java.util.stream.Collectors;
29 import java.util.stream.IntStream;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.InOrder;
33 import org.mockito.Mockito;
34
35 import static java.util.Collections.singleton;
36 import static org.assertj.core.api.Assertions.assertThatCode;
37 import static org.assertj.core.api.Assertions.assertThatNoException;
38 import static org.assertj.core.api.Assertions.assertThatThrownBy;
39 import static org.mockito.ArgumentMatchers.any;
40 import static org.mockito.ArgumentMatchers.same;
41 import static org.mockito.Mockito.doThrow;
42 import static org.mockito.Mockito.mock;
43 import static org.mockito.Mockito.verifyNoInteractions;
44 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
45
46 @RunWith(DataProviderRunner.class)
47 public class ProjectLifeCycleListenersImplTest {
48
49   private final ProjectLifeCycleListener listener1 = mock(ProjectLifeCycleListener.class);
50   private final ProjectLifeCycleListener listener2 = mock(ProjectLifeCycleListener.class);
51   private final ProjectLifeCycleListener listener3 = mock(ProjectLifeCycleListener.class);
52   private final ProjectLifeCycleListenersImpl underTestNoListeners = new ProjectLifeCycleListenersImpl();
53   private final ProjectLifeCycleListenersImpl underTestWithListeners = new ProjectLifeCycleListenersImpl(
54     new ProjectLifeCycleListener[] {listener1, listener2, listener3});
55
56   @Test
57   public void onProjectsDeleted_throws_NPE_if_set_is_null() {
58     assertThatThrownBy(() -> underTestWithListeners.onProjectsDeleted(null))
59       .isInstanceOf(NullPointerException.class)
60       .hasMessage("projects can't be null");
61   }
62
63   @Test
64   public void onProjectsDeleted_throws_NPE_if_set_is_null_even_if_no_listeners() {
65     assertThatThrownBy(() -> underTestNoListeners.onProjectsDeleted(null))
66       .isInstanceOf(NullPointerException.class)
67       .hasMessage("projects can't be null");
68   }
69
70   @Test
71   public void onProjectsDeleted_has_no_effect_if_set_is_empty() {
72     underTestNoListeners.onProjectsDeleted(Collections.emptySet());
73
74     underTestWithListeners.onProjectsDeleted(Collections.emptySet());
75     verifyNoInteractions(listener1, listener2, listener3);
76   }
77
78   @Test
79   @UseDataProvider("oneOrManyDeletedProjects")
80   public void onProjectsDeleted_does_not_fail_if_there_is_no_listener(Set<DeletedProject> projects) {
81     assertThatCode(() -> underTestNoListeners.onProjectsDeleted(projects)).doesNotThrowAnyException();
82   }
83
84   @Test
85   @UseDataProvider("oneOrManyDeletedProjects")
86   public void onProjectsDeleted_calls_all_listeners_in_order_of_addition_to_constructor(Set<DeletedProject> projects) {
87     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
88
89     underTestWithListeners.onProjectsDeleted(projects);
90
91     inOrder.verify(listener1).onProjectsDeleted(same(projects));
92     inOrder.verify(listener2).onProjectsDeleted(same(projects));
93     inOrder.verify(listener3).onProjectsDeleted(same(projects));
94     inOrder.verifyNoMoreInteractions();
95   }
96
97   @Test
98   @UseDataProvider("oneOrManyDeletedProjects")
99   public void onProjectsDeleted_calls_all_listeners_even_if_one_throws_an_Exception(Set<DeletedProject> projects) {
100     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
101     doThrow(new RuntimeException("Faking listener2 throwing an exception"))
102       .when(listener2)
103       .onProjectsDeleted(any());
104
105     underTestWithListeners.onProjectsDeleted(projects);
106
107     inOrder.verify(listener1).onProjectsDeleted(same(projects));
108     inOrder.verify(listener2).onProjectsDeleted(same(projects));
109     inOrder.verify(listener3).onProjectsDeleted(same(projects));
110     inOrder.verifyNoMoreInteractions();
111   }
112
113   @Test
114   @UseDataProvider("oneOrManyDeletedProjects")
115   public void onProjectsDeleted_calls_all_listeners_even_if_one_throws_an_Error(Set<DeletedProject> projects) {
116     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
117     doThrow(new Error("Faking listener2 throwing an Error"))
118       .when(listener2)
119       .onProjectsDeleted(any());
120
121     underTestWithListeners.onProjectsDeleted(projects);
122
123     inOrder.verify(listener1).onProjectsDeleted(same(projects));
124     inOrder.verify(listener2).onProjectsDeleted(same(projects));
125     inOrder.verify(listener3).onProjectsDeleted(same(projects));
126     inOrder.verifyNoMoreInteractions();
127   }
128
129   @Test
130   public void onProjectBranchesChanged_throws_NPE_if_set_is_null() {
131     assertThatThrownBy(() -> underTestWithListeners.onProjectBranchesChanged(null))
132       .isInstanceOf(NullPointerException.class)
133       .hasMessage("projects can't be null");
134   }
135
136   @Test
137   public void onProjectBranchesChanged_throws_NPE_if_set_is_null_even_if_no_listeners() {
138     assertThatThrownBy(() -> underTestNoListeners.onProjectBranchesChanged(null))
139       .isInstanceOf(NullPointerException.class)
140       .hasMessage("projects can't be null");
141   }
142
143   @Test
144   public void onProjectBranchesChanged_has_no_effect_if_set_is_empty() {
145     underTestNoListeners.onProjectBranchesChanged(Collections.emptySet());
146
147     underTestWithListeners.onProjectBranchesChanged(Collections.emptySet());
148     verifyNoInteractions(listener1, listener2, listener3);
149   }
150
151   @Test
152   @UseDataProvider("oneOrManyProjects")
153   public void onProjectBranchesChanged_does_not_fail_if_there_is_no_listener(Set<Project> projects) {
154      assertThatNoException().isThrownBy(()-> underTestNoListeners.onProjectBranchesChanged(projects));
155   }
156
157   @Test
158   @UseDataProvider("oneOrManyProjects")
159   public void onProjectBranchesChanged_calls_all_listeners_in_order_of_addition_to_constructor(Set<Project> projects) {
160     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
161
162     underTestWithListeners.onProjectBranchesChanged(projects);
163
164     inOrder.verify(listener1).onProjectBranchesChanged(same(projects));
165     inOrder.verify(listener2).onProjectBranchesChanged(same(projects));
166     inOrder.verify(listener3).onProjectBranchesChanged(same(projects));
167     inOrder.verifyNoMoreInteractions();
168   }
169
170   @Test
171   @UseDataProvider("oneOrManyProjects")
172   public void onProjectBranchesChanged_calls_all_listeners_even_if_one_throws_an_Exception(Set<Project> projects) {
173     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
174     doThrow(new RuntimeException("Faking listener2 throwing an exception"))
175       .when(listener2)
176       .onProjectBranchesChanged(any());
177
178     underTestWithListeners.onProjectBranchesChanged(projects);
179
180     inOrder.verify(listener1).onProjectBranchesChanged(same(projects));
181     inOrder.verify(listener2).onProjectBranchesChanged(same(projects));
182     inOrder.verify(listener3).onProjectBranchesChanged(same(projects));
183     inOrder.verifyNoMoreInteractions();
184   }
185
186   @Test
187   @UseDataProvider("oneOrManyProjects")
188   public void onProjectBranchesChanged_calls_all_listeners_even_if_one_throws_an_Error(Set<Project> projects) {
189     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
190     doThrow(new Error("Faking listener2 throwing an Error"))
191       .when(listener2)
192       .onProjectBranchesChanged(any());
193
194     underTestWithListeners.onProjectBranchesChanged(projects);
195
196     inOrder.verify(listener1).onProjectBranchesChanged(same(projects));
197     inOrder.verify(listener2).onProjectBranchesChanged(same(projects));
198     inOrder.verify(listener3).onProjectBranchesChanged(same(projects));
199     inOrder.verifyNoMoreInteractions();
200   }
201
202   @DataProvider
203   public static Object[][] oneOrManyProjects() {
204     return new Object[][] {
205       {singleton(newUniqueProject())},
206       {IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> newUniqueProject()).collect(Collectors.toSet())}
207     };
208   }
209
210   @DataProvider
211   public static Object[][] oneOrManyDeletedProjects() {
212     return new Object[][] {
213       {singleton(newUniqueProject())},
214       {IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> new DeletedProject(newUniqueProject(), "branch_" + i))
215         .collect(Collectors.toSet())}
216     };
217   }
218
219   @Test
220   public void onProjectsRekeyed_throws_NPE_if_set_is_null() {
221     assertThatThrownBy(() -> underTestWithListeners.onProjectsRekeyed(null))
222       .isInstanceOf(NullPointerException.class)
223       .hasMessage("rekeyedProjects can't be null");
224   }
225
226   @Test
227   public void onProjectsRekeyed_throws_NPE_if_set_is_null_even_if_no_listeners() {
228     assertThatThrownBy(() -> underTestNoListeners.onProjectsRekeyed(null))
229       .isInstanceOf(NullPointerException.class)
230       .hasMessage("rekeyedProjects can't be null");
231   }
232
233   @Test
234   public void onProjectsRekeyed_has_no_effect_if_set_is_empty() {
235     underTestNoListeners.onProjectsRekeyed(Collections.emptySet());
236
237     underTestWithListeners.onProjectsRekeyed(Collections.emptySet());
238     verifyNoInteractions(listener1, listener2, listener3);
239   }
240
241   @Test
242   @UseDataProvider("oneOrManyRekeyedProjects")
243   public void onProjectsRekeyed_does_not_fail_if_there_is_no_listener(Set<RekeyedProject> projects) {
244     assertThatNoException().isThrownBy(() -> underTestNoListeners.onProjectsRekeyed(projects));
245   }
246
247   @Test
248   @UseDataProvider("oneOrManyRekeyedProjects")
249   public void onProjectsRekeyed_calls_all_listeners_in_order_of_addition_to_constructor(Set<RekeyedProject> projects) {
250     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
251
252     underTestWithListeners.onProjectsRekeyed(projects);
253
254     inOrder.verify(listener1).onProjectsRekeyed(same(projects));
255     inOrder.verify(listener2).onProjectsRekeyed(same(projects));
256     inOrder.verify(listener3).onProjectsRekeyed(same(projects));
257     inOrder.verifyNoMoreInteractions();
258   }
259
260   @Test
261   @UseDataProvider("oneOrManyRekeyedProjects")
262   public void onProjectsRekeyed_calls_all_listeners_even_if_one_throws_an_Exception(Set<RekeyedProject> projects) {
263     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
264     doThrow(new RuntimeException("Faking listener2 throwing an exception"))
265       .when(listener2)
266       .onProjectsRekeyed(any());
267
268     underTestWithListeners.onProjectsRekeyed(projects);
269
270     inOrder.verify(listener1).onProjectsRekeyed(same(projects));
271     inOrder.verify(listener2).onProjectsRekeyed(same(projects));
272     inOrder.verify(listener3).onProjectsRekeyed(same(projects));
273     inOrder.verifyNoMoreInteractions();
274   }
275
276   @Test
277   @UseDataProvider("oneOrManyRekeyedProjects")
278   public void onProjectsRekeyed_calls_all_listeners_even_if_one_throws_an_Error(Set<RekeyedProject> projects) {
279     InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
280     doThrow(new Error("Faking listener2 throwing an Error"))
281       .when(listener2)
282       .onProjectsRekeyed(any());
283
284     underTestWithListeners.onProjectsRekeyed(projects);
285
286     inOrder.verify(listener1).onProjectsRekeyed(same(projects));
287     inOrder.verify(listener2).onProjectsRekeyed(same(projects));
288     inOrder.verify(listener3).onProjectsRekeyed(same(projects));
289     inOrder.verifyNoMoreInteractions();
290   }
291
292   @DataProvider
293   public static Object[][] oneOrManyRekeyedProjects() {
294     return new Object[][] {
295       {singleton(newUniqueRekeyedProject())},
296       {IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> newUniqueRekeyedProject()).collect(Collectors.toSet())}
297     };
298   }
299
300   private static Project newUniqueProject() {
301     return Project.from(newPrivateProjectDto());
302   }
303
304   private static int counter = 3_989;
305
306   private static RekeyedProject newUniqueRekeyedProject() {
307     int base = counter++;
308     Project project = Project.from(newPrivateProjectDto());
309     return new RekeyedProject(project, base + "_old_key");
310   }
311 }