*/
package org.sonar.server.badge.ws;
-import com.tngtech.java.junit.dataprovider.DataProvider;
-import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.server.badge.ws.SvgGenerator.Color;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.measure.Rating;
+import org.sonar.server.telemetry.TelemetryBadgeProvider;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import static org.sonar.api.measures.CoreMetrics.BUGS_KEY;
import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
import static org.sonar.api.measures.CoreMetrics.SECURITY_HOTSPOTS_KEY;
import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_ERROR;
import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_OK;
-@RunWith(DataProviderRunner.class)
-public class MeasureActionIT {
+class MeasureActionIT {
- @Rule
+ @RegisterExtension
public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
+ @RegisterExtension
public DbTester db = DbTester.create();
- private final MapSettings mapSettings = new MapSettings();
- private final Configuration config = mapSettings.asConfig();
+ private static final MapSettings mapSettings = new MapSettings();
+ private static final Configuration config = mapSettings.asConfig();
+ private static final TelemetryBadgeProvider telemetryBadgeProvider = mock(TelemetryBadgeProvider.class);
private final WsActionTester ws = new WsActionTester(
new MeasureAction(
db.getDbClient(),
new ProjectBadgesSupport(new ComponentFinder(db.getDbClient(), null), db.getDbClient(), config),
- new SvgGenerator()));
+ new SvgGenerator(), telemetryBadgeProvider));
- @Before
- public void before() {
+ @BeforeAll
+ public static void before() {
mapSettings.setProperty(CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY, false);
}
@Test
- public void int_measure() {
+ void getBadge_shouldUpdateTelemetryBadgeProvider() {
+ clearInvocations(telemetryBadgeProvider);
+ ProjectData projectData = db.components().insertPublicProject();
+ ComponentDto project = projectData.getMainBranchComponent();
+
+ userSession.registerProjects(projectData.getProjectDto());
+ MetricDto metric = createIntMetricAndMeasure(project, BUGS_KEY, 10_000);
+
+ ws.newRequest()
+ .setParam("project", project.getKey())
+ .setParam("metric", metric.getKey())
+ .execute();
+
+ verify(telemetryBadgeProvider).incrementForMetric(BUGS_KEY);
+ }
+
+ @Test
+ void int_measure() {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void percent_measure() {
+ void percent_measure() {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void duration_measure() {
+ void duration_measure() {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
checkWithIfNoneMatchHeader(project, metric, response);
}
- @DataProvider
public static Object[][] ratings() {
return new Object[][] {
{Rating.A, Color.RATING_A},
};
}
- @Test
- @UseDataProvider("ratings")
- public void rating_measure(Rating rating, Color color) {
+ @ParameterizedTest
+ @MethodSource("ratings")
+ void rating_measure(Rating rating, Color color) {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
checkWithIfNoneMatchHeader(project, metric, response);
}
- @DataProvider
public static Object[][] qualityGates() {
return new Object[][] {
{OK, "passed", QUALITY_GATE_OK},
};
}
- @Test
- @UseDataProvider("qualityGates")
- public void quality_gate(Level status, String expectedValue, Color expectedColor) {
+ @ParameterizedTest
+ @MethodSource("qualityGates")
+ void quality_gate(Level status, String expectedValue, Color expectedColor) {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void security_hotspots() {
+ void security_hotspots() {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void measure_on_non_main_branch() {
+ void measure_on_non_main_branch() {
ProjectData projectData = db.components().insertPublicProject(p -> p.setPrivate(false));
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void measure_on_application() {
+ void measure_on_application() {
ProjectData projectData = db.components().insertPublicApplication();
ComponentDto application = projectData.getMainBranchComponent();
}
@Test
- public void return_error_if_project_does_not_exist() throws ParseException {
+ void return_error_if_project_does_not_exist() throws ParseException {
MetricDto metric = db.measures().insertMetric(m -> m.setKey(BUGS_KEY));
TestResponse response = ws.newRequest()
}
@Test
- public void return_error_if_branch_does_not_exist() throws ParseException {
+ void return_error_if_branch_does_not_exist() throws ParseException {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(BRANCH));
}
@Test
- public void return_error_if_measure_not_found() throws ParseException {
+ void return_error_if_measure_not_found() throws ParseException {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void return_error_on_directory() throws ParseException {
+ void return_error_on_directory() throws ParseException {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
ComponentDto directory = db.components().insertComponent(ComponentTesting.newDirectory(project, "path"));
}
@Test
- public void return_error_on_private_project_without_token() throws ParseException {
+ void return_error_on_private_project_without_token() throws ParseException {
ProjectDto project = db.components().insertPrivateProject().getProjectDto();
UserDto user = db.users().insertUser();
userSession.logIn(user).addProjectPermission(USER, project);
checkError(response, "Project has not been found");
}
- @DataProvider
public static Object[][] publicProject_forceAuth_accessGranted() {
return new Object[][] {
// public project, force auth : works depending on token's validity
};
}
- @Test
- @UseDataProvider("publicProject_forceAuth_accessGranted")
- public void badge_accessible_on_private_project_with_token(boolean publicProject, boolean forceAuth,
+ @ParameterizedTest
+ @MethodSource("publicProject_forceAuth_accessGranted")
+ void badge_accessible_on_private_project_with_token(boolean publicProject, boolean forceAuth,
boolean validToken, boolean accessGranted) throws ParseException {
ProjectData project = publicProject ? db.components().insertPublicProject() : db.components().insertPrivateProject();
userSession.registerProjects(project.getProjectDto());
}
@Test
- public void return_error_on_provisioned_project() throws ParseException {
+ void return_error_on_provisioned_project() throws ParseException {
ProjectDto project = db.components().insertPublicProject().getProjectDto();
userSession.registerProjects(project);
}
@Test
- public void fail_on_invalid_quality_gate() {
+ void fail_on_invalid_quality_gate() {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void error_when_measure_not_found() throws ParseException {
+ void error_when_measure_not_found() {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void fail_when_metric_not_found() {
+ void fail_when_metric_not_found() {
ProjectData projectData = db.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
}
@Test
- public void test_definition() {
+ void test_definition() {
WebService.Action def = ws.getDef();
assertThat(def.key()).isEqualTo("measure");
assertThat(def.isInternal()).isFalse();
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.sonar.server.telemetry;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
+import org.sonar.telemetry.core.Dimension;
+import org.sonar.telemetry.core.Granularity;
+import org.sonar.telemetry.core.TelemetryDataType;
+
+public class TelemetryBadgeProvider extends AbstractTelemetryDataProvider<Integer> {
+ private final Map<String, Integer> badgesCounters = new HashMap<>();
+
+ public TelemetryBadgeProvider() {
+ super("project_badges_count", Dimension.INSTALLATION, Granularity.ADHOC, TelemetryDataType.INTEGER);
+ }
+
+ @Override
+ public Map<String, Integer> getValues() {
+ return badgesCounters;
+ }
+
+ @Override
+ public void after() {
+ badgesCounters.clear();
+ }
+
+ public void incrementForMetric(String metricKey) {
+ badgesCounters.merge(metricKey, 1, Integer::sum);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.sonar.server.telemetry;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.telemetry.core.Dimension;
+import org.sonar.telemetry.core.Granularity;
+import org.sonar.telemetry.core.TelemetryDataType;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class TelemetryBadgeProviderTest {
+
+ @Test
+ void testGetters() {
+ TelemetryBadgeProvider underTest = new TelemetryBadgeProvider();
+
+ underTest.incrementForMetric("bugs");
+ underTest.incrementForMetric("code_smells");
+ underTest.incrementForMetric("code_smells");
+ underTest.incrementForMetric("code_smells");
+
+ assertThat(underTest.getMetricKey()).isEqualTo("project_badges_count");
+ assertThat(underTest.getGranularity()).isEqualTo(Granularity.ADHOC);
+ assertThat(underTest.getDimension()).isEqualTo(Dimension.INSTALLATION);
+ assertThat(underTest.getType()).isEqualTo(TelemetryDataType.INTEGER);
+ assertThat(underTest.getValue()).isEmpty();
+ assertThat(underTest.getValues()).hasSize(2);
+ assertThat(underTest.getValues()).containsEntry("bugs", 1);
+ assertThat(underTest.getValues()).containsEntry("code_smells", 3);
+
+ underTest.after();
+
+ assertTrue(underTest.getValues().isEmpty());
+ }
+
+}