3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.computation.task.projectanalysis.step;
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.text.SimpleDateFormat;
26 import java.util.List;
27 import org.junit.Before;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.sonar.api.config.Settings;
32 import org.sonar.api.utils.System2;
33 import org.sonar.api.utils.log.LogTester;
34 import org.sonar.db.DbClient;
35 import org.sonar.db.DbTester;
36 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
37 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
38 import org.sonar.server.computation.task.projectanalysis.component.Component;
39 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
40 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
41 import org.sonar.server.computation.task.projectanalysis.component.ViewsComponent;
42 import org.sonar.server.computation.task.projectanalysis.period.Period;
43 import org.sonar.server.computation.task.projectanalysis.period.PeriodsHolderImpl;
44 import org.sonar.server.computation.task.step.ComputationStep;
46 import static org.assertj.core.api.Assertions.assertThat;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.when;
49 import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_DATE;
50 import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_DAYS;
51 import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS;
52 import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_PREVIOUS_VERSION;
53 import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_VERSION;
56 @RunWith(DataProviderRunner.class)
57 public class LoadPeriodsStepTest extends BaseStepTest {
59 private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
60 private static final String ROOT_KEY = "ROOT_KEY";
61 private static final ReportComponent PROJECT_ROOT = ReportComponent.builder(Component.Type.PROJECT, 1).setUuid("ABCD").setKey(ROOT_KEY).setVersion("1.1").build();
62 private static final ViewsComponent VIEW_ROOT = ViewsComponent.builder(Component.Type.VIEW, ROOT_KEY).setUuid("ABCD").build();
65 public DbTester dbTester = DbTester.create(System2.INSTANCE);
67 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
69 public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
71 public LogTester logTester = new LogTester();
73 PeriodsHolderImpl periodsHolder = new PeriodsHolderImpl();
74 DbClient dbClient = dbTester.getDbClient();
75 Settings settings = new Settings();
76 SettingsRepository settingsRepository = mock(SettingsRepository.class);
78 LoadPeriodsStep underTest;
81 protected ComputationStep step() {
86 public void setUp() throws Exception {
87 analysisMetadataHolder.setAnalysisDate(DATE_FORMAT.parse("2008-11-30").getTime());
89 underTest = new LoadPeriodsStep(dbClient, settingsRepository, treeRootHolder, analysisMetadataHolder, periodsHolder);
92 private void setupRoot(Component root) {
93 treeRootHolder.setRoot(root);
94 when(settingsRepository.getSettings(root)).thenReturn(settings);
98 public static Object[][] projectAndViewRoots() {
99 return new Object[][] {
106 @UseDataProvider("projectAndViewRoots")
107 public void no_period_on_first_analysis(Component root) {
110 // No project, no snapshot
113 assertThat(periodsHolder.getPeriods()).isEmpty();
117 @UseDataProvider("projectAndViewRoots")
118 public void feed_one_period(Component root) {
121 dbTester.prepareDbUnit(getClass(), "shared.xml");
123 String textDate = "2008-11-22";
124 settings.setProperty("sonar.timemachine.period1", textDate);
127 List<Period> periods = periodsHolder.getPeriods();
128 assertThat(periods).hasSize(1);
130 Period period = periods.get(0);
131 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_DATE);
132 assertThat(period.getModeParameter()).isEqualTo(textDate);
133 assertThat(period.getSnapshotDate()).isEqualTo(1227358680000L);
134 assertThat(period.getAnalysisUuid()).isEqualTo("u1003");
138 @UseDataProvider("projectAndViewRoots")
139 public void no_period_when_settings_match_no_analysis(Component root) {
142 dbTester.prepareDbUnit(getClass(), "shared.xml");
144 settings.setProperty("sonar.timemachine.period1", "UNKNWOWN VERSION");
147 assertThat(periodsHolder.getPeriods()).isEmpty();
151 @UseDataProvider("projectAndViewRoots")
152 public void no_period_when_settings_is_empty(Component root) {
155 dbTester.prepareDbUnit(getClass(), "shared.xml");
157 settings.setProperty("sonar.timemachine.period1", "");
160 assertThat(periodsHolder.getPeriods()).isEmpty();
164 @UseDataProvider("projectAndViewRoots")
165 public void ignore_unprocessed_snapshots(Component root) {
168 dbTester.prepareDbUnit(getClass(), "unprocessed_snapshots.xml");
170 settings.setProperty("sonar.timemachine.period1", "100");
173 assertThat(periodsHolder.getPeriods()).isEmpty();
177 @UseDataProvider("projectAndViewRoots")
178 public void feed_period_by_date(Component root) {
181 dbTester.prepareDbUnit(getClass(), "shared.xml");
183 String textDate = "2008-11-22";
184 settings.setProperty("sonar.timemachine.period1", textDate);
187 List<Period> periods = periodsHolder.getPeriods();
188 assertThat(periods).hasSize(1);
190 Period period = periods.get(0);
191 // Return analysis from given date 2008-11-22
192 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_DATE);
193 assertThat(period.getModeParameter()).isEqualTo(textDate);
194 assertThat(period.getSnapshotDate()).isEqualTo(1227358680000L);
195 assertThat(period.getAnalysisUuid()).isEqualTo("u1003");
197 assertThat(logTester.logs()).hasSize(1);
198 assertThat(logTester.logs().get(0)).startsWith("Compare to date 2008-11-22 (analysis of ");
202 @UseDataProvider("projectAndViewRoots")
203 public void search_by_date_return_nearest_later_analysis(Component root) {
206 dbTester.prepareDbUnit(getClass(), "shared.xml");
207 String date = "2008-11-24";
209 settings.setProperty("sonar.timemachine.period1", date);
212 List<Period> periods = periodsHolder.getPeriods();
213 assertThat(periods).hasSize(1);
215 // Analysis form 2008-11-29
216 Period period = periods.get(0);
217 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_DATE);
218 assertThat(period.getModeParameter()).isEqualTo(date);
219 assertThat(period.getSnapshotDate()).isEqualTo(1227934800000L);
220 assertThat(period.getAnalysisUuid()).isEqualTo("u1004");
224 @UseDataProvider("projectAndViewRoots")
225 public void no_period_by_date(Component root) {
228 dbTester.prepareDbUnit(getClass(), "shared.xml");
230 // No analysis at and after this date
231 settings.setProperty("sonar.timemachine.period1", "2008-11-30");
234 assertThat(periodsHolder.getPeriods()).isEmpty();
238 @UseDataProvider("projectAndViewRoots")
239 public void feed_period_by_days(Component root) {
242 dbTester.prepareDbUnit(getClass(), "shared.xml");
244 settings.setProperty("sonar.timemachine.period1", "10");
247 List<Period> periods = periodsHolder.getPeriods();
248 assertThat(periods).hasSize(1);
250 // return analysis from 2008-11-20
251 Period period = periods.get(0);
252 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_DAYS);
253 assertThat(period.getModeParameter()).isEqualTo("10");
254 assertThat(period.getSnapshotDate()).isEqualTo(1227157200000L);
255 assertThat(period.getAnalysisUuid()).isEqualTo("u1002");
257 assertThat(logTester.logs()).hasSize(1);
258 assertThat(logTester.logs().get(0)).startsWith("Compare over 10 days (2008-11-20, analysis of ");
262 @UseDataProvider("projectAndViewRoots")
263 public void no_period_by_days(Component root) {
266 dbTester.prepareDbUnit(getClass(), "empty.xml");
268 settings.setProperty("sonar.timemachine.period1", "0");
271 assertThat(periodsHolder.getPeriods()).isEmpty();
275 @UseDataProvider("projectAndViewRoots")
276 public void feed_period_by_previous_analysis(Component root) {
279 dbTester.prepareDbUnit(getClass(), "shared.xml");
281 settings.setProperty("sonar.timemachine.period1", "previous_analysis");
284 List<Period> periods = periodsHolder.getPeriods();
285 assertThat(periods).hasSize(1);
287 // return analysis from 2008-11-29
288 Period period = periods.get(0);
289 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
290 assertThat(period.getModeParameter()).isNotNull();
291 assertThat(period.getSnapshotDate()).isEqualTo(1227934800000L);
292 assertThat(period.getAnalysisUuid()).isEqualTo("u1004");
294 assertThat(logTester.logs()).hasSize(1);
295 assertThat(logTester.logs().get(0)).startsWith("Compare to previous analysis (");
299 @UseDataProvider("projectAndViewRoots")
300 public void no_period_by_previous_analysis(Component root) {
303 dbTester.prepareDbUnit(getClass(), "empty.xml");
305 settings.setProperty("sonar.timemachine.period1", "previous_analysis");
308 assertThat(periodsHolder.getPeriods()).isEmpty();
312 public void feed_period_by_previous_version() {
313 setupRoot(PROJECT_ROOT);
315 dbTester.prepareDbUnit(getClass(), "shared.xml");
317 settings.setProperty("sonar.timemachine.period1", "previous_version");
320 List<Period> periods = periodsHolder.getPeriods();
321 assertThat(periods).hasSize(1);
323 // Analysis form 2008-11-12
324 Period period = periods.get(0);
325 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_VERSION);
326 assertThat(period.getModeParameter()).isEqualTo("1.0");
327 assertThat(period.getSnapshotDate()).isEqualTo(1226494680000L);
328 assertThat(period.getAnalysisUuid()).isEqualTo("u1001");
330 assertThat(logTester.logs()).hasSize(1);
331 assertThat(logTester.logs().get(0)).startsWith("Compare to previous version (");
335 public void feed_period_by_previous_version_is_not_supported_for_views() {
336 setupRoot(VIEW_ROOT);
338 dbTester.prepareDbUnit(getClass(), "shared.xml");
340 settings.setProperty("sonar.timemachine.period1", "previous_version");
343 List<Period> periods = periodsHolder.getPeriods();
344 assertThat(periods).hasSize(0);
348 public void feed_period_by_previous_version_with_previous_version_deleted() {
349 setupRoot(PROJECT_ROOT);
351 dbTester.prepareDbUnit(getClass(), "previous_version_deleted.xml");
353 settings.setProperty("sonar.timemachine.period1", "previous_version");
356 List<Period> periods = periodsHolder.getPeriods();
357 assertThat(periods).hasSize(1);
359 // Analysis form 2008-11-11
360 Period period = periods.get(0);
361 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_VERSION);
362 assertThat(period.getModeParameter()).isEqualTo("0.9");
363 assertThat(period.getSnapshotDate()).isEqualTo(1226379600000L);
364 assertThat(period.getAnalysisUuid()).isEqualTo("u1000");
368 @UseDataProvider("projectAndViewRoots")
369 public void no_period_by_previous_version(Component root) {
372 dbTester.prepareDbUnit(getClass(), "empty.xml");
374 settings.setProperty("sonar.timemachine.period1", "previous_version");
377 assertThat(periodsHolder.getPeriods()).isEmpty();
381 public void feed_period_by_previous_version_with_first_analysis_when_no_previous_version_found() {
382 setupRoot(PROJECT_ROOT);
384 dbTester.prepareDbUnit(getClass(), "no_previous_version.xml");
386 settings.setProperty("sonar.timemachine.period1", "previous_version");
389 List<Period> periods = periodsHolder.getPeriods();
390 assertThat(periods).hasSize(1);
392 Period period = periods.get(0);
393 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_VERSION);
394 assertThat(period.getModeParameter()).isNull();
395 assertThat(period.getSnapshotDate()).isEqualTo(1226379600000L);
396 assertThat(period.getAnalysisUuid()).isEqualTo("u1000");
400 public void feed_period_by_previous_version_with_first_analysis_when_previous_snapshot_is_the_last_one() {
401 setupRoot(PROJECT_ROOT);
403 dbTester.prepareDbUnit(getClass(), "previous_version_is_last_one.xml");
405 settings.setProperty("sonar.timemachine.period1", "previous_version");
408 List<Period> periods = periodsHolder.getPeriods();
409 assertThat(periods).hasSize(1);
411 Period period = periods.get(0);
412 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_VERSION);
413 assertThat(period.getModeParameter()).isNull();
414 assertThat(period.getSnapshotDate()).isEqualTo(1226379600000L);
415 assertThat(period.getAnalysisUuid()).isEqualTo("u1000");
419 public void no_period_by_previous_version_when_no_event_version_for_views() {
420 setupRoot(VIEW_ROOT);
422 dbTester.prepareDbUnit(getClass(), "no_previous_version.xml");
424 settings.setProperty("sonar.timemachine.period1", "previous_version");
427 assertThat(periodsHolder.getPeriods()).isEmpty();
431 @UseDataProvider("projectAndViewRoots")
432 public void feed_period_by_version(Component root) {
435 dbTester.prepareDbUnit(getClass(), "shared.xml");
437 settings.setProperty("sonar.timemachine.period1", "0.9");
440 List<Period> periods = periodsHolder.getPeriods();
441 assertThat(periods).hasSize(1);
443 // Analysis form 2008-11-11
444 Period period = periods.get(0);
445 assertThat(period.getMode()).isEqualTo(TIMEMACHINE_MODE_VERSION);
446 assertThat(period.getModeParameter()).isEqualTo("0.9");
447 assertThat(period.getSnapshotDate()).isEqualTo(1226379600000L);
448 assertThat(period.getAnalysisUuid()).isEqualTo("u1000");
450 assertThat(logTester.logs()).hasSize(1);
451 assertThat(logTester.logs().get(0)).startsWith("Compare to version (0.9) (");
455 @UseDataProvider("projectAndViewRoots")
456 public void no_period_by_version(Component root) {
459 dbTester.prepareDbUnit(getClass(), "empty.xml");
461 settings.setProperty("sonar.timemachine.period1", "0.8");
464 assertThat(periodsHolder.getPeriods()).isEmpty();
468 public void all_five_types_of_periods_are_supported_for_PROJECT_component_tree() {
469 setupRoot(PROJECT_ROOT);
471 dbTester.prepareDbUnit(getClass(), "shared.xml");
473 settings.setProperty("sonar.timemachine.period1", "2008-11-22"); // Analysis from 2008-11-22 should be returned
474 settings.setProperty("sonar.timemachine.period2", "10"); // Analysis from 2008-11-20 should be returned
475 settings.setProperty("sonar.timemachine.period3", "previous_analysis"); // Analysis from 2008-11-29 should be returned
476 settings.setProperty("sonar.timemachine.period4", "previous_version"); // Analysis from 2008-11-12 should be returned
477 settings.setProperty("sonar.timemachine.period5", "0.9"); // Analysis from 2008-11-11
480 List<Period> periods = periodsHolder.getPeriods();
482 assertThat(periods).extracting("mode").containsExactly(TIMEMACHINE_MODE_DATE, TIMEMACHINE_MODE_DAYS,
483 TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, TIMEMACHINE_MODE_PREVIOUS_VERSION,
484 TIMEMACHINE_MODE_VERSION);
486 assertThat(periods.get(0).getMode()).isEqualTo(TIMEMACHINE_MODE_DATE);
487 assertThat(periods.get(0).getIndex()).isEqualTo(1);
488 assertThat(periods.get(0).getSnapshotDate()).isEqualTo(1227358680000L);
490 assertThat(periods.get(1).getMode()).isEqualTo(TIMEMACHINE_MODE_DAYS);
491 assertThat(periods.get(1).getIndex()).isEqualTo(2);
492 assertThat(periods.get(1).getSnapshotDate()).isEqualTo(1227157200000L);
494 assertThat(periods.get(2).getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
495 assertThat(periods.get(2).getIndex()).isEqualTo(3);
496 assertThat(periods.get(2).getSnapshotDate()).isEqualTo(1227934800000L);
498 assertThat(periods.get(3).getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_VERSION);
499 assertThat(periods.get(3).getIndex()).isEqualTo(4);
500 assertThat(periods.get(3).getSnapshotDate()).isEqualTo(1226494680000L);
502 assertThat(periods.get(4).getMode()).isEqualTo(TIMEMACHINE_MODE_VERSION);
503 assertThat(periods.get(4).getIndex()).isEqualTo(5);
504 assertThat(periods.get(4).getSnapshotDate()).isEqualTo(1226379600000L);
508 public void feed_four_different_periods() {
509 setupRoot(VIEW_ROOT);
511 dbTester.prepareDbUnit(getClass(), "shared.xml");
513 settings.setProperty("sonar.timemachine.period1", "2008-11-22"); // Analysis from 2008-11-22 should be returned
514 settings.setProperty("sonar.timemachine.period2", "10"); // Analysis from 2008-11-20 should be returned
515 settings.setProperty("sonar.timemachine.period3", "previous_analysis"); // Analysis from 2008-11-29 should be returned
516 settings.setProperty("sonar.timemachine.period4", "previous_version"); // Analysis from 2008-11-12 should be returned
517 settings.setProperty("sonar.timemachine.period5", "0.9"); // Analysis from 2008-11-11
520 List<Period> periods = periodsHolder.getPeriods();
522 assertThat(periods).extracting("mode").containsExactly(
523 TIMEMACHINE_MODE_DATE, TIMEMACHINE_MODE_DAYS,
524 TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, TIMEMACHINE_MODE_VERSION);
526 assertThat(periods.get(0).getMode()).isEqualTo(TIMEMACHINE_MODE_DATE);
527 assertThat(periods.get(0).getIndex()).isEqualTo(1);
528 assertThat(periods.get(0).getSnapshotDate()).isEqualTo(1227358680000L);
530 assertThat(periods.get(1).getMode()).isEqualTo(TIMEMACHINE_MODE_DAYS);
531 assertThat(periods.get(1).getIndex()).isEqualTo(2);
532 assertThat(periods.get(1).getSnapshotDate()).isEqualTo(1227157200000L);
534 assertThat(periods.get(2).getMode()).isEqualTo(TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
535 assertThat(periods.get(2).getIndex()).isEqualTo(3);
536 assertThat(periods.get(2).getSnapshotDate()).isEqualTo(1227934800000L);
538 assertThat(periods.get(3).getMode()).isEqualTo(TIMEMACHINE_MODE_VERSION);
539 assertThat(periods.get(3).getIndex()).isEqualTo(5);
540 assertThat(periods.get(3).getSnapshotDate()).isEqualTo(1226379600000L);
544 public void can_use_project_qualifier_in_settings() {
545 setupRoot(PROJECT_ROOT);
547 dbTester.prepareDbUnit(getClass(), "shared.xml");
549 settings.setProperty("sonar.timemachine.period4.TRK", "2008-11-22");
550 settings.setProperty("sonar.timemachine.period5.TRK", "previous_analysis");
553 assertThat(periodsHolder.getPeriods()).hasSize(2);
557 public void can_use_views_qualifier_in_settings() {
558 setupRoot(VIEW_ROOT);
560 dbTester.prepareDbUnit(getClass(), "shared.xml");
562 settings.setProperty("sonar.timemachine.period4.VW", "2008-11-22");
563 settings.setProperty("sonar.timemachine.period5.VW", "previous_analysis");
566 assertThat(periodsHolder.getPeriods()).hasSize(2);