From: Julien Lancelot Date: Wed, 28 Oct 2015 09:37:18 +0000 (+0100) Subject: Move measure history ITs X-Git-Tag: 5.3-RC1~430 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cf645d53f903ebfa6a6c36001a59636a28b8e389;p=sonarqube.git Move measure history ITs --- diff --git a/it/it-projects/shared/xoo-history-v1/sonar-project.properties b/it/it-projects/shared/xoo-history-v1/sonar-project.properties index e01f062e51b..ede32ccb043 100644 --- a/it/it-projects/shared/xoo-history-v1/sonar-project.properties +++ b/it/it-projects/shared/xoo-history-v1/sonar-project.properties @@ -1,5 +1,5 @@ sonar.projectKey=sample sonar.projectName=Sample -sonar.projectVersion=1.0-SNAPSHOT +sonar.projectVersion=0.9-SNAPSHOT sonar.sources=src/main/xoo sonar.language=xoo \ No newline at end of file diff --git a/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/ClassToModify.xoo.measures b/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/ClassToModify.xoo.measures index 7812e4167fb..0861ac725c3 100644 --- a/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/ClassToModify.xoo.measures +++ b/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/ClassToModify.xoo.measures @@ -1,2 +1,4 @@ ncloc:12 classes:1 +complexity:3 +complexity_in_classes:3 diff --git a/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/UnchangedClass.xoo.measures b/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/UnchangedClass.xoo.measures index 7812e4167fb..0861ac725c3 100644 --- a/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/UnchangedClass.xoo.measures +++ b/it/it-projects/shared/xoo-history-v1/src/main/xoo/sample/UnchangedClass.xoo.measures @@ -1,2 +1,4 @@ ncloc:12 classes:1 +complexity:3 +complexity_in_classes:3 diff --git a/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassAdded.xoo.measures b/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassAdded.xoo.measures index 66ba834e1ef..0861ac725c3 100644 --- a/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassAdded.xoo.measures +++ b/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassAdded.xoo.measures @@ -1,3 +1,4 @@ ncloc:12 classes:1 - +complexity:3 +complexity_in_classes:3 diff --git a/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassToModify.xoo.measures b/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassToModify.xoo.measures index 71d60758637..5de11af72ed 100644 --- a/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassToModify.xoo.measures +++ b/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/ClassToModify.xoo.measures @@ -1,3 +1,4 @@ ncloc:16 classes:1 - +complexity:5 +complexity_in_classes:4 diff --git a/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/UnchangedClass.xoo.measures b/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/UnchangedClass.xoo.measures index 7812e4167fb..0861ac725c3 100644 --- a/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/UnchangedClass.xoo.measures +++ b/it/it-projects/shared/xoo-history-v2/src/main/xoo/sample/UnchangedClass.xoo.measures @@ -1,2 +1,4 @@ ncloc:12 classes:1 +complexity:3 +complexity_in_classes:3 diff --git a/it/it-tests/src/test/java/it/Category1Suite.java b/it/it-tests/src/test/java/it/Category1Suite.java index 4414e82ea04..8c4aca7b0ba 100644 --- a/it/it-tests/src/test/java/it/Category1Suite.java +++ b/it/it-tests/src/test/java/it/Category1Suite.java @@ -41,6 +41,12 @@ package it;/* import com.sonar.orchestrator.Orchestrator; import it.authorisation.IssuePermissionTest; import it.i18n.I18nTest; +import it.measureHistory.DifferentialPeriodsTest; +import it.measureHistory.HistoryUiTest; +import it.measureHistory.SincePreviousVersionHistoryTest; +import it.measureHistory.SinceXDaysHistoryTest; +import it.measureHistory.TimeMachineTest; +import it.measureHistory.TimeMachineUiTest; import it.projectAdministration.BulkDeletionTest; import it.projectAdministration.ProjectAdministrationTest; import it.qualityGate.QualityGateNotificationTest; @@ -72,7 +78,14 @@ import static util.ItUtils.xooPlugin; QualityGateTest.class, QualityGateNotificationTest.class, // permission - IssuePermissionTest.class + IssuePermissionTest.class, + // measure history + DifferentialPeriodsTest.class, + HistoryUiTest.class, + SincePreviousVersionHistoryTest.class, + SinceXDaysHistoryTest.class, + TimeMachineTest.class, + TimeMachineUiTest.class }) public class Category1Suite { diff --git a/it/it-tests/src/test/java/it/Category2Suite.java b/it/it-tests/src/test/java/it/Category2Suite.java index 27cd9dd6b22..1e33a5fd860 100644 --- a/it/it-tests/src/test/java/it/Category2Suite.java +++ b/it/it-tests/src/test/java/it/Category2Suite.java @@ -52,8 +52,6 @@ import it.issue.ManualRulesTest; import it.measureFilter.MeasureFiltersTest; import it.measure.NewDebtRatioMeasureTest; import it.measure.TechnicalDebtMeasureVariationTest; -import it.measureHistory.DifferentialPeriodsTest; -import it.measureHistory.TimeMachineTest; import it.test.CoverageTest; import it.test.CoverageTrackingTest; import it.test.NewCoverageTest; @@ -69,9 +67,6 @@ import static util.ItUtils.xooPlugin; @Suite.SuiteClasses({ // custom measure CustomMeasuresTest.class, - // measure history - DifferentialPeriodsTest.class, - TimeMachineTest.class, // measure TechnicalDebtMeasureVariationTest.class, NewDebtRatioMeasureTest.class, diff --git a/it/it-tests/src/test/java/it/measure/NewDebtRatioMeasureTest.java b/it/it-tests/src/test/java/it/measure/NewDebtRatioMeasureTest.java index 2761bf490d3..ded142af5f1 100644 --- a/it/it-tests/src/test/java/it/measure/NewDebtRatioMeasureTest.java +++ b/it/it-tests/src/test/java/it/measure/NewDebtRatioMeasureTest.java @@ -5,7 +5,9 @@ import com.sonar.orchestrator.locator.FileLocation; import it.Category2Suite; import java.util.List; import javax.annotation.Nullable; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.sonar.wsclient.services.Measure; @@ -15,6 +17,7 @@ import util.ItUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.within; +import static util.ItUtils.setServerProperty; /** * SONAR-5876 @@ -26,6 +29,18 @@ public class NewDebtRatioMeasureTest { @ClassRule public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; + @BeforeClass + public static void initPeriods() throws Exception { + setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); + setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); + } + + @AfterClass + public static void resetPeriods() throws Exception { + ItUtils.resetPeriods(orchestrator); + } + @Before public void cleanUpAnalysisData() { orchestrator.resetData(); diff --git a/it/it-tests/src/test/java/it/measure/TechnicalDebtMeasureVariationTest.java b/it/it-tests/src/test/java/it/measure/TechnicalDebtMeasureVariationTest.java index b115f076866..63b929bb514 100644 --- a/it/it-tests/src/test/java/it/measure/TechnicalDebtMeasureVariationTest.java +++ b/it/it-tests/src/test/java/it/measure/TechnicalDebtMeasureVariationTest.java @@ -4,7 +4,9 @@ import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.locator.FileLocation; import it.Category2Suite; import java.util.List; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.sonar.wsclient.services.Measure; @@ -13,6 +15,7 @@ import org.sonar.wsclient.services.ResourceQuery; import util.ItUtils; import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.setServerProperty; /** * SONAR-4776 @@ -22,6 +25,18 @@ public class TechnicalDebtMeasureVariationTest { @ClassRule public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; + @BeforeClass + public static void initPeriods() throws Exception { + setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); + setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_analysis"); + } + + @AfterClass + public static void resetPeriods() throws Exception { + ItUtils.resetPeriods(orchestrator); + } + @Before public void cleanUpAnalysisData() { orchestrator.resetData(); diff --git a/it/it-tests/src/test/java/it/measureHistory/DifferentialPeriodsTest.java b/it/it-tests/src/test/java/it/measureHistory/DifferentialPeriodsTest.java index f4a194fed92..c1e9606ab4e 100644 --- a/it/it-tests/src/test/java/it/measureHistory/DifferentialPeriodsTest.java +++ b/it/it-tests/src/test/java/it/measureHistory/DifferentialPeriodsTest.java @@ -3,7 +3,8 @@ package it.measureHistory; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarRunner; import com.sonar.orchestrator.locator.FileLocation; -import it.Category2Suite; +import com.sonar.orchestrator.selenium.Selenese; +import it.Category1Suite; import java.util.List; import org.junit.After; import org.junit.Before; @@ -15,22 +16,29 @@ import org.sonar.wsclient.services.ResourceQuery; import util.ItUtils; import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.projectDir; +import static util.ItUtils.setServerProperty; public class DifferentialPeriodsTest { @ClassRule - public static final Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; + public static final Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; @Before public void cleanUpAnalysisData() { orchestrator.resetData(); } + @Before + public void initPeriods() throws Exception { + setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period2", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_analysis"); + } + @After - public void tearDown() throws Exception { - String propertyKey = "sonar.timemachine.period4"; - unsetProperty(propertyKey); - unsetProperty("sonar.timemachine.period5"); + public void resetPeriods() throws Exception { + ItUtils.resetPeriods(orchestrator); } /** @@ -38,19 +46,19 @@ public class DifferentialPeriodsTest { */ @Test public void ensure_differential_period_4_and_5_defined_at_project_level_is_taken_into_account() throws Exception { - setProperty("sonar.timemachine.period4", "30"); - setProperty("sonar.timemachine.period5", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period4", "30"); + setServerProperty(orchestrator, "sonar.timemachine.period5", "previous_analysis"); // Execute an analysis in the past to have a past snapshot without any issues orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty"); - orchestrator.executeBuild(SonarRunner.create(ItUtils.projectDir("shared/xoo-sample")) + orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample")) .setProperty("sonar.projectDate", "2013-01-01")); // Second analysis -> issues will be created orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); - orchestrator.executeBuild(SonarRunner.create(ItUtils.projectDir("shared/xoo-sample"))); + orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); // New technical debt only comes from new issues Resource newTechnicalDebt = orchestrator.getServer().getWsClient() @@ -61,7 +69,7 @@ public class DifferentialPeriodsTest { // Third analysis, with exactly the same profile -> no new issues so no new technical debt orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); - orchestrator.executeBuild(SonarRunner.create(ItUtils.projectDir("shared/xoo-sample"))); + orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); newTechnicalDebt = orchestrator.getServer().getWsClient().find( ResourceQuery.createForMetrics("sample:src/main/xoo/sample/Sample.xoo", "new_technical_debt").setIncludeTrends(true) @@ -71,16 +79,25 @@ public class DifferentialPeriodsTest { assertThat(newTechnicalDebt).isNull(); } - private static void unsetProperty(String propertyKey) { - setProperty(propertyKey, ""); - } + /** + * SONAR-4700 + */ + @Test + public void not_display_periods_selection_dropdown_on_first_analysis() { + orchestrator.getServer().provisionProject("sample", "sample"); + orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty"); + orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); - private static void setProperty(String propertyKey, String propertyValue) { - orchestrator.getServer().adminWsClient().post( - "/api/properties?", - "id", propertyKey, - "value", propertyValue - ); + // Use old way to execute Selenium because 'assertSelectOptions' action is not supported by SeleneseTest + orchestrator.executeSelenese(Selenese.builder().setHtmlTestsInClasspath("not-display-periods-selection-dropdown-on-first-analysis", + "/measureHistory/DifferentialPeriodsTest/not-display-periods-selection-dropdown-on-dashboard.html" + ).build()); + + orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); + + orchestrator.executeSelenese(Selenese.builder().setHtmlTestsInClasspath("display-periods-selection-dropdown-after-first-analysis", + "/measureHistory/DifferentialPeriodsTest/display-periods-selection-dropdown-on-dashboard.html" + ).build()); } } diff --git a/it/it-tests/src/test/java/it/measureHistory/HistoryUiTest.java b/it/it-tests/src/test/java/it/measureHistory/HistoryUiTest.java new file mode 100644 index 00000000000..bc957f94415 --- /dev/null +++ b/it/it-tests/src/test/java/it/measureHistory/HistoryUiTest.java @@ -0,0 +1,84 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package it.measureHistory; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarRunner; +import com.sonar.orchestrator.locator.FileLocation; +import com.sonar.orchestrator.selenium.Selenese; +import it.Category1Suite; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import util.selenium.SeleneseTest; + +import static util.ItUtils.projectDir; + +public class HistoryUiTest { + + @ClassRule + public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + + @BeforeClass + public static void initialize() { + orchestrator.resetData(); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); + orchestrator.getServer().provisionProject("sample", "sample"); + orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); + analyzeProject("shared/xoo-history-v1", "2014-10-19"); + analyzeProject("shared/xoo-history-v2", "2014-11-13"); + } + + private static void analyzeProject(String path, String date) { + orchestrator.executeBuild(SonarRunner.create(projectDir(path)) + .setProperties("sonar.projectDate", date)); + } + + @Test + public void test_timeline_widget() { + new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("history-timeline-widget", + "/measureHistory/HistoryUiTest/history-timeline-widget/timeline-widget.html", + // SONAR-3561 + "/measureHistory/HistoryUiTest/history-timeline-widget/should-display-even-if-one-missing-metric.html" + ).build()).runOn(orchestrator); + } + + @Test + public void test_timemachine_widget() { + // Use old way to execute Selenium because 'waitForTextPresent' action is not supported by SeleneseTest + orchestrator.executeSelenese(Selenese.builder().setHtmlTestsInClasspath("history-timemachine-widget", + "/measureHistory/HistoryUiTest/history-timemachine-widget/time-machine-widget.html", + // SONAR-3354 & SONAR-3353 + "/measureHistory/HistoryUiTest/history-timemachine-widget/should-display-empty-table-if-no-measure.html", + // SONAR-3650 + "/measureHistory/HistoryUiTest/history-timemachine-widget/should-exclude-new-metrics.html" + ).build()); + } + + /** + * SONAR-2911 + */ + @Test + public void test_comparison_page_between_project_versions() { + new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("comparison-page", + "/measureHistory/HistoryUiTest/comparison/should-compare-project-versions.html" + ).build()).runOn(orchestrator); + } +} diff --git a/it/it-tests/src/test/java/it/measureHistory/SincePreviousVersionHistoryTest.java b/it/it-tests/src/test/java/it/measureHistory/SincePreviousVersionHistoryTest.java new file mode 100644 index 00000000000..1fbd09aa03d --- /dev/null +++ b/it/it-tests/src/test/java/it/measureHistory/SincePreviousVersionHistoryTest.java @@ -0,0 +1,95 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package it.measureHistory; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarRunner; +import it.Category1Suite; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; +import util.ItUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.projectDir; +import static util.ItUtils.setServerProperty; + +public class SincePreviousVersionHistoryTest { + + @ClassRule + public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + + private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; + + @BeforeClass + public static void initPeriods() throws Exception { + setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); + setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); + } + + @AfterClass + public static void resetPeriods() throws Exception { + ItUtils.resetPeriods(orchestrator); + } + + /** + * SONAR-2496 + */ + @Test + public void test_since_previous_version_period() { + orchestrator.resetData(); + analyzeProject("0.9", "**/*2.xoo"); + analyzeProject("1.0-SNAPSHOT", null); + analyzeProject("1.0-SNAPSHOT", null); + + Resource project = getProject("files"); + Measure measure = project.getMeasure("files"); + + // There are 4 files + assertThat(measure.getValue()).isEqualTo(4); + + // nothing changed in the previous analysis + assertThat(project.getPeriod1Mode()).isEqualTo("previous_analysis"); + assertThat(measure.getVariation1()).isEqualTo(0); + + // but 2 files were added since the first analysis which was version 0.9 + assertThat(project.getPeriod3Mode()).isEqualTo("previous_version"); + assertThat(project.getPeriod3Param()).isEqualTo("0.9"); + assertThat(measure.getVariation3()).isEqualTo(2); + } + + private static void analyzeProject(String version, String exclusions) { + SonarRunner build = SonarRunner.create(projectDir("shared/xoo-multi-modules-sample")) + .setProperties("sonar.projectVersion", version); + if (exclusions != null) { + build.setProperties("sonar.exclusions", exclusions); + } + orchestrator.executeBuild(build); + } + + private Resource getProject(String... metricKeys) { + return orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(PROJECT, metricKeys).setIncludeTrends(true)); + } +} diff --git a/it/it-tests/src/test/java/it/measureHistory/SinceXDaysHistoryTest.java b/it/it-tests/src/test/java/it/measureHistory/SinceXDaysHistoryTest.java new file mode 100644 index 00000000000..a73a6158109 --- /dev/null +++ b/it/it-tests/src/test/java/it/measureHistory/SinceXDaysHistoryTest.java @@ -0,0 +1,138 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package it.measureHistory; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarRunner; +import com.sonar.orchestrator.locator.FileLocation; +import it.Category1Suite; +import java.text.SimpleDateFormat; +import java.util.Date; +import org.apache.commons.lang.time.DateUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; +import util.ItUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.projectDir; +import static util.ItUtils.setServerProperty; + +public class SinceXDaysHistoryTest { + + @ClassRule + public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + + private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; + + @BeforeClass + public static void analyseProjectWithHistory() { + initPeriods(); + + orchestrator.resetData(); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); + orchestrator.getServer().provisionProject(PROJECT, PROJECT); + orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "one-issue-per-line"); + + // Execute a analysis in the past before since 30 days period -> 0 issue, 0 file + analyzeProject("2013-01-01", "multi-modules-sample:module_b,multi-modules-sample:module_a"); + + // Execute a analysis 20 days ago, after since 30 days period -> 16 issues, 1 file + analyzeProject(getPastDate(20), "multi-modules-sample:module_b,multi-modules-sample:module_a:module_a2"); + + // Execute a analysis 10 days ago, after since 30 days period -> 28 issues, 2 files + analyzeProject(getPastDate(10), "multi-modules-sample:module_b"); + + // Execute a analysis in the present with all modules -> 52 issues, 4 files + analyzeProject(); + } + + public static void initPeriods() { + setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); + setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); + } + + @AfterClass + public static void resetPeriods() throws Exception { + ItUtils.resetPeriods(orchestrator); + } + + @Test + public void periods_are_well_defined() throws Exception { + Resource project = getProject("files"); + + assertThat(project.getPeriod1Mode()).isEqualTo("previous_analysis"); + + assertThat(project.getPeriod2Mode()).isEqualTo("days"); + assertThat(project.getPeriod2Param()).isEqualTo("30"); + } + + @Test + public void check_files_variation() throws Exception { + checkMeasure("files", 2, 3); + } + + @Test + public void check_issues_variation() throws Exception { + checkMeasure("violations", 24, 45); + } + + @Test + public void check_new_issues_measures() throws Exception { + checkMeasure("new_violations", 24, 45); + } + + private void checkMeasure(String measure, int variation1, int variation2){ + Resource project = getProject(measure); + Measure newTechnicalDebt = project.getMeasure(measure); + + assertThat(newTechnicalDebt.getVariation1().intValue()).isEqualTo(variation1); + assertThat(newTechnicalDebt.getVariation2().intValue()).isEqualTo(variation2); + } + + private Resource getProject(String... metricKeys) { + return orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(PROJECT, metricKeys).setIncludeTrends(true)); + } + + private static void analyzeProject() { + analyzeProject(null, null); + } + + private static void analyzeProject(String date, String skippedModules) { + SonarRunner runner = SonarRunner.create(projectDir("shared/xoo-multi-modules-sample")); + if (date != null) { + runner.setProperty("sonar.projectDate", date); + } + if (skippedModules != null) { + runner.setProperties("sonar.skippedModules", skippedModules); + } + orchestrator.executeBuild(runner); + } + + private static String getPastDate(int nbPastDays){ + return new SimpleDateFormat("yyyy-MM-dd").format(DateUtils.addDays(new Date(), nbPastDays * -1)); + } + +} diff --git a/it/it-tests/src/test/java/it/measureHistory/TimeMachineTest.java b/it/it-tests/src/test/java/it/measureHistory/TimeMachineTest.java index d5d2ebe7cbe..a9903dffa42 100644 --- a/it/it-tests/src/test/java/it/measureHistory/TimeMachineTest.java +++ b/it/it-tests/src/test/java/it/measureHistory/TimeMachineTest.java @@ -23,8 +23,9 @@ import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.BuildResult; import com.sonar.orchestrator.build.SonarRunner; import com.sonar.orchestrator.locator.FileLocation; -import it.Category2Suite; +import it.Category1Suite; import java.util.Date; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; @@ -33,20 +34,23 @@ import org.sonar.wsclient.services.ResourceQuery; import org.sonar.wsclient.services.TimeMachine; import org.sonar.wsclient.services.TimeMachineCell; import org.sonar.wsclient.services.TimeMachineQuery; +import util.ItUtils; import static org.assertj.core.api.Assertions.assertThat; import static util.ItUtils.projectDir; +import static util.ItUtils.setServerProperty; public class TimeMachineTest { private static final String PROJECT = "sample"; @ClassRule - public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; + public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; @BeforeClass public static void initialize() { orchestrator.resetData(); + initPeriods(); orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); orchestrator.getServer().provisionProject("sample", "Sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); @@ -54,6 +58,17 @@ public class TimeMachineTest { analyzeProject("measure/xoo-history-v2", "2014-11-13"); } + public static void initPeriods() { + setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); + setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); + setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); + } + + @AfterClass + public static void resetPeriods() throws Exception { + ItUtils.resetPeriods(orchestrator); + } + private static BuildResult analyzeProject(String path, String date) { return orchestrator.executeBuild(SonarRunner.create(projectDir(path), "sonar.projectDate", date)); } diff --git a/it/it-tests/src/test/java/it/measureHistory/TimeMachineUiTest.java b/it/it-tests/src/test/java/it/measureHistory/TimeMachineUiTest.java new file mode 100644 index 00000000000..eed6744f14a --- /dev/null +++ b/it/it-tests/src/test/java/it/measureHistory/TimeMachineUiTest.java @@ -0,0 +1,65 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package it.measureHistory; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarRunner; +import com.sonar.orchestrator.selenium.Selenese; +import it.Category1Suite; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import util.selenium.SeleneseTest; + +import static util.ItUtils.projectDir; + +public class TimeMachineUiTest { + + @ClassRule + public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + + @Before + public void setUp() throws Exception { + orchestrator.resetData(); + orchestrator.getServer().provisionProject("sample", "sample"); + orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty"); + } + + private static void analyzeProject(String date, String version) { + orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample")) + .setProperties("sonar.projectDate", date) + .setProperties("sonar.projectVersion", version) + ); + } + + // SONAR-3006 + @Test + public void test_time_machine_dashboard() { + analyzeProject("2012-09-01", "0.7"); + analyzeProject("2012-10-15", "0.8"); + analyzeProject("2012-11-30", "0.9"); + analyzeProject("2012-12-31", "1.0-SNAPSHOT"); + + new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("timemachine", + "/measureHistory/TimeMachineUiTest/should-display-timemachine-dashboard.html" + ).build()).runOn(orchestrator); + } + +} diff --git a/it/it-tests/src/test/java/util/ItUtils.java b/it/it-tests/src/test/java/util/ItUtils.java index b3cee3b3561..4bf8e8cf624 100644 --- a/it/it-tests/src/test/java/util/ItUtils.java +++ b/it/it-tests/src/test/java/util/ItUtils.java @@ -164,6 +164,14 @@ public class ItUtils { } } + public static void resetPeriods(Orchestrator orchestrator){ + setServerProperty(orchestrator, "sonar.timemachine.period1", null); + setServerProperty(orchestrator, "sonar.timemachine.period2", null); + setServerProperty(orchestrator, "sonar.timemachine.period3", null); + setServerProperty(orchestrator, "sonar.timemachine.period4", null); + setServerProperty(orchestrator, "sonar.timemachine.period5", null); + } + /** * Concatenates a vararg to a String array. * @@ -196,4 +204,4 @@ public class ItUtils { } } -} + } diff --git a/it/it-tests/src/test/resources/measureHistory/DifferentialPeriodsTest/display-periods-selection-dropdown-on-dashboard.html b/it/it-tests/src/test/resources/measureHistory/DifferentialPeriodsTest/display-periods-selection-dropdown-on-dashboard.html new file mode 100644 index 00000000000..c0aa52340c1 --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/DifferentialPeriodsTest/display-periods-selection-dropdown-on-dashboard.html @@ -0,0 +1,54 @@ + + + + + + + + display-added-files + + + + + + + + + + + + + + + + + + + + + + + + + +
should_display_added_files_in_differential_drilldown
open/sonar/dashboard/index?id=sample&name=Dashboard
assertTextdashboard*Time changes*
assertSelectOptionsselect-comparison*since previous analysis*
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/DifferentialPeriodsTest/not-display-periods-selection-dropdown-on-dashboard.html b/it/it-tests/src/test/resources/measureHistory/DifferentialPeriodsTest/not-display-periods-selection-dropdown-on-dashboard.html new file mode 100644 index 00000000000..092d1b35df8 --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/DifferentialPeriodsTest/not-display-periods-selection-dropdown-on-dashboard.html @@ -0,0 +1,29 @@ + + + + + + display-added-files + + + + + + + + + + + + + + + + + + + + +
should_display_added_files_in_differential_drilldown
open/sonar/dashboard/index?id=sample&name=Dashboard
assertNotTextdashboard*Time changes*
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/comparison/should-compare-project-versions.html b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/comparison/should-compare-project-versions.html new file mode 100644 index 00000000000..2e177ba42ca --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/comparison/should-compare-project-versions.html @@ -0,0 +1,34 @@ + + + + + + should-compare-project-versions + + + + + + + + + + + + + + + + + + + + + + + + + +
open/sonar/comparison/index?resource=sample&locale=en-gb
assertTextcomparison-page*Sample*0.9-SNAPSHOT*19 Oct 2014*Sample*1.0-SNAPSHOT*13 Nov 2014*
assertTextcomparison-page*Lines of code*24*40*
assertTextcomparison-page*Lines of code*Complexity*Comments (%)*Duplicated lines (%)*Issues*Coverage*
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timeline-widget/should-display-even-if-one-missing-metric.html b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timeline-widget/should-display-even-if-one-missing-metric.html new file mode 100644 index 00000000000..8c0d0ca3126 --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timeline-widget/should-display-even-if-one-missing-metric.html @@ -0,0 +1,35 @@ + + + + + +timeline + + + + + + + + + + + + + + + + + + + + + + + + + + +
timeline
open/sonar/widget?id=timeline&resource=sample&metric1=complexity&metric2=commits
assertElementPresenttimeline-chart-1
assertTextblock_1*Complexity*
assertTextNotPresentblock_1*Commits*
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timeline-widget/timeline-widget.html b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timeline-widget/timeline-widget.html new file mode 100644 index 00000000000..e1eefec4dc9 --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timeline-widget/timeline-widget.html @@ -0,0 +1,40 @@ + + + + + +timeline + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
timeline
open/sonar/widget?id=timeline&resource=sample&metric1=complexity&metric2=ncloc&chartTitle=MyWidget
assertElementPresenttimeline-chart-1
assertElementPresent//h3[text()='MyWidget']
assertTextblock_1*Complexity*
assertTextblock_1*Lines of code*
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/should-display-empty-table-if-no-measure.html b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/should-display-empty-table-if-no-measure.html new file mode 100644 index 00000000000..52078d7031b --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/should-display-empty-table-if-no-measure.html @@ -0,0 +1,32 @@ + + + + + +should-display-empty-table-if-no-measure + + + + + + + + + + + + + + + + + + + + + +
time_machine
open + /sonar/widget?id=time_machine&resource=sample&metric1=coverage&metric2=line_coverage&metric3=tests&displaySparkLine=true +
assertTextblock_1*Coverage*Line coverage*Unit tests*
assertElementNotPresent//img
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/should-exclude-new-metrics.html b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/should-exclude-new-metrics.html new file mode 100644 index 00000000000..2e1340c8ec4 --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/should-exclude-new-metrics.html @@ -0,0 +1,74 @@ + + + + + + should-exclude-new-metrics + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
should-exclude-new-metrics
open/sonar/sessions/new
typeloginadmin
typepasswordadmin
clickAndWaitcommit
clickAndWaitlink=Configure widgets
waitForTextPresentHistory Table
clickAndWaitid=add-widget-time_machine
waitForTextPresentHistory Table
assertElementPresent//option[text()='Overall condition coverage']
assertElementNotPresent//div[@class='widget_props' and @style='']//option[text()='Overall new condition coverage']
clicklink=Delete
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/time-machine-widget.html b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/time-machine-widget.html new file mode 100644 index 00000000000..a9601ab76a7 --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/HistoryUiTest/history-timemachine-widget/time-machine-widget.html @@ -0,0 +1,45 @@ + + + + + +time_machine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
time_machine
open/sonar/widget?id=time_machine&resource=sample&metric1=complexity&metric2=ncloc&metric3=violations&displaySparkLine=true&title=ViveLeSud
assertTextblock_1*ViveLeSud*
assertTextblock_1*Complexity*6*11*
assertTextblock_1*Lines of code*24*40*
assertTextblock_1*Issues*26*43*
assertElementPresentcss=img[alt="Chart?cht=sl&chdi=80x15&chv=20141019000000,6"]
+ + diff --git a/it/it-tests/src/test/resources/measureHistory/TimeMachineUiTest/should-display-timemachine-dashboard.html b/it/it-tests/src/test/resources/measureHistory/TimeMachineUiTest/should-display-timemachine-dashboard.html new file mode 100644 index 00000000000..1a40475885c --- /dev/null +++ b/it/it-tests/src/test/resources/measureHistory/TimeMachineUiTest/should-display-timemachine-dashboard.html @@ -0,0 +1,84 @@ + + + + + + + + should-display-timemachine-dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
should-display-timemachine-dashboard
open/sonar/dashboard/index/sample?name=TimeMachine
waitForTextdashboard*Complexity: 3*Technical Debt: 0*
assertTextdashboard*Sep 01 2012*0.7*Nov 30 2012*0.9*Dec 31 2012*1.0-SNAPSHOT*
assertTextdashboard*Lines of code*Lines*Statements*Files*Classes*Functions*Accessors*
assertTextdashboard*Comments*Comment lines*Public documented API*Public undocumented API*
assertTextdashboard*Duplicated lines (%)*Duplicated lines*Duplicated blocks*Duplicated files*
assertTextdashboard*Issues*Blocker issues*Critical issues*Major issues*Minor issues*Technical Debt*
assertTextdashboard*Complexity*Complexity /function*Complexity /class*Complexity /file*
assertTextdashboard*Coverage*Line coverage*
+ +