]> source.dussan.org Git - sonarqube.git/blob
2c4ed265b275dc7ffa71f992101714d2716141f1
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 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.scanner.bootstrap;
21
22 import com.google.common.collect.Lists;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.List;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.picocontainer.behaviors.FieldDecorated;
29 import org.sonar.api.batch.DependedUpon;
30 import org.sonar.api.batch.DependsUpon;
31 import org.sonar.api.batch.Phase;
32 import org.sonar.api.batch.ScannerSide;
33 import org.sonar.api.batch.sensor.Sensor;
34 import org.sonar.api.batch.sensor.SensorContext;
35 import org.sonar.api.batch.sensor.SensorDescriptor;
36 import org.sonar.core.platform.ComponentContainer;
37 import org.sonar.scanner.sensor.DefaultSensorDescriptor;
38 import org.sonar.scanner.sensor.ModuleSensorContext;
39 import org.sonar.scanner.sensor.ModuleSensorExtensionDictionnary;
40 import org.sonar.scanner.sensor.ModuleSensorOptimizer;
41 import org.sonar.scanner.sensor.ModuleSensorWrapper;
42
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.junit.Assert.assertEquals;
45 import static org.mockito.ArgumentMatchers.any;
46 import static org.mockito.Mockito.mock;
47 import static org.mockito.Mockito.when;
48
49 public class ModuleSensorExtensionDictionnaryTest {
50   private ModuleSensorOptimizer sensorOptimizer = mock(ModuleSensorOptimizer.class);
51
52   @Before
53   public void setUp() {
54     when(sensorOptimizer.shouldExecute(any(DefaultSensorDescriptor.class))).thenReturn(true);
55   }
56
57   private ModuleSensorExtensionDictionnary newSelector(Object... extensions) {
58     ComponentContainer iocContainer = new ComponentContainer();
59     for (Object extension : extensions) {
60       iocContainer.addSingleton(extension);
61     }
62     return new ModuleSensorExtensionDictionnary(iocContainer, mock(ModuleSensorContext.class), sensorOptimizer);
63   }
64
65   @Test
66   public void testGetFilteredExtensionWithExtensionMatcher() {
67     final Sensor sensor1 = new FakeSensor();
68     final Sensor sensor2 = new FakeSensor();
69
70     ModuleSensorExtensionDictionnary selector = newSelector(sensor1, sensor2);
71     Collection<Sensor> sensors = selector.select(Sensor.class, true, extension -> extension.equals(sensor1));
72     assertThat(sensors).contains(sensor1);
73     assertEquals(1, sensors.size());
74   }
75
76   @Test
77   public void testGetFilteredExtensions() {
78     Sensor sensor1 = new FakeSensor();
79     Sensor sensor2 = new FakeSensor();
80     FieldDecorated.Decorator decorator = mock(FieldDecorated.Decorator.class);
81
82     ModuleSensorExtensionDictionnary selector = newSelector(sensor1, sensor2, decorator);
83     Collection<Sensor> sensors = selector.select(Sensor.class, false, null);
84
85     assertThat(sensors).containsOnly(sensor1, sensor2);
86   }
87
88   @Test
89   public void shouldSearchInParentContainers() {
90     Sensor a = new FakeSensor();
91     Sensor b = new FakeSensor();
92     Sensor c = new FakeSensor();
93
94     ComponentContainer grandParent = new ComponentContainer();
95     grandParent.addSingleton(a);
96
97     ComponentContainer parent = grandParent.createChild();
98     parent.addSingleton(b);
99
100     ComponentContainer child = parent.createChild();
101     child.addSingleton(c);
102
103     ModuleSensorExtensionDictionnary dictionnary = new ModuleSensorExtensionDictionnary(child, mock(ModuleSensorContext.class), mock(ModuleSensorOptimizer.class));
104     assertThat(dictionnary.select(Sensor.class, true, null)).containsOnly(a, b, c);
105   }
106
107   @Test
108   public void sortExtensionsByDependency() {
109     Object a = new MethodDependentOf(null);
110     Object b = new MethodDependentOf(a);
111     Object c = new MethodDependentOf(b);
112
113     ModuleSensorExtensionDictionnary selector = newSelector(b, c, a);
114     List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
115
116     assertThat(extensions).hasSize(3);
117     assertThat(extensions.get(0)).isEqualTo(a);
118     assertThat(extensions.get(1)).isEqualTo(b);
119     assertThat(extensions.get(2)).isEqualTo(c);
120   }
121
122   @Test
123   public void useMethodAnnotationsToSortExtensions() {
124     Object a = new GeneratesSomething("foo");
125     Object b = new MethodDependentOf("foo");
126
127     ModuleSensorExtensionDictionnary selector = newSelector(a, b);
128     List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
129
130     assertThat(extensions.size()).isEqualTo(2);
131     assertThat(extensions.get(0)).isEqualTo(a);
132     assertThat(extensions.get(1)).isEqualTo(b);
133
134     // different initial order
135     selector = newSelector(b, a);
136     extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
137
138     assertThat(extensions).hasSize(2);
139     assertThat(extensions.get(0)).isEqualTo(a);
140     assertThat(extensions.get(1)).isEqualTo(b);
141   }
142
143   @Test
144   public void methodDependsUponCollection() {
145     Object a = new GeneratesSomething("foo");
146     Object b = new MethodDependentOf(Arrays.asList("foo"));
147
148     ModuleSensorExtensionDictionnary selector = newSelector(a, b);
149     List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
150
151     assertThat(extensions).hasSize(2);
152     assertThat(extensions.get(0)).isEqualTo(a);
153     assertThat(extensions.get(1)).isEqualTo(b);
154
155     // different initial order
156     selector = newSelector(b, a);
157     extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
158
159     assertThat(extensions).hasSize(2);
160     assertThat(extensions.get(0)).isEqualTo(a);
161     assertThat(extensions.get(1)).isEqualTo(b);
162   }
163
164   @Test
165   public void methodDependsUponArray() {
166     Object a = new GeneratesSomething("foo");
167     Object b = new MethodDependentOf(new String[] {"foo"});
168
169     ModuleSensorExtensionDictionnary selector = newSelector(a, b);
170     List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
171
172     assertThat(extensions).hasSize(2);
173     assertThat(extensions.get(0)).isEqualTo(a);
174     assertThat(extensions.get(1)).isEqualTo(b);
175
176     // different initial order
177     selector = newSelector(b, a);
178     extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
179
180     assertThat(extensions).hasSize(2);
181     assertThat(extensions.get(0)).isEqualTo(a);
182     assertThat(extensions.get(1)).isEqualTo(b);
183   }
184
185   @Test
186   public void useClassAnnotationsToSortExtensions() {
187     Object a = new ClassDependedUpon();
188     Object b = new ClassDependsUpon();
189
190     ModuleSensorExtensionDictionnary selector = newSelector(a, b);
191     List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
192
193     assertThat(extensions).hasSize(2);
194     assertThat(extensions.get(0)).isEqualTo(a);
195     assertThat(extensions.get(1)).isEqualTo(b);
196
197     // different initial order
198     selector = newSelector(b, a);
199     extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
200
201     assertThat(extensions).hasSize(2);
202     assertThat(extensions.get(0)).isEqualTo(a);
203     assertThat(extensions.get(1)).isEqualTo(b);
204   }
205
206   @Test
207   public void useClassAnnotationsOnInterfaces() {
208     Object a = new InterfaceDependedUpon() {
209     };
210     Object b = new InterfaceDependsUpon() {
211     };
212
213     ModuleSensorExtensionDictionnary selector = newSelector(a, b);
214     List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
215
216     assertThat(extensions).hasSize(2);
217     assertThat(extensions.get(0)).isEqualTo(a);
218     assertThat(extensions.get(1)).isEqualTo(b);
219
220     // different initial order
221     selector = newSelector(b, a);
222     extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
223
224     assertThat(extensions).hasSize(2);
225     assertThat(extensions.get(0)).isEqualTo(a);
226     assertThat(extensions.get(1)).isEqualTo(b);
227   }
228
229   @Test
230   public void inheritAnnotations() {
231     Object a = new SubClass("foo");
232     Object b = new MethodDependentOf("foo");
233
234     ModuleSensorExtensionDictionnary selector = newSelector(b, a);
235     List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
236
237     assertThat(extensions).hasSize(2);
238     assertThat(extensions.get(0)).isEqualTo(a);
239     assertThat(extensions.get(1)).isEqualTo(b);
240
241     // change initial order
242     selector = newSelector(a, b);
243     extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
244
245     assertThat(extensions).hasSize(2);
246     assertThat(extensions.get(0)).isEqualTo(a);
247     assertThat(extensions.get(1)).isEqualTo(b);
248   }
249
250   @Test(expected = IllegalStateException.class)
251   public void annotatedMethodsCanNotBePrivate() {
252     ModuleSensorExtensionDictionnary selector = newSelector();
253     Object wrong = new Object() {
254       @DependsUpon
255       private Object foo() {
256         return "foo";
257       }
258     };
259     selector.evaluateAnnotatedClasses(wrong, DependsUpon.class);
260   }
261
262   @Test
263   public void dependsUponPhaseForSensors() {
264     PreSensor pre = new PreSensor();
265     NormalSensor normal = new NormalSensor();
266     PostSensor post = new PostSensor();
267
268     ModuleSensorExtensionDictionnary selector = newSelector(normal, post, pre);
269     assertThat(selector.selectSensors(false)).extracting("wrappedSensor").containsExactly(pre, normal, post);
270   }
271
272   @Test
273   public void dependsUponInheritedPhase() {
274     PreSensorSubclass pre = new PreSensorSubclass();
275     NormalSensor normal = new NormalSensor();
276     PostSensorSubclass post = new PostSensorSubclass();
277
278     ModuleSensorExtensionDictionnary selector = newSelector(normal, post, pre);
279     List extensions = Lists.newArrayList(selector.select(Sensor.class, true, null));
280
281     assertThat(extensions).containsExactly(pre, normal, post);
282   }
283
284   @Test
285   public void selectSensors() {
286     FakeSensor nonGlobalSensor = new FakeSensor();
287     FakeGlobalSensor globalSensor = new FakeGlobalSensor();
288     ModuleSensorExtensionDictionnary selector = newSelector(nonGlobalSensor, globalSensor);
289
290     // verify non-global sensor
291     Collection<ModuleSensorWrapper> extensions = selector.selectSensors(false);
292     assertThat(extensions).hasSize(1);
293     assertThat(extensions).extracting("wrappedSensor").containsExactly(nonGlobalSensor);
294
295     // verify global sensor
296     extensions = selector.selectSensors(true);
297     assertThat(extensions).extracting("wrappedSensor").containsExactly(globalSensor);
298   }
299
300   interface Marker {
301
302   }
303
304   class FakeSensor implements Sensor {
305
306     @Override
307     public void describe(SensorDescriptor descriptor) {
308
309     }
310
311     @Override
312     public void execute(SensorContext context) {
313
314     }
315   }
316
317   class FakeGlobalSensor implements Sensor {
318
319     @Override
320     public void describe(SensorDescriptor descriptor) {
321       descriptor.global();
322     }
323
324     @Override
325     public void execute(SensorContext context) {
326     }
327
328   }
329
330   @ScannerSide
331   class MethodDependentOf implements Marker {
332     private Object dep;
333
334     MethodDependentOf(Object o) {
335       this.dep = o;
336     }
337
338     @DependsUpon
339     public Object dependsUponObject() {
340       return dep;
341     }
342   }
343
344   @ScannerSide
345   @DependsUpon("flag")
346   class ClassDependsUpon implements Marker {
347   }
348
349   @ScannerSide
350   @DependedUpon("flag")
351   class ClassDependedUpon implements Marker {
352   }
353
354   @ScannerSide
355   @DependsUpon("flag")
356   interface InterfaceDependsUpon extends Marker {
357   }
358
359   @ScannerSide
360   @DependedUpon("flag")
361   interface InterfaceDependedUpon extends Marker {
362   }
363
364   @ScannerSide
365   class GeneratesSomething implements Marker {
366     private Object gen;
367
368     GeneratesSomething(Object o) {
369       this.gen = o;
370     }
371
372     @DependedUpon
373     public Object generates() {
374       return gen;
375     }
376   }
377
378   class SubClass extends GeneratesSomething implements Marker {
379     SubClass(Object o) {
380       super(o);
381     }
382   }
383
384   class NormalSensor implements Sensor {
385
386     @Override
387     public void describe(SensorDescriptor descriptor) {
388     }
389
390     @Override
391     public void execute(SensorContext context) {
392     }
393
394   }
395
396   @Phase(name = Phase.Name.PRE)
397   class PreSensor implements Sensor {
398
399     @Override
400     public void describe(SensorDescriptor descriptor) {
401     }
402
403     @Override
404     public void execute(SensorContext context) {
405     }
406
407   }
408
409   class PreSensorSubclass extends PreSensor {
410
411   }
412
413   @Phase(name = Phase.Name.POST)
414   class PostSensor implements Sensor {
415
416     @Override
417     public void describe(SensorDescriptor descriptor) {
418     }
419
420     @Override
421     public void execute(SensorContext context) {
422     }
423
424   }
425
426   class PostSensorSubclass extends PostSensor {
427
428   }
429
430 }