]> source.dussan.org Git - sonarqube.git/commitdiff
Add category measure to integration tests
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Sat, 11 Nov 2017 11:04:33 +0000 (12:04 +0100)
committerEric Hartmann <hartmann.eric@gmail.Com>
Tue, 14 Nov 2017 12:10:17 +0000 (13:10 +0100)
19 files changed:
cix.sh
server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/Tester.java
server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/UserTester.java
server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/measures/MeasuresPage.java
tests/src/test/java/org/sonarqube/tests/Category1Suite.java
tests/src/test/java/org/sonarqube/tests/Category3Suite.java
tests/src/test/java/org/sonarqube/tests/complexity/ComplexityMeasuresTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/customMeasure/CustomMeasuresTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/measure/ComplexityMeasuresTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/measure/CustomMeasuresTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/measure/DecimalScaleMetricTest.java
tests/src/test/java/org/sonarqube/tests/measure/DifferentialPeriodsTest.java
tests/src/test/java/org/sonarqube/tests/measure/MeasureSuite.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/measure/MeasuresWsTest.java
tests/src/test/java/org/sonarqube/tests/measure/ProjectDashboardTest.java
tests/src/test/java/org/sonarqube/tests/measure/ProjectMeasuresPageTest.java
tests/src/test/java/org/sonarqube/tests/measure/SincePreviousVersionHistoryTest.java
tests/src/test/java/org/sonarqube/tests/measure/SinceXDaysHistoryTest.java
tests/src/test/java/org/sonarqube/tests/measure/TimeMachineTest.java

diff --git a/cix.sh b/cix.sh
index 96a877df2bfe8ed1af22bfc80e7a298cc9ec8809..61f588d95dec9be9c6b78ccca5c8a71546d6f4ae 100755 (executable)
--- a/cix.sh
+++ b/cix.sh
@@ -33,6 +33,7 @@ case "$RUN_ACTIVITY" in
       case "$CATEGORY_GROUP" in
         Category1)
           CATEGORY=Category1 && runCategory
+          CATEGORY=measure && runCategory
           CATEGORY=source && runCategory
           ;;
 
index 50412d8bc505768a7b2f69569cd05049a541ff24..f5077ad32667fb6f4b62aa4b748f087fabeba84f 100644 (file)
@@ -39,12 +39,21 @@ import static java.util.Objects.requireNonNull;
  * <li>clean-up of users between tests</li>
  * <li>clean-up of session when opening a browser (cookies, local storage)</li>
  * <li>quick access to {@link WsClient} instances</li>
+ * <li>clean-up of defined settings. Properties that are not defined by a plugin are not reset.</li>
  * <li>helpers to generate organizations and users</li>
  * </ul>
- * <p>
+ *
  * Recommendation is to define a {@code @Rule} instance. If not possible, then
  * {@code @ClassRule} must be used through a {@link org.junit.rules.RuleChain}
  * around {@link Orchestrator}.
+ *
+ * Not supported:
+ * <ul>
+ *   <li>clean-up global settings</li>
+ *   <li>clean-up system administrators/roots</li>
+ *   <li>clean-up default organization</li>
+ *   <li>clean-up the properties that are not defined (no PropertyDefinition)</li>
+ * </ul>
  */
 public class Tester extends ExternalResource implements TesterSession {
 
index 5f4f4a943d0db70012664cfbb114b19b18a73486..6c57c8a81aae1d2709400a63a8913b8167defb43 100644 (file)
@@ -67,6 +67,9 @@ public class UserTester {
     return service().create(request.build()).getUser();
   }
 
+  /**
+   * For standalone mode only
+   */
   @SafeVarargs
   public final User generateAdministrator(Consumer<CreateRequest.Builder>... populators) {
     User user = generate(populators);
@@ -77,16 +80,29 @@ public class UserTester {
 
   @SafeVarargs
   public final User generateAdministrator(Organizations.Organization organization, Consumer<CreateRequest.Builder>... populators) {
+    String organizationKey = organization.getKey();
     User user = generate(populators);
-    session.wsClient().organizations().addMember(organization.getKey(), user.getLogin());
+    session.wsClient().organizations().addMember(organizationKey, user.getLogin());
     session.wsClient().userGroups().addUser(AddUserWsRequest.builder()
-      .setOrganization(organization.getKey())
+      .setOrganization(organizationKey)
       .setLogin(user.getLogin())
       .setName("Owners")
       .build());
     return user;
   }
 
+  @SafeVarargs
+  public final User generateAdministratorOnDefaultOrganization(Consumer<CreateRequest.Builder>... populators) {
+    User user = generate(populators);
+    session.wsClient().organizations().addMember("default-organization", user.getLogin());
+    session.wsClient().userGroups().addUser(AddUserWsRequest.builder()
+      .setOrganization("default-organization")
+      .setLogin(user.getLogin())
+      .setName("sonar-administrators")
+      .build());
+    return user;
+  }
+
   @SafeVarargs
   public final User generateMember(Organizations.Organization organization, Consumer<CreateRequest.Builder>... populators) {
     User user = generate(populators);
index f3cd21aac1beaf1ea48229a4c5d793c89910467f..4e39003c0489da65cda41c7e69ed88e9a8f2df74 100644 (file)
@@ -23,7 +23,9 @@ import com.codeborne.selenide.CollectionCondition;
 import com.codeborne.selenide.Condition;
 import com.codeborne.selenide.Selenide;
 import com.codeborne.selenide.SelenideElement;
+import com.codeborne.selenide.WebDriverRunner;
 import org.openqa.selenium.Keys;
+import org.openqa.selenium.interactions.Actions;
 
 public class MeasuresPage {
   public MeasuresPage() {
@@ -61,7 +63,16 @@ public class MeasuresPage {
   }
 
   public MeasuresPage backShortcut() {
-    Selenide.$(".layout-page-header-panel").sendKeys(Keys.LEFT);
+    SelenideElement panel = Selenide.$(".layout-page-header-panel");
+
+    // panel.sendKeys(Keys.LEFT) does not work correctly on Chrome
+    // The workaround is to use Actions
+    // https://bugs.chromium.org/p/chromedriver/issues/detail?id=35
+    Actions actions = new Actions(WebDriverRunner.getWebDriver());
+    actions.moveToElement(panel);
+    actions.click();
+    actions.sendKeys(Keys.LEFT);
+    actions.build().perform();
     return this;
   }
 
index 54ff60c08266201df1ec9a681d27402e88e35d0f..8fbbe37567da154a9b8dd8875bff92323e8e47f0 100644 (file)
@@ -28,14 +28,6 @@ import org.sonarqube.tests.authorisation.IssuePermissionTest;
 import org.sonarqube.tests.authorisation.PermissionSearchTest;
 import org.sonarqube.tests.authorisation.ProvisioningPermissionTest;
 import org.sonarqube.tests.authorisation.QualityProfileAdminPermissionTest;
-import org.sonarqube.tests.complexity.ComplexityMeasuresTest;
-import org.sonarqube.tests.customMeasure.CustomMeasuresTest;
-import org.sonarqube.tests.measure.DifferentialPeriodsTest;
-import org.sonarqube.tests.measure.MeasuresWsTest;
-import org.sonarqube.tests.measure.ProjectMeasuresPageTest;
-import org.sonarqube.tests.measure.SincePreviousVersionHistoryTest;
-import org.sonarqube.tests.measure.SinceXDaysHistoryTest;
-import org.sonarqube.tests.measure.TimeMachineTest;
 import org.sonarqube.tests.projectAdministration.BackgroundTasksTest;
 import org.sonarqube.tests.projectAdministration.ProjectAdministrationTest;
 import org.sonarqube.tests.projectAdministration.ProjectBulkDeletionPageTest;
@@ -81,19 +73,8 @@ import static util.ItUtils.xooPlugin;
   PermissionSearchTest.class,
   ProvisioningPermissionTest.class,
   QualityProfileAdminPermissionTest.class,
-  // custom measure
-  CustomMeasuresTest.class,
   // measure
-  ProjectMeasuresPageTest.class,
-  ProjectsPageTest.class,
-  MeasuresWsTest.class,
-  // measure history
-  DifferentialPeriodsTest.class,
-  SincePreviousVersionHistoryTest.class,
-  SinceXDaysHistoryTest.class,
-  TimeMachineTest.class,
-  // complexity
-  ComplexityMeasuresTest.class
+  ProjectsPageTest.class
 })
 public class Category1Suite {
 
index 51328e715c5f75015d0283ad90bafec63445b948..e5fbb821543ddbb1b995238c863865429ab16bc9 100644 (file)
@@ -37,7 +37,6 @@ import org.sonarqube.tests.analysis.SSLTest;
 import org.sonarqube.tests.analysis.ScannerTest;
 import org.sonarqube.tests.analysis.SettingsEncryptionTest;
 import org.sonarqube.tests.analysis.TempFolderTest;
-import org.sonarqube.tests.measure.DecimalScaleMetricTest;
 import org.sonarqube.tests.plugins.VersionPluginTest;
 import org.sonarqube.tests.webhook.WebhooksTest;
 
@@ -62,8 +61,6 @@ import static util.ItUtils.xooPlugin;
   SSLTest.class,
   FavoriteTest.class,
   RedirectTest.class,
-  // measures
-  DecimalScaleMetricTest.class,
   WebhooksTest.class
 })
 public class Category3Suite {
diff --git a/tests/src/test/java/org/sonarqube/tests/complexity/ComplexityMeasuresTest.java b/tests/src/test/java/org/sonarqube/tests/complexity/ComplexityMeasuresTest.java
deleted file mode 100644 (file)
index 3eb28da..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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 org.sonarqube.tests.complexity;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category1Suite;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-import static util.ItUtils.getMeasuresAsDoubleByMetricKey;
-import static util.ItUtils.projectDir;
-
-// TODO complete the test with other complexity metrics
-public class ComplexityMeasuresTest {
-
-  private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample";
-  private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a";
-  private static final String SUB_MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1";
-  private static final String DIRECTORY = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1";
-  private static final String FILE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo";
-
-  private static final String COMPLEXITY_METRIC = "complexity";
-  private static final String COGNITIVE_COMPLEXITY_METRIC = "cognitive_complexity";
-
-  @ClassRule
-  public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-
-  @BeforeClass
-  public static void inspectProject() {
-    orchestrator.resetData();
-    orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample")));
-  }
-
-  @Test
-  public void compute_complexity_metrics_on_file() {
-    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, FILE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
-      entry(COMPLEXITY_METRIC, 3d),
-      entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
-  }
-
-  @Test
-  public void compute_complexity_metrics_on_directory() {
-    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, DIRECTORY, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
-      entry(COMPLEXITY_METRIC, 3d),
-      entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
-  }
-
-  @Test
-  public void compute_complexity_metrics_on_sub_module() {
-    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, SUB_MODULE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
-      entry(COMPLEXITY_METRIC, 3d),
-      entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
-  }
-
-  @Test
-  public void compute_complexity_metrics_on_module() {
-    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, MODULE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
-      entry(COMPLEXITY_METRIC, 7d),
-      entry(COGNITIVE_COMPLEXITY_METRIC, 9d));
-  }
-
-  @Test
-  public void compute_complexity_metrics_on_project() {
-    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, PROJECT, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
-      entry(COMPLEXITY_METRIC, 13d),
-      entry(COGNITIVE_COMPLEXITY_METRIC, 17d));
-  }
-
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/customMeasure/CustomMeasuresTest.java b/tests/src/test/java/org/sonarqube/tests/customMeasure/CustomMeasuresTest.java
deleted file mode 100644 (file)
index 206f3eb..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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 org.sonarqube.tests.customMeasure;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category1Suite;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import util.ItUtils;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static util.ItUtils.projectDir;
-
-public class CustomMeasuresTest {
-
-  private static final String PROJECT_KEY = "sample";
-
-  @ClassRule
-  public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-
-  @Before
-  public void deleteProjects() {
-    orchestrator.resetData();
-  }
-
-  @Test
-  public void custom_measures_should_be_integrated_during_project_analysis() {
-    analyzeProject();
-    setBurnedBudget(1200.3);
-    setTeamSize(4);
-
-    assertThat(getMeasureAsDouble("team_size")).isNull();
-    assertThat(getMeasureAsDouble("burned_budget")).isNull();
-
-    analyzeProject();
-
-    assertThat(getMeasureAsDouble("burned_budget")).isEqualTo(1200.3);
-    assertThat(getMeasureAsDouble("team_size")).isEqualTo(4d);
-  }
-
-  @Test
-  public void should_update_value() {
-    analyzeProject();
-    setTeamSize(4);
-    analyzeProject();
-    updateTeamSize(15);
-    assertThat(getMeasureAsDouble("team_size")).isEqualTo(4d);
-    analyzeProject();// the value is available when the project is analyzed again
-    assertThat(getMeasureAsDouble("team_size")).isEqualTo(15d);
-  }
-
-  @Test
-  public void should_delete_custom_measure() {
-    analyzeProject();
-    setTeamSize(4);
-    analyzeProject();
-    deleteCustomMeasure("team_size");
-    assertThat(getMeasureAsDouble("team_size")).isEqualTo(4d);// the value is still available. It will be removed during next
-                                                                           // analyzed
-
-    analyzeProject();
-    assertThat(getMeasureAsDouble("team_size")).isNull();
-  }
-
-  private void analyzeProject() {
-    orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-sample")));
-  }
-
-  private void setTeamSize(int i) {
-    orchestrator.getServer().adminWsClient().post("api/custom_measures/create", "projectKey", PROJECT_KEY, "metricKey", "team_size", "value", String.valueOf(i));
-  }
-
-  private void updateTeamSize(int i) {
-    String response = orchestrator.getServer().adminWsClient().get("api/custom_measures/search", "projectKey", PROJECT_KEY, "metricKey", "team_size");
-    Matcher jsonObjectMatcher = Pattern.compile(".*?\"id\"\\s*:\\s*\"(.*?)\".*", Pattern.MULTILINE).matcher(response);
-    jsonObjectMatcher.find();
-    String customMeasureId = jsonObjectMatcher.group(1);
-    orchestrator.getServer().adminWsClient().post("api/custom_measures/update", "id", customMeasureId, "value", String.valueOf(i));
-  }
-
-  private void setBurnedBudget(double d) {
-    orchestrator.getServer().adminWsClient().post("api/custom_measures/create", "projectKey", PROJECT_KEY, "metricKey", "burned_budget", "value", String.valueOf(d));
-  }
-
-  private void deleteCustomMeasure(String metricKey) {
-    String response = orchestrator.getServer().adminWsClient().get("api/custom_measures/search", "projectKey", PROJECT_KEY, "metricKey", metricKey);
-    Matcher jsonObjectMatcher = Pattern.compile(".*?\"id\"\\s*:\\s*\"(.*?)\".*", Pattern.MULTILINE).matcher(response);
-    jsonObjectMatcher.find();
-    String customMeasureId = jsonObjectMatcher.group(1);
-    orchestrator.getServer().adminWsClient().post("api/custom_measures/delete", "id", customMeasureId);
-  }
-
-  private Double getMeasureAsDouble(String metricKey) {
-    return ItUtils.getMeasureAsDouble(orchestrator, PROJECT_KEY, metricKey);
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/measure/ComplexityMeasuresTest.java b/tests/src/test/java/org/sonarqube/tests/measure/ComplexityMeasuresTest.java
new file mode 100644 (file)
index 0000000..bbdd584
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 org.sonarqube.tests.measure;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.SonarScanner;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.sonarqube.qa.util.Tester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.entry;
+import static util.ItUtils.getMeasuresAsDoubleByMetricKey;
+import static util.ItUtils.projectDir;
+
+// TODO complete the test with other complexity metrics
+public class ComplexityMeasuresTest {
+
+  private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample";
+  private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a";
+  private static final String SUB_MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1";
+  private static final String DIRECTORY = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1";
+  private static final String FILE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo";
+  private static final String COMPLEXITY_METRIC = "complexity";
+  private static final String COGNITIVE_COMPLEXITY_METRIC = "cognitive_complexity";
+
+  @ClassRule
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
+
+  private static Tester tester = new Tester(orchestrator);
+
+  @ClassRule
+  public static RuleChain ruleChain = RuleChain.outerRule(orchestrator).around(tester);
+
+  @BeforeClass
+  public static void inspectProject() {
+    orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample")));
+  }
+
+  @Test
+  public void compute_complexity_metrics_on_file() {
+    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, FILE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
+      entry(COMPLEXITY_METRIC, 3d),
+      entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
+  }
+
+  @Test
+  public void compute_complexity_metrics_on_directory() {
+    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, DIRECTORY, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
+      entry(COMPLEXITY_METRIC, 3d),
+      entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
+  }
+
+  @Test
+  public void compute_complexity_metrics_on_sub_module() {
+    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, SUB_MODULE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
+      entry(COMPLEXITY_METRIC, 3d),
+      entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
+  }
+
+  @Test
+  public void compute_complexity_metrics_on_module() {
+    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, MODULE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
+      entry(COMPLEXITY_METRIC, 7d),
+      entry(COGNITIVE_COMPLEXITY_METRIC, 9d));
+  }
+
+  @Test
+  public void compute_complexity_metrics_on_project() {
+    assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, PROJECT, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
+      entry(COMPLEXITY_METRIC, 13d),
+      entry(COGNITIVE_COMPLEXITY_METRIC, 17d));
+  }
+
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/measure/CustomMeasuresTest.java b/tests/src/test/java/org/sonarqube/tests/measure/CustomMeasuresTest.java
new file mode 100644 (file)
index 0000000..91d2884
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 org.sonarqube.tests.measure;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.SonarScanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.PostRequest;
+import util.ItUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.projectDir;
+
+public class CustomMeasuresTest {
+
+  private static final String PROJECT_KEY = "sample";
+
+  @ClassRule
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
+
+  @Rule
+  public Tester tester = new Tester(orchestrator);
+
+  @Test
+  public void custom_measures_should_be_integrated_during_project_analysis() {
+    analyzeProject();
+    setBurnedBudget(1200.3);
+    setTeamSize(4);
+
+    assertThat(getMeasureAsDouble("team_size")).isNull();
+    assertThat(getMeasureAsDouble("burned_budget")).isNull();
+
+    analyzeProject();
+
+    assertThat(getMeasureAsDouble("burned_budget")).isEqualTo(1200.3);
+    assertThat(getMeasureAsDouble("team_size")).isEqualTo(4d);
+  }
+
+  @Test
+  public void should_update_value() {
+    analyzeProject();
+    setTeamSize(4);
+    analyzeProject();
+    updateTeamSize(15);
+    assertThat(getMeasureAsDouble("team_size")).isEqualTo(4d);
+    analyzeProject();// the value is available when the project is analyzed again
+    assertThat(getMeasureAsDouble("team_size")).isEqualTo(15d);
+  }
+
+  @Test
+  public void should_delete_custom_measure() {
+    analyzeProject();
+    setTeamSize(4);
+    analyzeProject();
+    deleteCustomMeasure("team_size");
+    assertThat(getMeasureAsDouble("team_size")).isEqualTo(4d);// the value is still available. It will be removed during next
+    // analyzed
+
+    analyzeProject();
+    assertThat(getMeasureAsDouble("team_size")).isNull();
+  }
+
+  private void analyzeProject() {
+    orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-sample")));
+  }
+
+  private void setTeamSize(int i) {
+    PostRequest postRequest = new PostRequest("api/custom_measures/create")
+      .setParam("projectKey", PROJECT_KEY)
+      .setParam("metricKey", "team_size")
+      .setParam("value", String.valueOf(i));
+    tester.wsClient().wsConnector().call(postRequest);
+  }
+
+  private void updateTeamSize(int i) {
+    GetRequest getRequest = new GetRequest("api/custom_measures/search")
+      .setParam("projectKey", PROJECT_KEY)
+      .setParam("metricKey", "team_size");
+    String response = tester.wsClient().wsConnector().call(getRequest).content();
+    Matcher jsonObjectMatcher = Pattern.compile(".*?\"id\"\\s*:\\s*\"(.*?)\".*", Pattern.MULTILINE).matcher(response);
+    jsonObjectMatcher.find();
+    String customMeasureId = jsonObjectMatcher.group(1);
+    PostRequest postRequest = new PostRequest("api/custom_measures/update")
+      .setParam("id", customMeasureId)
+      .setParam("value", String.valueOf(i));
+    tester.wsClient().wsConnector().call(postRequest);
+  }
+
+  private void setBurnedBudget(double d) {
+    PostRequest postRequest = new PostRequest("api/custom_measures/create")
+      .setParam("projectKey", PROJECT_KEY)
+      .setParam("metricKey", "burned_budget")
+      .setParam("value", String.valueOf(d));
+    tester.wsClient().wsConnector().call(postRequest);
+  }
+
+  private void deleteCustomMeasure(String metricKey) {
+    GetRequest getRequest = new GetRequest("api/custom_measures/search")
+      .setParam("projectKey", PROJECT_KEY)
+      .setParam("metricKey", metricKey);
+    String response = tester.wsClient().wsConnector().call(getRequest).content();
+    Matcher jsonObjectMatcher = Pattern.compile(".*?\"id\"\\s*:\\s*\"(.*?)\".*", Pattern.MULTILINE).matcher(response);
+    jsonObjectMatcher.find();
+    String customMeasureId = jsonObjectMatcher.group(1);
+
+    PostRequest postRequest = new PostRequest("api/custom_measures/delete")
+      .setParam("id", customMeasureId);
+    tester.wsClient().wsConnector().call(postRequest);
+  }
+
+  private Double getMeasureAsDouble(String metricKey) {
+    return ItUtils.getMeasureAsDouble(orchestrator, PROJECT_KEY, metricKey);
+  }
+}
index 448c9554402da5cf232a6bb0f1d2779f60ea7a76..ad75c6bbedc7745cb08df60ab4a644ab7d302ee6 100644 (file)
 package org.sonarqube.tests.measure;
 
 import com.sonar.orchestrator.Orchestrator;
-import org.sonarqube.tests.Category3Suite;
 import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
+import org.sonarqube.qa.util.Tester;
 import util.ItUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -37,7 +38,10 @@ public class DecimalScaleMetricTest {
    * Requires the plugin "batch-plugin" 
    */
   @ClassRule
-  public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
+
+  @Rule
+  public Tester tester = new Tester(orchestrator);
 
   @Test
   public void override_decimal_scale_of_numeric_metric() {
index a9b2b814ea3c7e7d12cd9a86fb141f2bb07995f7..360cd6b68473e141f2a131bf9d8bcb6acf3bb013 100644 (file)
 package org.sonarqube.tests.measure;
 
 import com.sonar.orchestrator.Orchestrator;
-import org.sonarqube.tests.Category1Suite;
 import java.util.Date;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.qa.util.pageobjects.Navigation;
+import org.sonarqube.qa.util.Tester;
 import util.ItUtils;
-import util.user.UserRule;
 
 import static org.apache.commons.lang.time.DateUtils.addDays;
 import static org.assertj.core.api.Assertions.assertThat;
 import static util.ItUtils.formatDate;
 import static util.ItUtils.getLeakPeriodValue;
 import static util.ItUtils.getMeasuresAsDoubleByMetricKey;
-import static util.ItUtils.newAdminWsClient;
-import static util.ItUtils.resetPeriod;
 import static util.ItUtils.runProjectAnalysis;
-import static util.ItUtils.setServerProperty;
 
 public class DifferentialPeriodsTest {
 
-  static final String PROJECT_KEY = "sample";
-  static final String MULTI_MODULE_PROJECT_KEY = "com.sonarsource.it.samples:multi-modules-sample";
-
-  static WsClient CLIENT;
+  private static final String PROJECT_KEY = "sample";
+  private static final String MULTI_MODULE_PROJECT_KEY = "com.sonarsource.it.samples:multi-modules-sample";
 
   @ClassRule
-  public static final Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
+  public static final Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
 
   @Rule
-  public UserRule userRule = UserRule.from(orchestrator);
-
-  private String adminUser;
-
-  @BeforeClass
-  public static void createWsClient() throws Exception {
-    CLIENT = newAdminWsClient(orchestrator);
-  }
-
-  @Before
-  public void cleanUpAnalysisData() {
-    orchestrator.resetData();
-    adminUser = userRule.createAdminUser();
-  }
-
-  @After
-  public void reset() throws Exception {
-    resetPeriod(orchestrator);
-  }
+  public Tester tester = new Tester(orchestrator);
 
   /**
    * SONAR-7093
@@ -82,8 +53,8 @@ public class DifferentialPeriodsTest {
     orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
 
     // Set a global property and a project property to ensure project property is used
-    setServerProperty(orchestrator, "sonar.leak.period", "previous_version");
-    setServerProperty(orchestrator, PROJECT_KEY, "sonar.leak.period", "30");
+    tester.settings().setGlobalSettings("sonar.leak.period", "previous_version");
+    tester.settings().setProjectSetting(PROJECT_KEY, "sonar.leak.period", "30");
 
     // Execute an analysis in the past to have a past snapshot without any issues
     orchestrator.getServer().associateProjectToQualityProfile(PROJECT_KEY, "xoo", "empty");
@@ -101,7 +72,8 @@ public class DifferentialPeriodsTest {
     assertThat(getLeakPeriodValue(orchestrator, PROJECT_KEY, "violations")).isEqualTo(17);
 
     // Check on ui that it's possible to define leak period on project
-    Navigation.create(orchestrator).openHome().logIn().submitCredentials(adminUser).openSettings("sample")
+    tester.wsClient().users().skipOnboardingTutorial();
+    tester.openBrowser().openHome().logIn().submitCredentials("admin", "admin").openSettings("sample")
       .assertSettingDisplayed("sonar.leak.period");
   }
 
@@ -111,7 +83,7 @@ public class DifferentialPeriodsTest {
   @Test
   public void ensure_differential_measures_are_computed_when_adding_new_component_after_period() throws Exception {
     orchestrator.getServer().provisionProject(MULTI_MODULE_PROJECT_KEY, MULTI_MODULE_PROJECT_KEY);
-    setServerProperty(orchestrator, MULTI_MODULE_PROJECT_KEY, "sonar.leak.period", "30");
+    tester.settings().setProjectSetting(MULTI_MODULE_PROJECT_KEY, "sonar.leak.period", "30");
 
     // Execute an analysis 60 days ago without module b
     orchestrator.getServer().associateProjectToQualityProfile(MULTI_MODULE_PROJECT_KEY, "xoo", "empty");
@@ -133,7 +105,7 @@ public class DifferentialPeriodsTest {
   @Test
   public void compute_no_new_lines_measures_when_changes_but_no_scm() throws Exception {
     orchestrator.getServer().provisionProject(MULTI_MODULE_PROJECT_KEY, MULTI_MODULE_PROJECT_KEY);
-    setServerProperty(orchestrator, MULTI_MODULE_PROJECT_KEY, "sonar.leak.period", "previous_version");
+    tester.settings().setProjectSetting(MULTI_MODULE_PROJECT_KEY, "sonar.leak.period", "previous_version");
 
     // Execute an analysis 60 days ago without module b
     orchestrator.getServer().associateProjectToQualityProfile(MULTI_MODULE_PROJECT_KEY, "xoo", "empty");
@@ -156,7 +128,7 @@ public class DifferentialPeriodsTest {
   public void compute_zero_new_lines_measures_when_no_changes_and_scm_available() throws Exception {
     String projectKey = "sample-scm";
     orchestrator.getServer().provisionProject(projectKey, projectKey);
-    setServerProperty(orchestrator, projectKey, "sonar.leak.period", "previous_version");
+    tester.settings().setProjectSetting(projectKey, "sonar.leak.period", "previous_version");
 
     // Execute an analysis 60 days ago
     runProjectAnalysis(orchestrator, "scm/xoo-sample-with-scm", "sonar.projectDate", formatDate(addDays(new Date(), -60)),
diff --git a/tests/src/test/java/org/sonarqube/tests/measure/MeasureSuite.java b/tests/src/test/java/org/sonarqube/tests/measure/MeasureSuite.java
new file mode 100644 (file)
index 0000000..ffc9325
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 org.sonarqube.tests.measure;
+
+import com.sonar.orchestrator.Orchestrator;
+import org.junit.ClassRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+import static util.ItUtils.pluginArtifact;
+import static util.ItUtils.xooPlugin;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+  ComplexityMeasuresTest.class,
+  CustomMeasuresTest.class,
+  DecimalScaleMetricTest.class,
+  DifferentialPeriodsTest.class,
+  MeasuresWsTest.class,
+  ProjectDashboardTest.class,
+  ProjectMeasuresPageTest.class,
+  SincePreviousVersionHistoryTest.class,
+  SinceXDaysHistoryTest.class,
+  TimeMachineTest.class
+})
+public class MeasureSuite {
+
+  @ClassRule
+  public static final Orchestrator ORCHESTRATOR = Orchestrator.builderEnv()
+    // reduce memory for Elasticsearch
+    .setServerProperty("sonar.search.javaOpts", "-Xms128m -Xmx128m")
+
+    .addPlugin(xooPlugin())
+
+    // used by DecimalScaleMetricTest
+    .addPlugin(pluginArtifact("batch-plugin"))
+
+    .build();
+
+}
index 6bbca17f4983eaa6bb9d522de55fe619e85abe36..e7718f11b36ba1f0fd6cd40c95c5ae5ff9cc54d1 100644 (file)
@@ -21,60 +21,48 @@ package org.sonarqube.tests.measure;
 
 import com.sonar.orchestrator.Orchestrator;
 import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category1Suite;
 import java.util.List;
-import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
+import org.sonarqube.qa.util.Tester;
 import org.sonarqube.ws.WsMeasures;
 import org.sonarqube.ws.WsMeasures.ComponentTreeWsResponse;
 import org.sonarqube.ws.WsMeasures.ComponentWsResponse;
-import org.sonarqube.ws.client.WsClient;
 import org.sonarqube.ws.client.measure.ComponentTreeWsRequest;
 import org.sonarqube.ws.client.measure.ComponentWsRequest;
-import util.ItUtils;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static util.ItUtils.projectDir;
-import static util.ItUtils.setServerProperty;
 
 public class MeasuresWsTest {
-  @ClassRule
-  public static final Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
 
   private static final String FILE_KEY = "sample:src/main/xoo/sample/Sample.xoo";
   private static final String DIR_KEY = "sample:src/main/xoo/sample";
-  WsClient wsClient;
 
-  @BeforeClass
-  public static void initPeriod() throws Exception {
-    setServerProperty(orchestrator, "sonar.leak.period", "previous_version");
-  }
+  @ClassRule
+  public static final Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
 
-  @AfterClass
-  public static void resetPeriod() throws Exception {
-    ItUtils.resetPeriod(orchestrator);
-  }
+  @Rule
+  public Tester tester = new Tester(orchestrator);
 
   @Before
-  public void inspectProject() {
-    orchestrator.resetData();
-
-    wsClient = ItUtils.newAdminWsClient(orchestrator);
+  public void setUp() {
+    tester.settings().setGlobalSettings("sonar.leak.period", "previous_version");
   }
 
   @Test
   public void component_tree() {
     scanXooSample();
 
-    ComponentTreeWsResponse response = wsClient.measures().componentTree(new ComponentTreeWsRequest()
-      .setBaseComponentKey("sample")
+    ComponentTreeWsResponse response = tester.wsClient().measures().componentTree(new ComponentTreeWsRequest()
+      .setComponent("sample")
       .setMetricKeys(singletonList("ncloc"))
-      .setAdditionalFields(newArrayList("metrics", "periods")));
+      .setAdditionalFields(asList("metrics", "periods")));
 
     assertThat(response).isNotNull();
     assertThat(response.getBaseComponent().getKey()).isEqualTo("sample");
@@ -85,7 +73,7 @@ public class MeasuresWsTest {
   }
 
   /**
-   * @see SONAR-7958
+   * SONAR-7958
    */
   @Test
   public void component_tree_supports_module_move_down() {
@@ -110,7 +98,7 @@ public class MeasuresWsTest {
   }
 
   /**
-   * @see SONAR-7958
+   * SONAR-7958
    */
   @Test
   public void component_tree_supports_module_move_up() {
@@ -135,8 +123,8 @@ public class MeasuresWsTest {
   }
 
   private void verifyComponentTreeWithChildren(String baseComponentKey, String... childKeys) {
-    ComponentTreeWsResponse response = wsClient.measures().componentTree(new ComponentTreeWsRequest()
-      .setBaseComponentKey(baseComponentKey)
+    ComponentTreeWsResponse response = tester.wsClient().measures().componentTree(new ComponentTreeWsRequest()
+      .setComponent(baseComponentKey)
       .setMetricKeys(singletonList("ncloc"))
       .setStrategy("children"));
 
@@ -149,8 +137,8 @@ public class MeasuresWsTest {
   public void component() {
     scanXooSample();
 
-    ComponentWsResponse response = wsClient.measures().component(new ComponentWsRequest()
-      .setComponentKey("sample")
+    ComponentWsResponse response = tester.wsClient().measures().component(new ComponentWsRequest()
+      .setComponent("sample")
       .setMetricKeys(singletonList("ncloc"))
       .setAdditionalFields(newArrayList("metrics", "periods")));
 
index 98c68aa196494e9d0a7c2ad509e714ac36b5de75..ff1b07fcd39b3dcc0debed29aa915f31a203fc17 100644 (file)
@@ -27,38 +27,28 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.openqa.selenium.Keys;
-import org.sonarqube.qa.util.pageobjects.Navigation;
+import org.sonarqube.qa.util.Tester;
 import org.sonarqube.qa.util.pageobjects.ProjectDashboardPage;
-import org.sonarqube.tests.Category1Suite;
 import org.sonarqube.ws.client.PostRequest;
-import org.sonarqube.ws.client.WsClient;
-import util.user.UserRule;
 
 import static com.codeborne.selenide.Condition.exist;
-import static com.codeborne.selenide.Condition.hasText;
 import static com.codeborne.selenide.Condition.text;
-import static util.ItUtils.newAdminWsClient;
 import static util.ItUtils.projectDir;
 import static util.selenium.Selenese.runSelenese;
 
 public class ProjectDashboardTest {
 
   @ClassRule
-  public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
 
   @Rule
-  public UserRule userRule = UserRule.from(orchestrator);
+  public Tester tester = new Tester(orchestrator);
 
-  private Navigation nav = Navigation.create(orchestrator);
-
-  private static WsClient wsClient;
   private String adminUser;
 
   @Before
   public void setUp() throws Exception {
-    wsClient = newAdminWsClient(orchestrator);
-    orchestrator.resetData();
-    adminUser = userRule.createAdminUser();
+    adminUser = tester.users().generateAdministratorOnDefaultOrganization().getLogin();
   }
 
   @Test
@@ -72,10 +62,10 @@ public class ProjectDashboardTest {
   public void display_size() {
     executeBuild("shared/xoo-sample", "sample", "Sample");
 
-    ProjectDashboardPage page = Navigation.create(orchestrator).openProjectDashboard("sample");
+    ProjectDashboardPage page = tester.openBrowser().openProjectDashboard("sample");
 
-    page.getLinesOfCode().should(hasText("13"));
-    page.getLanguageDistribution().should(hasText("Xoo"), hasText("13"));
+    page.getLinesOfCode().should(text("13"));
+    page.getLanguageDistribution().should(text("Xoo"), text("13"));
   }
 
   @Test
@@ -83,12 +73,12 @@ public class ProjectDashboardTest {
     executeBuild("shared/xoo-sample", "sample", "Sample");
 
     // Add some tags to the project
-    wsClient.wsConnector().call(
+    tester.wsClient().wsConnector().call(
       new PostRequest("api/project_tags/set")
         .setParam("project", "sample")
         .setParam("tags", "foo,bar,baz"));
 
-    ProjectDashboardPage page = Navigation.create(orchestrator).openProjectDashboard("sample");
+    ProjectDashboardPage page = tester.openBrowser().openProjectDashboard("sample");
     page
       .shouldHaveTags("foo", "bar", "baz")
       .shouldNotBeEditable();
@@ -98,13 +88,13 @@ public class ProjectDashboardTest {
   public void display_tags_with_edit() {
     executeBuild("shared/xoo-sample", "sample-with-tags", "Sample with tags");
     // Add some tags to another project to have them in the list
-    wsClient.wsConnector().call(
+    tester.wsClient().wsConnector().call(
       new PostRequest("api/project_tags/set")
         .setParam("project", "sample-with-tags")
         .setParam("tags", "foo,bar,baz"));
 
     executeBuild("shared/xoo-sample", "sample", "Sample");
-    ProjectDashboardPage page = nav.logIn().submitCredentials(adminUser).openProjectDashboard("sample");
+    ProjectDashboardPage page = tester.openBrowser().logIn().submitCredentials(adminUser).openProjectDashboard("sample");
     page
       .shouldHaveTags("No tags")
       .shouldBeEditable()
@@ -113,10 +103,10 @@ public class ProjectDashboardTest {
     page
       .shouldHaveTags("foo")
       .sendKeysToTagsInput("test")
-      .getTagAtIdx(0).should(hasText("+ test")).click();
+      .getTagAtIdx(0).should(text("+ test")).click();
     page
       .shouldHaveTags("foo", "test")
-      .getTagAtIdx(1).should(hasText("test"));
+      .getTagAtIdx(1).should(text("test"));
     page
       .sendKeysToTagsInput(Keys.ENTER)
       .shouldHaveTags("test");
@@ -126,19 +116,22 @@ public class ProjectDashboardTest {
   public void display_project_activity_shortcut() {
     executeBuild("shared/xoo-sample", "sample-with-tags", "Sample with tags");
     // Add some tags to another project to have them in the list
-    wsClient.wsConnector().call(
+    tester.wsClient().wsConnector().call(
       new PostRequest("api/project_tags/set")
         .setParam("project", "sample-with-tags")
         .setParam("tags", "foo,bar,baz"));
 
     executeBuild("shared/xoo-sample", "sample", "Sample");
-    ProjectDashboardPage page = nav.logIn().submitCredentials(adminUser).openProjectDashboard("sample");
+    ProjectDashboardPage page = tester.openBrowser()
+      .logIn()
+      .submitCredentials(adminUser)
+      .openProjectDashboard("sample");
     page.getOverviewMeasure("Debt").$(".overview-domain-measure-history-link").should(exist);
   }
 
   @Test
   public void display_a_nice_error_when_requesting_unknown_project() {
-    nav.open("/dashboard/index?id=unknown");
+    tester.openBrowser().open("/dashboard/index?id=unknown");
     Selenide.$("#nonav").should(text("The requested project does not exist. Either it has never been analyzed successfully or it has been deleted."));
     // TODO verify that on global homepage
   }
index 080d9e059a8de8c24bd1771c4bcdaba1f7d36cbb..6a81318ec5346eed4f40f5fd1f7a84c0f87e1598 100644 (file)
@@ -21,15 +21,14 @@ package org.sonarqube.tests.measure;
 
 import com.sonar.orchestrator.Orchestrator;
 import com.sonar.orchestrator.build.SonarScanner;
-import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.ClassRule;
-import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.sonarqube.qa.util.Tester;
 import org.sonarqube.qa.util.pageobjects.Navigation;
 import org.sonarqube.qa.util.pageobjects.measures.MeasureContent;
 import org.sonarqube.qa.util.pageobjects.measures.MeasuresPage;
-import org.sonarqube.tests.Category1Suite;
-import org.sonarqube.qa.util.Tester;
 
 import static com.codeborne.selenide.Condition.visible;
 import static com.codeborne.selenide.Selenide.$;
@@ -39,33 +38,35 @@ import static util.ItUtils.projectDir;
 
 public class ProjectMeasuresPageTest {
 
+  private static final String PROJECT_KEY = "project-measures-page-test-project";
+
   @ClassRule
-  public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
 
-  @Rule
-  public Tester tester = new Tester(orchestrator).disableOrganizations();
+  private static Tester tester = new Tester(orchestrator);
 
-  private static String projectKey = "project-measures-page-test-project";
+  @ClassRule
+  public static RuleChain ruleChain = RuleChain.outerRule(orchestrator).around(tester);
 
-  @Before
-  public void inspectProject() {
+  @BeforeClass
+  public static void setUp() {
     orchestrator.executeBuild(
       SonarScanner
         .create(projectDir("shared/xoo-sample"))
-        .setProperty("sonar.projectKey", projectKey)
+        .setProperty("sonar.projectKey", PROJECT_KEY)
         .setProperty("sonar.projectName", "ProjectMeasuresPageTest Project"));
 
     // one more time
     orchestrator.executeBuild(
       SonarScanner
         .create(projectDir("shared/xoo-sample"))
-        .setProperty("sonar.projectKey", projectKey)
+        .setProperty("sonar.projectKey", PROJECT_KEY)
         .setProperty("sonar.projectName", "ProjectMeasuresPageTest Project"));
   }
 
   @Test
   public void should_display_measures_page() {
-    MeasuresPage page = tester.openBrowser().openProjectMeasures(projectKey);
+    MeasuresPage page = tester.openBrowser().openProjectMeasures(PROJECT_KEY);
     page
       .displayBubbleChart("Risk")
       .openFacet("Maintainability")
@@ -79,7 +80,7 @@ public class ProjectMeasuresPageTest {
 
   @Test
   public void should_drilldown_on_list_view() {
-    MeasuresPage page = tester.openBrowser().openProjectMeasures(projectKey);
+    MeasuresPage page = tester.openBrowser().openProjectMeasures(PROJECT_KEY);
     MeasureContent content = page
       .openFacet("Size").openMeasureContent("ncloc");
     content
@@ -95,7 +96,7 @@ public class ProjectMeasuresPageTest {
 
   @Test
   public void should_drilldown_on_tree_view() {
-    MeasuresPage page = tester.openBrowser().openProjectMeasures(projectKey);
+    MeasuresPage page = tester.openBrowser().openProjectMeasures(PROJECT_KEY);
     MeasureContent content = page
       .openFacet("Size").openMeasureContent("ncloc");
     page.switchView("tree");
index 5dd7e15ca238cb71227bd71f8f8dd989ea65df22..dede45c53ae40d91a93025f78cc98f16f883531a 100644 (file)
@@ -21,17 +21,15 @@ package org.sonarqube.tests.measure;
 
 import com.sonar.orchestrator.Orchestrator;
 import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category1Suite;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.time.DateUtils;
-import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
-import util.ItUtils;
+import org.sonarqube.qa.util.Tester;
 
 import static java.lang.Integer.parseInt;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -40,56 +38,20 @@ import static org.sonarqube.ws.WsMeasures.PeriodValue;
 import static util.ItUtils.getLeakPeriodValue;
 import static util.ItUtils.getMeasureWithVariation;
 import static util.ItUtils.projectDir;
-import static util.ItUtils.setServerProperty;
 
 public class SincePreviousVersionHistoryTest {
 
-  private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample";
-  @ClassRule
-  public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-
-  @BeforeClass
-  public static void initPeriod() throws Exception {
-    setServerProperty(orchestrator, "sonar.leak.period", "previous_version");
-  }
-
-  @AfterClass
-  public static void resetPeriod() throws Exception {
-    ItUtils.resetPeriod(orchestrator);
-  }
-
-  private static void analyzeProject(String version) {
-    analyzeProject(version, null, null);
-  }
-
-  private static void analyzeProjectWithExclusions(String version, String exclusions) {
-    analyzeProject(version, exclusions, null);
-  }
-
-  private static void analyzeProjectWithDate(String version, String date) {
-    analyzeProject(version, null, date);
-  }
+  private static final String PROJECT_KEY = "com.sonarsource.it.samples:multi-modules-sample";
 
-  private static void analyzeProject(String version, @Nullable String exclusions, @Nullable String date) {
-    SonarScanner build = SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))
-      .setProperties("sonar.projectVersion", version);
-    if (exclusions != null) {
-      build.setProperties("sonar.exclusions", exclusions);
-    }
-    if (date != null) {
-      build.setProperty("sonar.projectDate", date);
-    }
-    orchestrator.executeBuild(build);
-  }
+  @ClassRule
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
 
-  public static String toStringDate(Date date) {
-    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-    return sdf.format(date);
-  }
+  @Rule
+  public Tester tester = new Tester(orchestrator);
 
   @Before
-  public void resetData() throws Exception {
-    orchestrator.resetData();
+  public void setUp() throws Exception {
+    tester.settings().setGlobalSettings("sonar.leak.period", "previous_version");
   }
 
   /**
@@ -101,7 +63,7 @@ public class SincePreviousVersionHistoryTest {
     analyzeProject("1.0-SNAPSHOT");
     analyzeProject("1.0-SNAPSHOT");
 
-    Measure measure = getMeasureWithVariation(orchestrator, PROJECT, "files");
+    Measure measure = getMeasureWithVariation(orchestrator, PROJECT_KEY, "files");
 
     // There are 4 files
     assertThat(parseInt(measure.getValue())).isEqualTo(4);
@@ -119,15 +81,44 @@ public class SincePreviousVersionHistoryTest {
     // Analyze project by excluding some files
     analyzeProject("1.0-SNAPSHOT", "**/*2.xoo", toStringDate(DateUtils.addDays(now, -2)));
     // No difference measure after first analysis
-    assertThat(getLeakPeriodValue(orchestrator, PROJECT, "files")).isNull();
+    assertThat(getLeakPeriodValue(orchestrator, PROJECT_KEY, "files")).isNull();
 
     analyzeProjectWithDate("1.0-SNAPSHOT", toStringDate(DateUtils.addDays(now, -1)));
     // No new version, first analysis is used -> 2 new files
-    assertThat(getLeakPeriodValue(orchestrator, PROJECT, "files")).isEqualTo(2);
+    assertThat(getLeakPeriodValue(orchestrator, PROJECT_KEY, "files")).isEqualTo(2);
 
     analyzeProjectWithDate("1.0-SNAPSHOT", toStringDate(now));
     // Still no new version, first analysis is used -> 2 new files
-    assertThat(getLeakPeriodValue(orchestrator, PROJECT, "files")).isEqualTo(2);
+    assertThat(getLeakPeriodValue(orchestrator, PROJECT_KEY, "files")).isEqualTo(2);
+  }
+
+
+  private static void analyzeProject(String version) {
+    analyzeProject(version, null, null);
+  }
+
+  private static void analyzeProjectWithExclusions(String version, String exclusions) {
+    analyzeProject(version, exclusions, null);
+  }
+
+  private static void analyzeProjectWithDate(String version, String date) {
+    analyzeProject(version, null, date);
   }
 
+  private static void analyzeProject(String version, @Nullable String exclusions, @Nullable String date) {
+    SonarScanner build = SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))
+      .setProperties("sonar.projectVersion", version);
+    if (exclusions != null) {
+      build.setProperties("sonar.exclusions", exclusions);
+    }
+    if (date != null) {
+      build.setProperty("sonar.projectDate", date);
+    }
+    orchestrator.executeBuild(build);
+  }
+
+  private static String toStringDate(Date date) {
+    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+    return sdf.format(date);
+  }
 }
index b37942b817e6c7aa32ced1e8d4b7b36dcaebde7c..c030f301e0baea8cce30975c4d4a11d3cc489444 100644 (file)
@@ -21,15 +21,15 @@ package org.sonarqube.tests.measure;
 
 import com.sonar.orchestrator.Orchestrator;
 import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category1Suite;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import javax.annotation.Nullable;
 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.junit.rules.RuleChain;
+import org.sonarqube.qa.util.Tester;
 import org.sonarqube.ws.WsMeasures;
 import util.ItUtils;
 
@@ -37,20 +37,23 @@ import static java.lang.Integer.parseInt;
 import static org.assertj.core.api.Assertions.assertThat;
 import static util.ItUtils.getMeasureWithVariation;
 import static util.ItUtils.projectDir;
-import static util.ItUtils.setServerProperty;
 
 public class SinceXDaysHistoryTest {
 
+  private static final String PROJECT = "multi-files-sample";
+
   @ClassRule
-  public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
 
-  private static final String PROJECT = "multi-files-sample";
+  private static Tester tester = new Tester(orchestrator);
+
+  @ClassRule
+  public static RuleChain ruleChain = RuleChain.outerRule(orchestrator).around(tester);
 
   @BeforeClass
   public static void analyseProjectWithHistory() {
-    initPeriod();
+    tester.settings().setGlobalSettings("sonar.leak.period", "30");
 
-    orchestrator.resetData();
     ItUtils.restoreProfile(orchestrator, SinceXDaysHistoryTest.class.getResource("/measure/one-issue-per-line-profile.xml"));
     orchestrator.getServer().provisionProject(PROJECT, PROJECT);
     orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "one-issue-per-line");
@@ -68,15 +71,6 @@ public class SinceXDaysHistoryTest {
     analyzeProject();
   }
 
-  private static void initPeriod() {
-    setServerProperty(orchestrator, "sonar.leak.period", "30");
-  }
-
-  @AfterClass
-  public static void resetPeriods() throws Exception {
-    ItUtils.resetPeriod(orchestrator);
-  }
-
   @Test
   public void check_files_variation() throws Exception {
     checkMeasure("files", 3);
index 5d5e5afdde1f339e2fc9480dca96f8372c5bc8f5..34b9f0dbc1888c3d32c1370dc4e7ffe3bde4bdcc 100644 (file)
 package org.sonarqube.tests.measure;
 
 import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildResult;
 import com.sonar.orchestrator.build.SonarScanner;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.Map;
-import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Test;
-import org.sonarqube.tests.Category1Suite;
+import org.junit.rules.RuleChain;
+import org.sonarqube.qa.util.Tester;
 import org.sonarqube.ws.WsMeasures.Measure;
 import org.sonarqube.ws.WsMeasures.SearchHistoryResponse;
 import org.sonarqube.ws.WsMeasures.SearchHistoryResponse.HistoryValue;
-import org.sonarqube.ws.client.measure.MeasuresService;
 import org.sonarqube.ws.client.measure.SearchHistoryRequest;
 import util.ItUtils;
 import util.ItUtils.ComponentNavigation;
@@ -45,22 +43,23 @@ import static util.ItUtils.formatDate;
 import static util.ItUtils.getComponentNavigation;
 import static util.ItUtils.getMeasuresByMetricKey;
 import static util.ItUtils.getMeasuresWithVariationsByMetricKey;
-import static util.ItUtils.newAdminWsClient;
 import static util.ItUtils.projectDir;
-import static util.ItUtils.setServerProperty;
 
 public class TimeMachineTest {
 
-  private static final String PROJECT = "sample";
+  private static final String PROJECT_KEY = "sample";
 
   @ClassRule
-  public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-  private static MeasuresService wsMeasures;
+  public static Orchestrator orchestrator = MeasureSuite.ORCHESTRATOR;
+
+  private static Tester tester = new Tester(orchestrator);
+
+  @ClassRule
+  public static RuleChain ruleChain = RuleChain.outerRule(orchestrator).around(tester);
 
   @BeforeClass
-  public static void initialize() {
-    orchestrator.resetData();
-    initPeriod();
+  public static void setUp() {
+    tester.settings().setGlobalSettings("sonar.leak.period", "previous_version");
     ItUtils.restoreProfile(orchestrator, TimeMachineTest.class.getResource("/measure/one-issue-per-line-profile.xml"));
     orchestrator.getServer().provisionProject("sample", "Sample");
     orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
@@ -70,26 +69,11 @@ public class TimeMachineTest {
     String aMonthAgo = formatDate(addDays(now, -30));
     analyzeProject("measure/xoo-history-v1", aMonthAgo);
     analyzeProject("measure/xoo-history-v2", yesterday);
-
-    wsMeasures = newAdminWsClient(orchestrator).measures();
-  }
-
-  private static void initPeriod() {
-    setServerProperty(orchestrator, "sonar.leak.period", "previous_version");
-  }
-
-  @AfterClass
-  public static void resetPeriod() throws Exception {
-    ItUtils.resetPeriod(orchestrator);
-  }
-
-  private static BuildResult analyzeProject(String path, String date) {
-    return orchestrator.executeBuild(SonarScanner.create(projectDir(path), "sonar.projectDate", date));
   }
 
   @Test
   public void projectIsAnalyzed() {
-    ComponentNavigation component = getComponentNavigation(orchestrator, PROJECT);
+    ComponentNavigation component = getComponentNavigation(orchestrator, PROJECT_KEY);
     assertThat(component.getVersion()).isEqualTo("1.0-SNAPSHOT");
   }
 
@@ -118,8 +102,8 @@ public class TimeMachineTest {
   public void noDataForInterval() {
     Date now = new Date();
 
-    SearchHistoryResponse response = wsMeasures.searchHistory(SearchHistoryRequest.builder()
-      .setComponent(PROJECT)
+    SearchHistoryResponse response = tester.wsClient().measures().searchHistory(SearchHistoryRequest.builder()
+      .setComponent(PROJECT_KEY)
       .setMetrics(singletonList("lines"))
       .setFrom(formatDate(now))
       .setTo(formatDate(now))
@@ -134,20 +118,24 @@ public class TimeMachineTest {
    */
   @Test
   public void measure_variations_are_only_meaningful_when_additional_fields_contains_periods() {
-    Map<String, Measure> measures = getMeasuresWithVariationsByMetricKey(orchestrator, PROJECT, "violations", "new_violations");
+    Map<String, Measure> measures = getMeasuresWithVariationsByMetricKey(orchestrator, PROJECT_KEY, "violations", "new_violations");
     assertThat(measures.get("violations")).isNotNull();
     assertThat(measures.get("new_violations")).isNotNull();
     SearchHistoryResponse response = searchHistory("new_violations");
     assertThat(response.getMeasures(0).getHistoryCount()).isGreaterThan(0);
 
-    measures = getMeasuresByMetricKey(orchestrator, PROJECT, "violations", "new_violations");
+    measures = getMeasuresByMetricKey(orchestrator, PROJECT_KEY, "violations", "new_violations");
     assertThat(measures.get("violations")).isNotNull();
     assertThat(measures.get("new_violations")).isNull();
   }
 
+  private static void analyzeProject(String path, String date) {
+    orchestrator.executeBuild(SonarScanner.create(projectDir(path), "sonar.projectDate", date));
+  }
+
   private static SearchHistoryResponse searchHistory(String... metrics) {
-    return wsMeasures.searchHistory(SearchHistoryRequest.builder()
-      .setComponent(PROJECT)
+    return tester.wsClient().measures().searchHistory(SearchHistoryRequest.builder()
+      .setComponent(PROJECT_KEY)
       .setMetrics(Arrays.asList(metrics))
       .build());
   }