You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LoadPeriodsStepTest.java 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  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.ce.task.projectanalysis.step;
  21. import com.tngtech.java.junit.dataprovider.DataProvider;
  22. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  23. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  24. import java.text.SimpleDateFormat;
  25. import java.util.Arrays;
  26. import java.util.Date;
  27. import java.util.Random;
  28. import java.util.stream.Stream;
  29. import javax.annotation.Nullable;
  30. import org.junit.Before;
  31. import org.junit.Rule;
  32. import org.junit.Test;
  33. import org.junit.rules.ExpectedException;
  34. import org.junit.runner.RunWith;
  35. import org.sonar.api.impl.config.MapSettings;
  36. import org.sonar.api.utils.MessageException;
  37. import org.sonar.api.utils.System2;
  38. import org.sonar.api.utils.log.LogAndArguments;
  39. import org.sonar.api.utils.log.LogTester;
  40. import org.sonar.api.utils.log.LoggerLevel;
  41. import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
  42. import org.sonar.ce.task.projectanalysis.analysis.Branch;
  43. import org.sonar.ce.task.projectanalysis.component.Component;
  44. import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
  45. import org.sonar.ce.task.projectanalysis.component.ReportComponent;
  46. import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
  47. import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
  48. import org.sonar.ce.task.projectanalysis.period.Period;
  49. import org.sonar.ce.task.projectanalysis.period.PeriodHolderImpl;
  50. import org.sonar.ce.task.step.ComputationStep;
  51. import org.sonar.ce.task.step.TestComputationStepContext;
  52. import org.sonar.db.DbClient;
  53. import org.sonar.db.DbTester;
  54. import org.sonar.db.component.BranchDto;
  55. import org.sonar.db.component.BranchType;
  56. import org.sonar.db.component.ComponentDto;
  57. import org.sonar.db.component.SnapshotDto;
  58. import org.sonar.db.event.EventTesting;
  59. import org.sonar.db.organization.OrganizationDto;
  60. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  61. import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
  62. import static org.assertj.core.api.Assertions.assertThat;
  63. import static org.assertj.core.api.Assertions.fail;
  64. import static org.mockito.Mockito.doReturn;
  65. import static org.mockito.Mockito.mock;
  66. import static org.mockito.Mockito.verify;
  67. import static org.mockito.Mockito.verifyNoMoreInteractions;
  68. import static org.mockito.Mockito.verifyZeroInteractions;
  69. import static org.mockito.Mockito.when;
  70. import static org.sonar.core.config.CorePropertyDefinitions.LEAK_PERIOD_MODE_DATE;
  71. import static org.sonar.core.config.CorePropertyDefinitions.LEAK_PERIOD_MODE_DAYS;
  72. import static org.sonar.core.config.CorePropertyDefinitions.LEAK_PERIOD_MODE_MANUAL_BASELINE;
  73. import static org.sonar.core.config.CorePropertyDefinitions.LEAK_PERIOD_MODE_PREVIOUS_VERSION;
  74. import static org.sonar.core.config.CorePropertyDefinitions.LEAK_PERIOD_MODE_VERSION;
  75. import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
  76. import static org.sonar.db.component.SnapshotDto.STATUS_UNPROCESSED;
  77. import static org.sonar.db.event.EventDto.CATEGORY_VERSION;
  78. import static org.sonar.db.event.EventTesting.newEvent;
  79. @RunWith(DataProviderRunner.class)
  80. public class LoadPeriodsStepTest extends BaseStepTest {
  81. private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
  82. @Rule
  83. public DbTester dbTester = DbTester.create(System2.INSTANCE);
  84. @Rule
  85. public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
  86. @Rule
  87. public LogTester logTester = new LogTester();
  88. @Rule
  89. public ExpectedException expectedException = ExpectedException.none();
  90. private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
  91. private PeriodHolderImpl periodsHolder = new PeriodHolderImpl();
  92. private MapSettings settings = new MapSettings();
  93. private ConfigurationRepository configurationRepository = mock(ConfigurationRepository.class);
  94. private System2 system2Mock = mock(System2.class);
  95. private LoadPeriodsStep underTest = new LoadPeriodsStep(analysisMetadataHolder, treeRootHolder, periodsHolder, system2Mock,
  96. dbTester.getDbClient(), configurationRepository);
  97. private Date november30th2008;
  98. @Override
  99. protected ComputationStep step() {
  100. return underTest;
  101. }
  102. @Before
  103. public void setUp() throws Exception {
  104. november30th2008 = DATE_FORMAT.parse("2008-11-30");
  105. when(analysisMetadataHolder.isLongLivingBranch()).thenReturn(true);
  106. }
  107. @Test
  108. public void no_period_on_first_analysis_and_execute_has_no_effect() {
  109. TreeRootHolder treeRootHolderMock = mock(TreeRootHolder.class);
  110. PeriodHolderImpl periodHolderMock = mock(PeriodHolderImpl.class);
  111. DbClient dbClientMock = mock(DbClient.class);
  112. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(true);
  113. LoadPeriodsStep underTest = new LoadPeriodsStep(analysisMetadataHolder, treeRootHolderMock, periodHolderMock, system2Mock, dbClientMock, configurationRepository);
  114. underTest.execute(new TestComputationStepContext());
  115. verify(analysisMetadataHolder).isFirstAnalysis();
  116. verify(periodHolderMock).setPeriod(null);
  117. verifyNoMoreInteractions(analysisMetadataHolder, periodHolderMock);
  118. verifyZeroInteractions(treeRootHolderMock, system2Mock, dbClientMock, configurationRepository);
  119. }
  120. @Test
  121. public void feed_one_period() {
  122. OrganizationDto organization = dbTester.organizations().insert();
  123. ComponentDto project = dbTester.components().insertMainBranch(organization);
  124. SnapshotDto analysis = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L)); // 2008-11-29
  125. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  126. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  127. setupRoot(project);
  128. setupBranchWithNoManualBaseline(project);
  129. String textDate = "2008-11-22";
  130. settings.setProperty("sonar.leak.period", textDate);
  131. underTest.execute(new TestComputationStepContext());
  132. assertPeriod(LEAK_PERIOD_MODE_DATE, textDate, analysis.getCreatedAt(), analysis.getUuid());
  133. }
  134. @Test
  135. public void ignore_unprocessed_snapshots() {
  136. OrganizationDto organization = dbTester.organizations().insert();
  137. ComponentDto project = dbTester.components().insertMainBranch(organization);
  138. SnapshotDto analysis1 = dbTester.components()
  139. .insertSnapshot(project, snapshot -> snapshot.setStatus(STATUS_UNPROCESSED).setCreatedAt(1226379600000L).setLast(false));// 2008-11-11
  140. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project,
  141. snapshot -> snapshot.setStatus(STATUS_PROCESSED).setProjectVersion("not provided").setCreatedAt(1226379600000L).setLast(false));// 2008-11-29
  142. dbTester.events().insertEvent(newEvent(analysis1).setName("not provided").setCategory(CATEGORY_VERSION).setDate(analysis1.getCreatedAt()));
  143. dbTester.events().insertEvent(newEvent(analysis2).setName("not provided").setCategory(CATEGORY_VERSION).setDate(analysis2.getCreatedAt()));
  144. when(analysisMetadataHolder.getAnalysisDate()).thenReturn(november30th2008.getTime());
  145. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  146. setupRoot(project);
  147. setupBranchWithNoManualBaseline(project);
  148. settings.setProperty("sonar.leak.period", "100");
  149. underTest.execute(new TestComputationStepContext());
  150. assertPeriod(LEAK_PERIOD_MODE_DAYS, "100", analysis2.getCreatedAt(), analysis2.getUuid());
  151. verifyDebugLogs("Resolving new code period by 100 days: 2008-08-22");
  152. }
  153. @Test
  154. public void feed_period_by_date() {
  155. OrganizationDto organization = dbTester.organizations().insert();
  156. ComponentDto project = dbTester.components().insertMainBranch(organization);
  157. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setLast(false)); // 2008-11-11
  158. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226494680000L).setLast(false)); // 2008-11-12
  159. SnapshotDto analysis3 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227157200000L).setLast(false)); // 2008-11-20
  160. SnapshotDto analysis4 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setLast(false)); // 2008-11-22
  161. SnapshotDto analysis5 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setLast(true)); // 2008-11-29
  162. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  163. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  164. setupRoot(project);
  165. setupBranchWithNoManualBaseline(project);
  166. String textDate = "2008-11-22";
  167. settings.setProperty("sonar.leak.period", textDate);
  168. underTest.execute(new TestComputationStepContext());
  169. // Return analysis from given date 2008-11-22
  170. assertPeriod(LEAK_PERIOD_MODE_DATE, textDate, analysis4.getCreatedAt(), analysis4.getUuid());
  171. verifyDebugLogs("Resolving new code period by date: 2008-11-22");
  172. }
  173. @Test
  174. @UseDataProvider("branchTypesNotAllowedToHaveManualBaseline")
  175. public void feed_period_by_date_and_ignore_baseline_when_not_eligible_for_manual(BranchType branchType) {
  176. OrganizationDto organization = dbTester.organizations().insert();
  177. ComponentDto project = dbTester.components().insertMainBranch(organization);
  178. ComponentDto branch = dbTester.components().insertProjectBranch(project, t -> t.setBranchType(branchType));
  179. SnapshotDto analysis1 = dbTester.components().insertSnapshot(branch, snapshot -> snapshot.setCreatedAt(1226379600000L).setLast(false)); // 2008-11-11
  180. SnapshotDto analysis2 = dbTester.components().insertSnapshot(branch, snapshot -> snapshot.setCreatedAt(1226494680000L).setLast(false)); // 2008-11-12
  181. SnapshotDto analysis3 = dbTester.components().insertSnapshot(branch, snapshot -> snapshot.setCreatedAt(1227157200000L).setLast(false)); // 2008-11-20
  182. SnapshotDto analysis4 = dbTester.components().insertSnapshot(branch, snapshot -> snapshot.setCreatedAt(1227358680000L).setLast(false)); // 2008-11-22
  183. SnapshotDto analysis5 = dbTester.components().insertSnapshot(branch, snapshot -> snapshot.setCreatedAt(1227934800000L).setLast(true)); // 2008-11-29
  184. dbTester.getDbClient().branchDao().updateManualBaseline(dbTester.getSession(), branch.uuid(), analysis1.getUuid());
  185. dbTester.commit();
  186. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  187. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  188. setBranchOf(branch);
  189. setupRoot(branch);
  190. String textDate = "2008-11-22";
  191. settings.setProperty("sonar.leak.period", textDate);
  192. underTest.execute(new TestComputationStepContext());
  193. // Return analysis from given date 2008-11-22
  194. assertPeriod(LEAK_PERIOD_MODE_DATE, textDate, analysis4.getCreatedAt(), analysis4.getUuid());
  195. verifyDebugLogs("Resolving new code period by date: 2008-11-22");
  196. }
  197. @DataProvider
  198. public static Object[][] branchTypesNotAllowedToHaveManualBaseline() {
  199. return new Object[][] {
  200. {BranchType.SHORT},
  201. {BranchType.PULL_REQUEST}
  202. };
  203. }
  204. @Test
  205. @UseDataProvider("anyValidLeakPeriodSettingValue")
  206. public void do_not_fail_when_project_has_no_BranchDto(String leakPeriodSettingValue) {
  207. OrganizationDto organization = dbTester.organizations().insert();
  208. // creates row in projects but not in project_branches
  209. ComponentDto project = dbTester.components().insertPrivateProject(organization);
  210. dbTester.components().insertSnapshot(project);
  211. SnapshotDto aVersionAnalysis = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setLast(false));// 2008-11-22
  212. dbTester.events().insertEvent(EventTesting.newEvent(aVersionAnalysis).setName("a_version").setCategory(CATEGORY_VERSION));
  213. dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setLast(true)); // 2008-11-29
  214. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  215. when(analysisMetadataHolder.getAnalysisDate()).thenReturn(november30th2008.getTime());
  216. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  217. setMetadataBranch(BranchType.LONG);
  218. setupRoot(project);
  219. settings.setProperty("sonar.leak.period", leakPeriodSettingValue);
  220. underTest.execute(new TestComputationStepContext());
  221. }
  222. @Test
  223. @UseDataProvider("anyValidLeakPeriodSettingValue")
  224. public void fail_with_ISE_when_manual_baseline_is_set_but_does_not_exist_in_DB(String leakPeriodSettingValue) {
  225. OrganizationDto organization = dbTester.organizations().insert();
  226. ComponentDto project = dbTester.components().insertMainBranch(organization);
  227. dbTester.components().setManualBaseline(project, new SnapshotDto().setUuid("nonexistent"));
  228. setBranchOf(project);
  229. setupRoot(project);
  230. expectedException.expect(IllegalStateException.class);
  231. expectedException.expectMessage("Analysis 'nonexistent' of project '" + project.uuid() + "' defined as manual baseline does not exist");
  232. settings.setProperty("sonar.leak.period", leakPeriodSettingValue);
  233. underTest.execute(new TestComputationStepContext());
  234. }
  235. @Test
  236. @UseDataProvider("anyValidLeakPeriodSettingValue")
  237. public void fail_with_ISE_when_manual_baseline_is_set_but_does_not_belong_to_current_project(String leakPeriodSettingValue) {
  238. OrganizationDto organization = dbTester.organizations().insert();
  239. ComponentDto project = dbTester.components().insertMainBranch(organization);
  240. ComponentDto otherProject = dbTester.components().insertMainBranch(organization);
  241. SnapshotDto otherProjectAnalysis = dbTester.components().insertSnapshot(otherProject);
  242. dbTester.components().setManualBaseline(project, otherProjectAnalysis);
  243. setBranchOf(project);
  244. setupRoot(project);
  245. expectedException.expect(IllegalStateException.class);
  246. expectedException.expectMessage("Analysis '" + otherProjectAnalysis.getUuid() + "' of project '" + project.uuid()
  247. + "' defined as manual baseline does not exist");
  248. settings.setProperty("sonar.leak.period", leakPeriodSettingValue);
  249. underTest.execute(new TestComputationStepContext());
  250. }
  251. @Test
  252. @UseDataProvider("anyValidLeakPeriodSettingValue")
  253. public void feed_period_by_manual_baseline_ignores_leak_period_setting(String leakPeriodSettingValue) {
  254. OrganizationDto organization = dbTester.organizations().insert();
  255. ComponentDto project = dbTester.components().insertMainBranch(organization);
  256. SnapshotDto manualBaselineAnalysis = dbTester.components().insertSnapshot(project);
  257. SnapshotDto aVersionAnalysis = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setLast(false));// 2008-11-22
  258. dbTester.events().insertEvent(EventTesting.newEvent(aVersionAnalysis).setName("a_version").setCategory(CATEGORY_VERSION));
  259. dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setLast(true)); // 2008-11-29
  260. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  261. when(analysisMetadataHolder.getAnalysisDate()).thenReturn(november30th2008.getTime());
  262. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  263. dbTester.components().setManualBaseline(project, manualBaselineAnalysis);
  264. setBranchOf(project);
  265. setupRoot(project);
  266. settings.setProperty("sonar.leak.period", leakPeriodSettingValue);
  267. underTest.execute(new TestComputationStepContext());
  268. assertPeriod(LEAK_PERIOD_MODE_MANUAL_BASELINE, null, manualBaselineAnalysis.getCreatedAt(), manualBaselineAnalysis.getUuid());
  269. verifyDebugLogs("Resolving new code period by manual baseline");
  270. }
  271. @Test
  272. @UseDataProvider("anyValidLeakPeriodSettingValue")
  273. public void feed_period_by_manual_baseline_on_long_living_branch(String leakPeriodSettingValue) {
  274. OrganizationDto organization = dbTester.organizations().insert();
  275. ComponentDto project = dbTester.components().insertMainBranch(organization);
  276. ComponentDto branch = dbTester.components().insertProjectBranch(project);
  277. SnapshotDto manualBaselineAnalysis = dbTester.components().insertSnapshot(branch);
  278. SnapshotDto aVersionAnalysis = dbTester.components().insertSnapshot(branch, snapshot -> snapshot.setCreatedAt(1227358680000L).setLast(false));// 2008-11-22
  279. dbTester.events().insertEvent(EventTesting.newEvent(aVersionAnalysis).setName("a_version").setCategory(CATEGORY_VERSION));
  280. dbTester.components().insertSnapshot(branch, snapshot -> snapshot.setCreatedAt(1227934800000L).setLast(true)); // 2008-11-29
  281. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  282. when(analysisMetadataHolder.getAnalysisDate()).thenReturn(november30th2008.getTime());
  283. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  284. dbTester.components().setManualBaseline(branch, manualBaselineAnalysis);
  285. setBranchOf(branch);
  286. setupRoot(branch);
  287. settings.setProperty("sonar.leak.period", leakPeriodSettingValue);
  288. underTest.execute(new TestComputationStepContext());
  289. assertPeriod(LEAK_PERIOD_MODE_MANUAL_BASELINE, null, manualBaselineAnalysis.getCreatedAt(), manualBaselineAnalysis.getUuid());
  290. verifyDebugLogs("Resolving new code period by manual baseline");
  291. }
  292. @DataProvider
  293. public static Object[][] anyValidLeakPeriodSettingValue() {
  294. return new Object[][] {
  295. // days
  296. {"100"},
  297. // date
  298. {"2008-11-22"},
  299. // previous_version keyword
  300. {"previous_version"},
  301. // an existing version event value
  302. {"a_version"},
  303. };
  304. }
  305. @Test
  306. public void feed_period_parameter_as_null_when_manual_baseline_has_no_version() {
  307. OrganizationDto organization = dbTester.organizations().insert();
  308. ComponentDto project = dbTester.components().insertMainBranch(organization);
  309. SnapshotDto manualBaselineAnalysis = dbTester.components().insertSnapshot(project);
  310. dbTester.components().setManualBaseline(project, manualBaselineAnalysis);
  311. setBranchOf(project);
  312. setupRoot(project);
  313. settings.setProperty("sonar.leak.period", "ignored");
  314. underTest.execute(new TestComputationStepContext());
  315. assertPeriod(LEAK_PERIOD_MODE_MANUAL_BASELINE, null, manualBaselineAnalysis.getCreatedAt(), manualBaselineAnalysis.getUuid());
  316. }
  317. @Test
  318. public void feed_period_parameter_as_null_when_manual_baseline_has_same_project_version() {
  319. String version = randomAlphabetic(12);
  320. OrganizationDto organization = dbTester.organizations().insert();
  321. ComponentDto project = dbTester.components().insertMainBranch(organization);
  322. SnapshotDto manualBaselineAnalysis = dbTester.components().insertSnapshot(project, t -> t.setProjectVersion(version).setProjectVersion(version));
  323. dbTester.components().setManualBaseline(project, manualBaselineAnalysis);
  324. setBranchOf(project);
  325. setupRoot(project);
  326. settings.setProperty("sonar.leak.period", "ignored");
  327. underTest.execute(new TestComputationStepContext());
  328. assertPeriod(LEAK_PERIOD_MODE_MANUAL_BASELINE, null, manualBaselineAnalysis.getCreatedAt(), manualBaselineAnalysis.getUuid());
  329. }
  330. @Test
  331. public void feed_no_period_parameter_as_projectVersion_when_manual_baseline_has_project_version() {
  332. String projectVersion = randomAlphabetic(15);
  333. OrganizationDto organization = dbTester.organizations().insert();
  334. ComponentDto project = dbTester.components().insertMainBranch(organization);
  335. SnapshotDto manualBaselineAnalysis = dbTester.components().insertSnapshot(project, t -> t.setProjectVersion(projectVersion));
  336. dbTester.components().setManualBaseline(project, manualBaselineAnalysis);
  337. setBranchOf(project);
  338. setupRoot(project);
  339. settings.setProperty("sonar.leak.period", "ignored");
  340. underTest.execute(new TestComputationStepContext());
  341. assertPeriod(LEAK_PERIOD_MODE_MANUAL_BASELINE, null, manualBaselineAnalysis.getCreatedAt(), manualBaselineAnalysis.getUuid());
  342. }
  343. @Test
  344. @UseDataProvider("projectVersionNullOrNot")
  345. public void feed_no_period_parameter_as_version_event_version_when_manual_baseline_has_one(@Nullable String projectVersion) {
  346. String eventVersion = randomAlphabetic(15);
  347. OrganizationDto organization = dbTester.organizations().insert();
  348. ComponentDto project = dbTester.components().insertMainBranch(organization);
  349. SnapshotDto manualBaselineAnalysis = dbTester.components().insertSnapshot(project, t -> t.setProjectVersion(projectVersion));
  350. dbTester.events().insertEvent(EventTesting.newEvent(manualBaselineAnalysis).setCategory(CATEGORY_VERSION).setName(eventVersion));
  351. dbTester.components().setManualBaseline(project, manualBaselineAnalysis);
  352. setBranchOf(project);
  353. setupRoot(project);
  354. settings.setProperty("sonar.leak.period", "ignored");
  355. underTest.execute(new TestComputationStepContext());
  356. assertPeriod(LEAK_PERIOD_MODE_MANUAL_BASELINE, null, manualBaselineAnalysis.getCreatedAt(), manualBaselineAnalysis.getUuid());
  357. }
  358. @DataProvider
  359. public static Object[][] projectVersionNullOrNot() {
  360. return new Object[][] {
  361. {null},
  362. {randomAlphabetic(15)},
  363. };
  364. }
  365. private Branch setBranchOf(ComponentDto project) {
  366. BranchDto branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), project.uuid()).get();
  367. return setMetadataBranch(branchDto.getBranchType());
  368. }
  369. private Branch setMetadataBranch(BranchType branchType) {
  370. Branch branch = mock(Branch.class, invoc -> {
  371. throw new UnsupportedOperationException();
  372. });
  373. doReturn(branchType).when(branch).getType();
  374. when(analysisMetadataHolder.getBranch()).thenReturn(branch);
  375. return branch;
  376. }
  377. @Test
  378. public void search_by_date_return_nearest_later_analysis() {
  379. OrganizationDto organization = dbTester.organizations().insert();
  380. ComponentDto project = dbTester.components().insertMainBranch(organization);
  381. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setLast(false)); // 2008-11-11
  382. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226494680000L).setLast(false)); // 2008-11-12
  383. SnapshotDto analysis3 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227157200000L).setLast(false)); // 2008-11-20
  384. SnapshotDto analysis4 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setLast(false)); // 2008-11-22
  385. SnapshotDto analysis5 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setLast(true)); // 2008-11-29
  386. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  387. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  388. setupRoot(project);
  389. setupBranchWithNoManualBaseline(project);
  390. String date = "2008-11-13";
  391. settings.setProperty("sonar.leak.period", date);
  392. underTest.execute(new TestComputationStepContext());
  393. // Analysis form 2008-11-20
  394. assertPeriod(LEAK_PERIOD_MODE_DATE, date, analysis3.getCreatedAt(), analysis3.getUuid());
  395. verifyDebugLogs("Resolving new code period by date: 2008-11-13");
  396. }
  397. @Test
  398. public void fail_with_MessageException_if_period_is_date_after_today() {
  399. OrganizationDto organization = dbTester.organizations().insert();
  400. ComponentDto project = dbTester.components().insertMainBranch(organization);
  401. dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L)); // 2008-11-29
  402. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  403. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  404. setupRoot(project);
  405. setupBranchWithNoManualBaseline(project);
  406. String propertyValue = "2008-12-01";
  407. settings.setProperty("sonar.leak.period", propertyValue);
  408. verifyFailWithInvalidValueMessageException(propertyValue,
  409. "Invalid code period '2008-12-01': date is in the future (now: '2008-11-30')");
  410. }
  411. @Test
  412. public void fail_with_MessageException_if_date_does_not_exist() {
  413. OrganizationDto organization = dbTester.organizations().insert();
  414. ComponentDto project = dbTester.components().insertMainBranch(organization);
  415. dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L)); // 2008-11-29
  416. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  417. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  418. setupRoot(project);
  419. setupBranchWithNoManualBaseline(project);
  420. String propertyValue = "2008-11-31";
  421. settings.setProperty("sonar.leak.period", propertyValue);
  422. verifyFailWithInvalidValueMessageException(propertyValue,
  423. "Invalid code period '2008-11-31': Invalid date");
  424. }
  425. @Test
  426. public void fail_with_MessageException_if_period_is_today_but_no_analysis_today() {
  427. OrganizationDto organization = dbTester.organizations().insert();
  428. ComponentDto project = dbTester.components().insertMainBranch(organization);
  429. dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L)); // 2008-11-29
  430. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  431. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  432. setupRoot(project);
  433. setupBranchWithNoManualBaseline(project);
  434. String propertyValue = "2008-11-30";
  435. settings.setProperty("sonar.leak.period", propertyValue);
  436. verifyFailWithInvalidValueMessageException(propertyValue,
  437. "Resolving new code period by date: 2008-11-30",
  438. "Invalid code period '2008-11-30': No analysis found created after date '2008-11-30'");
  439. }
  440. @Test
  441. @UseDataProvider("zeroOrLess")
  442. public void fail_with_MessageException_if_period_is_0_or_less(int zeroOrLess) {
  443. OrganizationDto organization = dbTester.organizations().insert();
  444. ComponentDto project = dbTester.components().insertMainBranch(organization);
  445. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  446. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  447. setupRoot(project);
  448. setupBranchWithNoManualBaseline(project);
  449. String propertyValue = String.valueOf(zeroOrLess);
  450. settings.setProperty("sonar.leak.period", propertyValue);
  451. verifyFailWithInvalidValueMessageException(propertyValue,
  452. "Invalid code period '" + zeroOrLess + "': number of days is <= 0");
  453. }
  454. @DataProvider
  455. public static Object[][] zeroOrLess() {
  456. return new Object[][] {
  457. {0},
  458. {-1 - new Random().nextInt(30)}
  459. };
  460. }
  461. @Test
  462. public void fail_with_ISE_if_not_firstAnalysis_but_no_snapshot_in_DB() {
  463. OrganizationDto organization = dbTester.organizations().insert();
  464. ComponentDto project = dbTester.components().insertMainBranch(organization);
  465. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  466. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  467. setupRoot(project);
  468. setupBranchWithNoManualBaseline(project);
  469. settings.setProperty("sonar.leak.period", "previous_version");
  470. expectedException.expect(IllegalStateException.class);
  471. expectedException.expectMessage("Attempting to resolve period while no analysis exist");
  472. underTest.execute(new TestComputationStepContext());
  473. }
  474. @Test
  475. @UseDataProvider("stringConsideredAsVersions")
  476. public void fail_with_MessageException_if_string_is_not_an_existing_version_event(String propertyValue) {
  477. OrganizationDto organization = dbTester.organizations().insert();
  478. ComponentDto project = dbTester.components().insertMainBranch(organization);
  479. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setProjectVersion("0.9").setLast(false)); // 2008-11-11
  480. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226494680000L).setProjectVersion("1.0").setLast(false)); // 2008-11-12
  481. SnapshotDto analysis3 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227157200000L).setProjectVersion("1.1").setLast(false)); // 2008-11-20
  482. SnapshotDto analysis4 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setProjectVersion("1.1").setLast(false)); // 2008-11-22
  483. SnapshotDto analysis5 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setProjectVersion("1.1").setLast(true)); // 2008-11-29
  484. dbTester.events().insertEvent(newEvent(analysis1).setName("0.9").setCategory(CATEGORY_VERSION).setDate(analysis1.getCreatedAt()));
  485. dbTester.events().insertEvent(newEvent(analysis2).setName("1.0").setCategory(CATEGORY_VERSION).setDate(analysis2.getCreatedAt()));
  486. dbTester.events().insertEvent(newEvent(analysis5).setName("1.1").setCategory(CATEGORY_VERSION).setDate(analysis4.getCreatedAt()));
  487. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  488. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  489. setupRoot(project);
  490. setupBranchWithNoManualBaseline(project);
  491. settings.setProperty("sonar.leak.period", propertyValue);
  492. try {
  493. underTest.execute(new TestComputationStepContext());
  494. fail("a Message Exception should have been thrown");
  495. } catch (MessageException e) {
  496. verifyInvalidValueMessage(e, propertyValue);
  497. assertThat(logTester.getLogs()).hasSize(2);
  498. assertThat(logTester.getLogs(LoggerLevel.DEBUG))
  499. .hasSize(2)
  500. .extracting(LogAndArguments::getFormattedMsg)
  501. .contains("Invalid code period '" + propertyValue + "': version is none of the existing ones: [1.1, 1.0, 0.9]");
  502. }
  503. }
  504. @DataProvider
  505. public static Object[][] stringConsideredAsVersions() {
  506. return new Object[][] {
  507. {randomAlphabetic(5)},
  508. {"1,3"},
  509. {"1.3"},
  510. {"0 1"},
  511. {"1-SNAPSHOT"},
  512. {"01-12-2018"}, // unsupported date format
  513. };
  514. }
  515. @Test
  516. public void fail_with_MessageException_if_property_does_not_exist() {
  517. OrganizationDto organization = dbTester.organizations().insert();
  518. ComponentDto project = dbTester.components().insertMainBranch(organization);
  519. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  520. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  521. setupRoot(project);
  522. verifyFailWithInvalidValueMessageException("", "Invalid code period '': property is undefined or value is empty");
  523. }
  524. @Test
  525. public void fail_with_MessageException_if_property_is_empty() {
  526. OrganizationDto organization = dbTester.organizations().insert();
  527. ComponentDto project = dbTester.components().insertMainBranch(organization);
  528. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  529. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  530. setupRoot(project);
  531. String propertyValue = "";
  532. settings.setProperty("sonar.leak.period", propertyValue);
  533. verifyFailWithInvalidValueMessageException(propertyValue, "Invalid code period '': property is undefined or value is empty");
  534. }
  535. private void verifyFailWithInvalidValueMessageException(String propertyValue, String debugLog, String... otherDebugLogs) {
  536. try {
  537. underTest.execute(new TestComputationStepContext());
  538. fail("a Message Exception should have been thrown");
  539. } catch (MessageException e) {
  540. verifyInvalidValueMessage(e, propertyValue);
  541. verifyDebugLogs(debugLog, otherDebugLogs);
  542. }
  543. }
  544. @Test
  545. public void feed_period_by_days() {
  546. OrganizationDto organization = dbTester.organizations().insert();
  547. ComponentDto project = dbTester.components().insertMainBranch(organization);
  548. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setLast(false)); // 2008-11-11
  549. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226494680000L).setLast(false)); // 2008-11-12
  550. SnapshotDto analysis3 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227157200000L).setLast(false)); // 2008-11-20
  551. SnapshotDto analysis4 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setLast(false)); // 2008-11-22
  552. SnapshotDto analysis5 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setLast(true)); // 2008-11-29
  553. when(analysisMetadataHolder.getAnalysisDate()).thenReturn(november30th2008.getTime());
  554. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  555. setupRoot(project);
  556. setupBranchWithNoManualBaseline(project);
  557. settings.setProperty("sonar.leak.period", "10");
  558. underTest.execute(new TestComputationStepContext());
  559. // return analysis from 2008-11-20
  560. assertPeriod(LEAK_PERIOD_MODE_DAYS, "10", analysis3.getCreatedAt(), analysis3.getUuid());
  561. assertThat(logTester.getLogs()).hasSize(1);
  562. assertThat(logTester.getLogs(LoggerLevel.DEBUG))
  563. .extracting(LogAndArguments::getFormattedMsg)
  564. .containsOnly("Resolving new code period by 10 days: 2008-11-20");
  565. }
  566. @Test
  567. public void feed_period_by_previous_version() {
  568. OrganizationDto organization = dbTester.organizations().insert();
  569. ComponentDto project = dbTester.components().insertMainBranch(organization);
  570. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setProjectVersion("0.9").setLast(false)); // 2008-11-11
  571. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226494680000L).setProjectVersion("1.0").setLast(false)); // 2008-11-12
  572. SnapshotDto analysis3 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227157200000L).setProjectVersion("1.1").setLast(false)); // 2008-11-20
  573. SnapshotDto analysis4 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setProjectVersion("1.1").setLast(false)); // 2008-11-22
  574. SnapshotDto analysis5 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setProjectVersion("1.1").setLast(true)); // 2008-11-29
  575. dbTester.events().insertEvent(newEvent(analysis1).setName("0.9").setCategory(CATEGORY_VERSION).setDate(analysis1.getCreatedAt()));
  576. dbTester.events().insertEvent(newEvent(analysis2).setName("1.0").setCategory(CATEGORY_VERSION).setDate(analysis2.getCreatedAt()));
  577. dbTester.events().insertEvent(newEvent(analysis5).setName("1.1").setCategory(CATEGORY_VERSION).setDate(analysis4.getCreatedAt()));
  578. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  579. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  580. setupRoot(project, "1.1");
  581. setupBranchWithNoManualBaseline(project);
  582. settings.setProperty("sonar.leak.period", "previous_version");
  583. underTest.execute(new TestComputationStepContext());
  584. // Analysis form 2008-11-12
  585. assertPeriod(LEAK_PERIOD_MODE_PREVIOUS_VERSION, "1.0", analysis2.getCreatedAt(), analysis2.getUuid());
  586. verifyDebugLogs("Resolving new code period by previous version: 1.0");
  587. }
  588. @Test
  589. public void feed_period_by_previous_version_with_previous_version_deleted() {
  590. OrganizationDto organization = dbTester.organizations().insert();
  591. ComponentDto project = dbTester.components().insertMainBranch(organization);
  592. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setProjectVersion("0.9").setLast(false)); // 2008-11-11
  593. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226494680000L).setProjectVersion("1.0").setLast(false)); // 2008-11-12
  594. SnapshotDto analysis3 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227157200000L).setProjectVersion("1.1").setLast(false)); // 2008-11-20
  595. dbTester.events().insertEvent(newEvent(analysis1).setName("0.9").setCategory(CATEGORY_VERSION));
  596. // The "1.0" version was deleted from the history
  597. dbTester.events().insertEvent(newEvent(analysis3).setName("1.1").setCategory(CATEGORY_VERSION));
  598. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  599. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  600. setupRoot(project, "1.1");
  601. setupBranchWithNoManualBaseline(project);
  602. settings.setProperty("sonar.leak.period", "previous_version");
  603. underTest.execute(new TestComputationStepContext());
  604. // Analysis form 2008-11-11
  605. assertPeriod(LEAK_PERIOD_MODE_PREVIOUS_VERSION, "0.9", analysis1.getCreatedAt(), analysis1.getUuid());
  606. }
  607. @Test
  608. public void feed_period_by_previous_version_with_first_analysis_when_no_previous_version_found() {
  609. OrganizationDto organization = dbTester.organizations().insert();
  610. ComponentDto project = dbTester.components().insertMainBranch(organization);
  611. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setProjectVersion("1.1").setLast(false)); // 2008-11-11
  612. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setProjectVersion("1.1").setLast(true)); // 2008-11-29
  613. dbTester.events().insertEvent(newEvent(analysis2).setName("1.1").setCategory(CATEGORY_VERSION));
  614. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  615. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  616. setupRoot(project, "1.1");
  617. setupBranchWithNoManualBaseline(project);
  618. settings.setProperty("sonar.leak.period", "previous_version");
  619. underTest.execute(new TestComputationStepContext());
  620. assertPeriod(LEAK_PERIOD_MODE_PREVIOUS_VERSION, null, analysis1.getCreatedAt(), analysis1.getUuid());
  621. verifyDebugLogs("Resolving first analysis as new code period as there is only one existing version");
  622. }
  623. @Test
  624. public void feed_period_by_previous_version_with_first_analysis_when_previous_snapshot_is_the_last_one() {
  625. OrganizationDto organization = dbTester.organizations().insert();
  626. ComponentDto project = dbTester.components().insertMainBranch(organization);
  627. SnapshotDto analysis = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setProjectVersion("0.9").setLast(true)); // 2008-11-11
  628. dbTester.events().insertEvent(newEvent(analysis).setName("0.9").setCategory(CATEGORY_VERSION));
  629. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  630. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  631. setupRoot(project, "1.1");
  632. setupBranchWithNoManualBaseline(project);
  633. settings.setProperty("sonar.leak.period", "previous_version");
  634. underTest.execute(new TestComputationStepContext());
  635. assertPeriod(LEAK_PERIOD_MODE_PREVIOUS_VERSION, null, analysis.getCreatedAt(), analysis.getUuid());
  636. verifyDebugLogs("Resolving first analysis as new code period as there is only one existing version");
  637. }
  638. @Test
  639. public void feed_period_by_version() {
  640. OrganizationDto organization = dbTester.organizations().insert();
  641. ComponentDto project = dbTester.components().insertMainBranch(organization);
  642. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setProjectVersion("0.9").setLast(false)); // 2008-11-11
  643. SnapshotDto analysis2 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226494680000L).setProjectVersion("1.0").setLast(false)); // 2008-11-12
  644. SnapshotDto analysis3 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227157200000L).setProjectVersion("1.1").setLast(false)); // 2008-11-20
  645. SnapshotDto analysis4 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227358680000L).setProjectVersion("1.1").setLast(false)); // 2008-11-22
  646. SnapshotDto analysis5 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1227934800000L).setProjectVersion("1.1").setLast(true)); // 2008-11-29
  647. dbTester.events().insertEvent(newEvent(analysis1).setName("0.9").setCategory(CATEGORY_VERSION));
  648. dbTester.events().insertEvent(newEvent(analysis2).setName("1.0").setCategory(CATEGORY_VERSION));
  649. dbTester.events().insertEvent(newEvent(analysis5).setName("1.1").setCategory(CATEGORY_VERSION));
  650. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  651. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  652. setupRoot(project, "1.1");
  653. setupBranchWithNoManualBaseline(project);
  654. settings.setProperty("sonar.leak.period", "1.0");
  655. underTest.execute(new TestComputationStepContext());
  656. // Analysis form 2008-11-11
  657. assertPeriod(LEAK_PERIOD_MODE_VERSION, "1.0", analysis2.getCreatedAt(), analysis2.getUuid());
  658. verifyDebugLogs("Resolving new code period by version: 1.0");
  659. }
  660. /**
  661. * SONAR-11492
  662. */
  663. @Test
  664. public void feed_period_by_version_with_only_one_existing_version() {
  665. OrganizationDto organization = dbTester.organizations().insert();
  666. ComponentDto project = dbTester.components().insertMainBranch(organization);
  667. SnapshotDto analysis1 = dbTester.components().insertSnapshot(project, snapshot -> snapshot.setCreatedAt(1226379600000L).setProjectVersion("0.9").setLast(true)); // 2008-11-11
  668. dbTester.events().insertEvent(newEvent(analysis1).setName("0.9").setCategory(CATEGORY_VERSION));
  669. when(system2Mock.now()).thenReturn(november30th2008.getTime());
  670. when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
  671. setupRoot(project, "0.9");
  672. setupBranchWithNoManualBaseline(project);
  673. settings.setProperty("sonar.leak.period", "0.9");
  674. underTest.execute(new TestComputationStepContext());
  675. // Analysis form 2008-11-11
  676. assertPeriod(LEAK_PERIOD_MODE_VERSION, "0.9", analysis1.getCreatedAt(), analysis1.getUuid());
  677. verifyDebugLogs("Resolving new code period by version: 0.9");
  678. }
  679. @Test
  680. @UseDataProvider("anyValidLeakPeriodSettingValue")
  681. public void leak_period_setting_is_ignored_for_SLB_or_PR(String leakPeriodSettingValue) {
  682. when(analysisMetadataHolder.isLongLivingBranch()).thenReturn(false);
  683. settings.setProperty("sonar.leak.period", leakPeriodSettingValue);
  684. underTest.execute(new TestComputationStepContext());
  685. assertThat(periodsHolder.hasPeriod()).isFalse();
  686. }
  687. private void assertPeriod(String mode, @Nullable String modeParameter, long snapshotDate, String analysisUuid) {
  688. Period period = periodsHolder.getPeriod();
  689. assertThat(period).isNotNull();
  690. assertThat(period.getMode()).isEqualTo(mode);
  691. assertThat(period.getModeParameter()).isEqualTo(modeParameter);
  692. assertThat(period.getSnapshotDate()).isEqualTo(snapshotDate);
  693. assertThat(period.getAnalysisUuid()).isEqualTo(analysisUuid);
  694. }
  695. private void verifyDebugLogs(String log, String... otherLogs) {
  696. assertThat(logTester.getLogs()).hasSize(1 + otherLogs.length);
  697. assertThat(logTester.getLogs(LoggerLevel.DEBUG))
  698. .extracting(LogAndArguments::getFormattedMsg)
  699. .containsOnly(Stream.concat(Stream.of(log), Arrays.stream(otherLogs)).toArray(String[]::new));
  700. }
  701. private void setupRoot(ComponentDto project) {
  702. setupRoot(project, randomAlphanumeric(3));
  703. }
  704. private void setupRoot(ComponentDto project, String version) {
  705. treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, 1).setUuid(project.uuid()).setKey(project.getKey()).setProjectVersion(version).build());
  706. when(configurationRepository.getConfiguration()).thenReturn(settings.asConfig());
  707. }
  708. private void setupBranchWithNoManualBaseline(ComponentDto projectOrLongBranch) {
  709. dbTester.components().unsetManualBaseline(projectOrLongBranch);
  710. setBranchOf(projectOrLongBranch);
  711. }
  712. private static void verifyInvalidValueMessage(MessageException e, String propertyValue) {
  713. assertThat(e).hasMessage("Invalid new code period. '" + propertyValue
  714. + "' is not one of: integer > 0, date before current analysis j, \"previous_version\", or version string that exists in the project' \n" +
  715. "Please contact a project administrator to correct this setting");
  716. }
  717. }