import org.sonar.core.util.Uuids;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.KeyType;
import static java.util.Collections.singletonList;
+import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
public class LiveMeasureDao implements Dao {
mapper(dbSession).selectTreeByQuery(query, baseComponent.uuid(), query.getUuidPath(baseComponent), resultHandler);
}
+ /**
+ * Example:
+ * If Main Branch = 0 LOCs (provisioned but never analyzed) and the "largest long-lived branch" is 120 LOCs, I'm expecting to consider the value 120.
+ * If Main Branch = 100 LOCs and the "largest long-lived branch" is 120 LOCs, I'm expecting to consider the value 120.
+ * If Main Branch = 100 LOCs and the "largest long-lived branch" is 80 LOCs, I'm expecting to consider the value 100.
+ */
+ public long sumNclocOfBiggestLongLivingBranch(DbSession dbSession) {
+ Long ncloc = mapper(dbSession).sumNclocOfBiggestLongLivingBranch(NCLOC_KEY, KeyType.BRANCH, BranchType.LONG);
+ return ncloc == null ? 0L : ncloc;
+ }
+
public void insert(DbSession dbSession, LiveMeasureDto dto) {
mapper(dbSession).insert(dto, Uuids.create(), null, system2.now());
}
import javax.annotation.Nullable;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ResultHandler;
+import org.sonar.db.component.BranchType;
+import org.sonar.db.component.KeyType;
public interface LiveMeasureMapper {
@Param("baseUuidPath") String baseUuidPath,
ResultHandler<LiveMeasureDto> resultHandler);
+ Long sumNclocOfBiggestLongLivingBranch(
+ @Param("ncloc") String nclocKey,
+ @Param("branch") KeyType branchOrPullRequest,
+ @Param("branchType") BranchType branchType);
+
void insert(
@Param("dto") LiveMeasureDto dto,
@Param("uuid") String uuid,
</foreach>
</select>
+ <select id="sumNclocOfBiggestLongLivingBranch" parameterType="map" resultType="long">
+ select sum(sumncloc.maxncloc) from (
+ select b.project_uuid as projectUuid, max(lm.value) as maxncloc
+ from live_measures lm
+ inner join metrics m on m.id = lm.metric_id
+ inner join projects p on p.uuid = lm.component_uuid
+ inner join project_branches b on b.uuid = p.uuid
+ where
+ m.name = #{ncloc, jdbcType=VARCHAR}
+ and p.enabled = ${_true}
+ and p.scope = 'PRJ'
+ and p.qualifier = 'TRK'
+ and p.copy_component_uuid is null
+ and b.branch_type = #{branchType, jdbcType=VARCHAR}
+ and b.key_type = #{branch, jdbcType=VARCHAR}
+ group by b.project_uuid
+ ) sumncloc
+ </select>
+
<insert id="insert" parameterType="map" useGeneratedKeys="false">
insert into live_measures (
uuid,
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
+import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.metric.MetricDto;
+import org.sonar.db.organization.OrganizationDto;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
+import static org.sonar.api.measures.Metric.ValueType.INT;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.measure.MeasureTesting.newLiveMeasure;
}
@Test
- public void test_selectByComponentUuidsAndMetricIds() {
+ public void selectByComponentUuidsAndMetricIds() {
LiveMeasureDto measure1 = newLiveMeasure().setMetricId(metric.getId());
LiveMeasureDto measure2 = newLiveMeasure().setMetricId(metric.getId());
underTest.insert(db.getSession(), measure1);
}
@Test
- public void test_selectByComponentUuidsAndMetricKeys() {
+ public void selectByComponentUuidsAndMetricKeys() {
LiveMeasureDto measure1 = newLiveMeasure().setMetricId(metric.getId());
LiveMeasureDto measure2 = newLiveMeasure().setMetricId(metric.getId());
underTest.insert(db.getSession(), measure1);
}
@Test
- public void test_selectMeasure() {
+ public void selectMeasure() {
MetricDto metric = db.measures().insertMetric();
LiveMeasureDto stored = newLiveMeasure().setMetricId(metric.getId());
underTest.insert(db.getSession(), stored);
.contains(project.uuid(), file.uuid(), metric.getId(), 3.14, 0.1, "text_value", "text_value");
}
+ @Test
+ public void countNcloc() {
+ OrganizationDto organization = db.organizations().insert();
+ MetricDto ncloc = db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.toString()));
+ MetricDto lines = db.measures().insertMetric(m -> m.setKey("lines").setValueType(INT.toString()));
+
+ ComponentDto simpleProject = db.components().insertMainBranch(organization);
+ db.measures().insertLiveMeasure(simpleProject, ncloc, m -> m.setValue(10d));
+
+ ComponentDto projectWithBiggerLongLivingBranch = db.components().insertMainBranch(organization);
+ ComponentDto bigLongLivingBranch = db.components().insertProjectBranch(projectWithBiggerLongLivingBranch, b -> b.setBranchType(BranchType.LONG));
+ db.measures().insertLiveMeasure(projectWithBiggerLongLivingBranch, ncloc, m -> m.setValue(100d));
+ db.measures().insertLiveMeasure(bigLongLivingBranch, ncloc, m -> m.setValue(200d));
+
+ ComponentDto projectWithLinesButNoLoc = db.components().insertMainBranch(organization);
+ db.measures().insertLiveMeasure(projectWithLinesButNoLoc, lines, m -> m.setValue(365d));
+ db.measures().insertLiveMeasure(projectWithLinesButNoLoc, ncloc, m -> m.setValue(0d));
+
+ long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession());
+
+ assertThat(result).isEqualTo(10L + 200L);
+ }
+
+ @Test
+ public void countNcloc_empty() {
+ db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.toString()));
+ db.measures().insertMetric(m -> m.setKey("lines").setValueType(INT.toString()));
+
+ long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession());
+
+ assertThat(result).isEqualTo(0L);
+ }
+
@Test
public void insert_data() {
byte[] data = "text_value".getBytes(StandardCharsets.UTF_8);
}
@Test
- public void test_insertOrUpdate() {
+ public void insertOrUpdate() {
// insert
LiveMeasureDto dto = newLiveMeasure();
underTest.insertOrUpdate(db.getSession(), dto, "foo");
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.qa.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+
+import static java.util.Arrays.asList;
+
+public class XooProjectBuilder {
+ private final String key;
+ private final List<String> moduleKeys = new ArrayList<>();
+ private int filesPerModule = 1;
+ private Properties projectProperties = new Properties();
+
+ public XooProjectBuilder(String projectKey) {
+ this.key = projectKey;
+ }
+
+ public XooProjectBuilder addModules(String key, String... otherKeys) {
+ this.moduleKeys.add(key);
+ this.moduleKeys.addAll(asList(otherKeys));
+ return this;
+ }
+
+ public XooProjectBuilder setFilesPerModule(int i) {
+ this.filesPerModule = i;
+ return this;
+ }
+
+ public XooProjectBuilder addProjectProperties(String... keyValueProperties) {
+ for (int i = 0; i < keyValueProperties.length; i += 2) {
+ this.projectProperties.setProperty(keyValueProperties[i], keyValueProperties[i + 1]);
+ }
+ return this;
+ }
+
+ public File build(File dir) {
+ for (String moduleKey : moduleKeys) {
+ generateModule(moduleKey, new File(dir, moduleKey), new Properties());
+ }
+ projectProperties.setProperty("sonar.modules", StringUtils.join(moduleKeys, ","));
+ generateModule(key, dir, projectProperties);
+ return dir;
+ }
+
+ private void generateModule(String key, File dir, Properties additionalProps) {
+ try {
+ File sourceDir = new File(dir, "src");
+ FileUtils.forceMkdir(sourceDir);
+ for (int i = 0; i < filesPerModule; i++) {
+ File sourceFile = new File(sourceDir, "File" + i + ".xoo");
+ FileUtils.write(sourceFile, "content of " + sourceFile.getName());
+
+ File measuresFile = new File(sourceFile + ".measures");
+ FileUtils.write(measuresFile, "ncloc:10\n" +
+ "comment_lines:3\n");
+ }
+ Properties props = new Properties();
+ props.setProperty("sonar.projectKey", key);
+ props.setProperty("sonar.projectName", key);
+ props.setProperty("sonar.projectVersion", "1.0");
+ props.setProperty("sonar.sources", sourceDir.getName());
+ props.putAll(additionalProps);
+ File propsFile = new File(dir, "sonar-project.properties");
+ try (OutputStream output = FileUtils.openOutputStream(propsFile)) {
+ props.store(output, "generated");
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.measure.index.ProjectMeasuresIndex;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
import org.sonar.server.user.UserSession;
-import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.Editions.FormDataResponse;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+
public class FormDataAction implements EditionsWsAction {
private final UserSession userSession;
private final Server server;
- private final ProjectMeasuresIndex measuresIndex;
+ private final DbClient dbClient;
- public FormDataAction(UserSession userSession, Server server, ProjectMeasuresIndex measuresIndex) {
+ public FormDataAction(UserSession userSession, Server server, DbClient dbClient) {
this.userSession = userSession;
this.server = server;
- this.measuresIndex = measuresIndex;
+ this.dbClient = dbClient;
}
@Override
.checkLoggedIn()
.checkIsSystemAdministrator();
- String serverId = server.getId();
- long nloc = measuresIndex.searchTelemetryStatistics().getNcloc();
-
FormDataResponse responsePayload = FormDataResponse.newBuilder()
- .setNcloc(nloc)
- .setServerId(serverId)
+ .setNcloc(computeNcloc())
+ .setServerId(server.getId())
.build();
- WsUtils.writeProtobuf(responsePayload, request, response);
+ writeProtobuf(responsePayload, request, response);
+ }
+
+ private long computeNcloc() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ return dbClient.liveMeasureDao().sumNclocOfBiggestLongLivingBranch(dbSession);
+ }
}
}
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY;
-import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
import static org.sonar.api.measures.CoreMetrics.NEW_COVERAGE_KEY;
import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_TAGS;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.MAX_PAGE_SIZE;
-@ComputeEngineSide
@ServerSide
+@ComputeEngineSide
public class ProjectMeasuresIndex {
public static final List<String> SUPPORTED_FACETS = ImmutableList.of(
.order(Terms.Order.count(false))
.subAggregation(sum(FIELD_DISTRIB_NCLOC).field(FIELD_DISTRIB_NCLOC))));
- Stream.of(LINES_KEY, NCLOC_KEY)
- .forEach(metric -> request.addAggregation(AggregationBuilders.nested(metric, FIELD_MEASURES)
- .subAggregation(AggregationBuilders.filter(metric + "_filter", termQuery(FIELD_MEASURES_KEY, metric))
- .subAggregation(sum(metric + "_filter_sum").field(FIELD_MEASURES_VALUE)))));
+ request.addAggregation(AggregationBuilders.nested(NCLOC_KEY, FIELD_MEASURES)
+ .subAggregation(AggregationBuilders.filter(NCLOC_KEY + "_filter", termQuery(FIELD_MEASURES_KEY, NCLOC_KEY))
+ .subAggregation(sum(NCLOC_KEY + "_filter_sum").field(FIELD_MEASURES_VALUE))));
ProjectMeasuresStatistics.Builder statistics = ProjectMeasuresStatistics.builder();
SearchResponse response = request.get();
statistics.setProjectCount(response.getHits().getTotalHits());
- Stream.of(LINES_KEY, NCLOC_KEY)
+ Stream.of(NCLOC_KEY)
.map(metric -> (Nested) response.getAggregations().get(metric))
.map(nested -> (Filter) nested.getAggregations().get(nested.getName() + "_filter"))
.map(filter -> (Sum) filter.getAggregations().get(filter.getName() + "_sum"))
import java.util.Map;
import static java.util.Objects.requireNonNull;
-import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
public class ProjectMeasuresStatistics {
private final long projectCount;
- private final long lines;
private final long ncloc;
private final Map<String, Long> projectCountByLanguage;
private final Map<String, Long> nclocByLanguage;
private ProjectMeasuresStatistics(Builder builder) {
projectCount = builder.projectCount;
- lines = builder.lines;
ncloc = builder.ncloc;
projectCountByLanguage = builder.projectCountByLanguage;
nclocByLanguage = builder.nclocByLanguage;
return projectCount;
}
- public long getLines() {
- return lines;
- }
-
+ /**
+ * @deprecated since 7.2 Global Ncloc computation should rely on org.sonar.db.measure.LiveMeasureDao#countNcloc(org.sonar.db.DbSession)
+ */
+ @Deprecated
public long getNcloc() {
return ncloc;
}
public static class Builder {
private Long projectCount;
- private Long lines;
private Long ncloc;
private Map<String, Long> projectCountByLanguage;
private Map<String, Long> nclocByLanguage;
}
public Builder setSum(String metric, long value) {
- switch (metric) {
- case LINES_KEY:
- this.lines = value;
- break;
- case NCLOC_KEY:
- this.ncloc = value;
- break;
- default:
- throw new IllegalStateException("Metric not supported: " + metric);
+ if (NCLOC_KEY.equals(metric)) {
+ this.ncloc = value;
+ } else {
+ throw new IllegalStateException("Metric not supported: " + metric);
}
return this;
}
public ProjectMeasuresStatistics build() {
requireNonNull(projectCount);
- requireNonNull(lines);
requireNonNull(ncloc);
requireNonNull(projectCountByLanguage);
requireNonNull(nclocByLanguage);
private final String serverId;
private final String version;
private final Map<String, String> plugins;
- private final long lines;
private final long ncloc;
private final long userCount;
private final long projectCount;
serverId = builder.serverId;
version = builder.version;
plugins = builder.plugins;
- lines = builder.projectMeasuresStatistics.getLines();
- ncloc = builder.projectMeasuresStatistics.getNcloc();
+ ncloc = builder.ncloc;
userCount = builder.userCount;
projectCount = builder.projectMeasuresStatistics.getProjectCount();
usingBranches = builder.usingBranches;
return plugins;
}
- public long getLines() {
- return lines;
- }
-
public long getNcloc() {
return ncloc;
}
private Map<String, String> plugins;
private Database database;
private ProjectMeasuresStatistics projectMeasuresStatistics;
+ private Long ncloc;
private Boolean usingBranches;
private Builder() {
return this;
}
- void setUserCount(long userCount) {
+ Builder setUserCount(long userCount) {
this.userCount = userCount;
+ return this;
}
- void setPlugins(Map<String, String> plugins) {
+ Builder setPlugins(Map<String, String> plugins) {
this.plugins = plugins;
+ return this;
}
- void setProjectMeasuresStatistics(ProjectMeasuresStatistics projectMeasuresStatistics) {
+ Builder setProjectMeasuresStatistics(ProjectMeasuresStatistics projectMeasuresStatistics) {
this.projectMeasuresStatistics = projectMeasuresStatistics;
+ return this;
+ }
+
+ Builder setNcloc(long ncloc) {
+ this.ncloc = ncloc;
+ return this;
}
Builder setDatabase(Database database) {
requireNonNull(version);
requireNonNull(plugins);
requireNonNull(projectMeasuresStatistics);
+ requireNonNull(ncloc);
requireNonNull(database);
requireNonNull(usingBranches);
import org.sonar.api.utils.text.JsonWriter;
-import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
public class TelemetryDataJsonWriter {
json.prop("userCount", statistics.getUserCount());
json.prop("projectCount", statistics.getProjectCount());
json.prop("usingBranches", statistics.isUsingBranches());
- json.prop(LINES_KEY, statistics.getLines());
json.prop(NCLOC_KEY, statistics.getNcloc());
json.name("projectCountByLanguage");
json.beginArray();
import java.sql.SQLException;
import java.util.Map;
import java.util.function.Function;
+import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.platform.Server;
import org.sonar.api.server.ServerSide;
import org.sonar.core.platform.PluginInfo;
import org.sonar.server.user.index.UserIndex;
import org.sonar.server.user.index.UserQuery;
+@ComputeEngineSide
@ServerSide
public class TelemetryDataLoader {
private final Server server;
try (DbSession dbSession = dbClient.openSession(false)) {
data.setDatabase(loadDatabaseMetadata(dbSession));
data.setUsingBranches(dbClient.branchDao().hasNonMainBranches(dbSession));
+ data.setNcloc(dbClient.liveMeasureDao().sumNclocOfBiggestLongLivingBranch(dbSession));
}
return data.build();
*/
package org.sonar.server.edition.ws;
-import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import java.io.IOException;
-import java.util.Arrays;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.api.platform.Server;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.edition.EditionManagementState;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.metric.MetricDto;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.measure.index.ProjectMeasuresIndex;
-import org.sonar.server.measure.index.ProjectMeasuresStatistics;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
-import org.sonar.test.JsonAssert;
-import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.Editions.FormDataResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE;
+import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
+import static org.sonar.api.measures.Metric.ValueType.INT;
+import static org.sonar.test.JsonAssert.assertJson;
@RunWith(DataProviderRunner.class)
public class FormDataActionTest {
+
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ @Rule
+ public DbTester db = DbTester.create();
private Server server = mock(Server.class);
- private ProjectMeasuresStatistics stats = mock(ProjectMeasuresStatistics.class);
- private ProjectMeasuresIndex measuresIndex = mock(ProjectMeasuresIndex.class);
- private FormDataAction underTest = new FormDataAction(userSessionRule, server, measuresIndex);
- private WsActionTester actionTester = new WsActionTester(underTest);
-
- @Before
- public void setUp() {
- when(measuresIndex.searchTelemetryStatistics()).thenReturn(stats);
- }
+ private DbClient dbClient = db.getDbClient();
+ private FormDataAction underTest = new FormDataAction(userSessionRule, server, dbClient);
+
+ private WsActionTester ws = new WsActionTester(underTest);
@Test
- public void verify_definition() {
- WebService.Action def = actionTester.getDef();
+ public void definition() {
+ WebService.Action def = ws.getDef();
assertThat(def.key()).isEqualTo("form_data");
assertThat(def.since()).isEqualTo("6.7");
@Test
public void request_fails_if_user_not_logged_in() {
userSessionRule.anonymous();
- TestRequest request = actionTester.newRequest();
+ TestRequest request = ws.newRequest();
expectedException.expect(UnauthorizedException.class);
expectedException.expectMessage("Authentication is required");
@Test
public void request_fails_if_user_is_not_system_administer() {
userSessionRule.logIn();
- TestRequest request = actionTester.newRequest();
+ TestRequest request = ws.newRequest();
expectedException.expect(ForbiddenException.class);
expectedException.expectMessage("Insufficient privileges");
}
@Test
- public void verify_example() {
+ public void json_example() {
userSessionRule.logIn().setSystemAdministrator();
when(server.getId()).thenReturn("uuid");
- when(stats.getNcloc()).thenReturn(12345L);
+ setNcloc(12345L);
- TestRequest request = actionTester.newRequest();
+ String result = ws.newRequest().execute().getInput();
- JsonAssert.assertJson(request.execute().getInput()).isSimilarTo(actionTester.getDef().responseExampleAsString());
+ assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString());
}
@Test
- public void returns_server_id_and_nloc() throws IOException {
+ public void returns_server_id_and_nloc() {
userSessionRule.logIn().setSystemAdministrator();
when(server.getId()).thenReturn("myserver");
- when(stats.getNcloc()).thenReturn(1000L);
+ long ncloc = 256L;
+ setNcloc(ncloc);
FormDataResponse expectedResponse = FormDataResponse.newBuilder()
.setServerId("myserver")
- .setNcloc(1000L)
+ .setNcloc(ncloc)
.build();
- TestRequest request = actionTester.newRequest().setMediaType(MediaTypes.PROTOBUF);
+ FormDataResponse result = ws.newRequest().executeProtobuf(FormDataResponse.class);
- assertThat(FormDataResponse.parseFrom(request.execute().getInputStream())).isEqualTo(expectedResponse);
+ assertThat(result).isEqualTo(expectedResponse);
}
- @DataProvider
- public static Object[][] notNonePendingInstallationStatuses() {
- return Arrays.stream(EditionManagementState.PendingStatus.values())
- .filter(s -> s != NONE)
- .map(s -> new Object[] {s})
- .toArray(Object[][]::new);
+ private void setNcloc(double ncloc) {
+ ComponentDto project = db.components().insertMainBranch();
+ MetricDto nclocMetric = db.measures().insertMetric(m -> m.setValueType(INT.toString()).setKey(NCLOC_KEY));
+ db.measures().insertLiveMeasure(project, nclocMetric, m -> m.setValue(ncloc));
}
}
@Test
public void search_statistics() {
es.putDocuments(INDEX_TYPE_PROJECT_MEASURES,
- newDoc("lines", 10, "ncloc", 20, "coverage", 80)
+ newDoc("lines", 10, "coverage", 80)
.setLanguages(Arrays.asList("java", "cs", "js"))
.setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 200, "cs", 250, "js", 50)),
- newDoc("lines", 20, "ncloc", 30, "coverage", 80)
+ newDoc("lines", 20, "coverage", 80)
.setLanguages(Arrays.asList("java", "python", "kotlin"))
.setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 300, "python", 100, "kotlin", 404)));
ProjectMeasuresStatistics result = underTest.searchTelemetryStatistics();
assertThat(result.getProjectCount()).isEqualTo(2);
- assertThat(result.getLines()).isEqualTo(30);
- assertThat(result.getNcloc()).isEqualTo(50);
assertThat(result.getProjectCountByLanguage()).containsOnly(
entry("java", 2L), entry("cs", 1L), entry("js", 1L), entry("python", 1L), entry("kotlin", 1L));
assertThat(result.getNclocByLanguage()).containsOnly(
+ "\"Application Nodes\":[{\"Name\":\"appNodes\",\"\":{\"name\":\"appNodes\"}}],"
+ "\"Search Nodes\":[{\"Name\":\"searchNodes\",\"\":{\"name\":\"searchNodes\"}}],"
+ "\"Statistics\":{\"id\":\"\",\"version\":\"\",\"database\":{\"name\":\"\",\"version\":\"\"},\"plugins\":[],"
- + "\"userCount\":0,\"projectCount\":0,\"usingBranches\":false,\"lines\":0,\"ncloc\":0,\"projectCountByLanguage\":[],\"nclocByLanguage\":[]}}");
+ + "\"userCount\":0,\"projectCount\":0,\"usingBranches\":false,\"ncloc\":0,\"projectCountByLanguage\":[],\"nclocByLanguage\":[]}}");
}
private static NodeInfo createNodeInfo(String name) {
// response does not contain empty "Section Three"
assertThat(writer.toString()).isEqualTo("{\"Health\":\"GREEN\",\"Health Causes\":[],\"Section One\":{\"foo\":\"bar\"},\"Section Two\":{\"one\":1,\"two\":2}," +
"\"Statistics\":{\"id\":\"\",\"version\":\"\",\"database\":{\"name\":\"\",\"version\":\"\"},\"plugins\":[],\"userCount\":0,\"projectCount\":0,\"usingBranches\":false," +
- "\"lines\":0,\"ncloc\":0,\"projectCountByLanguage\":[],\"nclocByLanguage\":[]}}");
+ "\"ncloc\":0,\"projectCountByLanguage\":[],\"nclocByLanguage\":[]}}");
}
private void logInAsSystemAdministrator() {
}
@Test
- public void exclude_branches() throws IOException {
+ public void take_biggest_long_living_branches() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
server.setId("AU-TpxcB-iU5OvuD2FL7").setVersion("7.5.4");
ArgumentCaptor<String> jsonCaptor = ArgumentCaptor.forClass(String.class);
verify(client, timeout(2_000).atLeastOnce()).upload(jsonCaptor.capture());
assertJson(jsonCaptor.getValue()).isSimilarTo("{\n" +
- " \"ncloc\": 10\n" +
+ " \"ncloc\": 20\n" +
"}\n");
}
"userCount": 3,
"projectCount": 2,
"usingBranches": true,
- "lines": 500,
"ncloc": 300,
"projectCountByLanguage": [
{
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.qa.util.XooProjectBuilder;
import org.sonarqube.tests.Category4Suite;
import org.sonarqube.ws.Ce;
import org.sonarqube.ws.client.ce.ActivityStatusRequest;
-import util.XooProjectBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.qa.util.XooProjectBuilder;
import org.sonarqube.ws.client.components.ShowRequest;
import org.sonarqube.ws.client.components.TreeRequest;
import org.sonarqube.ws.client.projects.UpdateKeyRequest;
-import util.XooProjectBuilder;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.qa.util.XooProjectBuilder;
import org.sonarqube.ws.Components.Component;
import org.sonarqube.ws.Organizations;
import org.sonarqube.ws.client.components.ShowRequest;
-import util.XooProjectBuilder;
import static org.apache.commons.lang.StringUtils.repeat;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.qa.util.XooProjectBuilder;
import org.sonarqube.ws.Components;
import org.sonarqube.ws.Organizations;
import org.sonarqube.ws.Projects;
import org.sonarqube.ws.client.projects.BulkUpdateKeyRequest;
import org.sonarqube.ws.client.projects.UpdateKeyRequest;
import util.ItUtils;
-import util.XooProjectBuilder;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.qa.util.XooProjectBuilder;
import org.sonarqube.ws.Ce;
import org.sonarqube.ws.Projects;
import org.sonarqube.ws.client.ce.ActivityStatusRequest;
import org.sonarqube.ws.client.plugins.UninstallRequest;
import org.sonarqube.ws.client.qualityprofiles.AddProjectRequest;
import util.ItUtils;
-import util.XooProjectBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import static util.ItUtils.newOrchestratorBuilder;
List<String> plugins = ((List<Map<String, String>>) json.get("plugins")).stream().map(p -> p.get("name")).collect(Collectors.toList());
assertThat(plugins).contains("xoo");
assertThat(getInteger(json.get("ncloc"))).isEqualTo(13 * 2 + 7);
- assertThat(getInteger(json.get("lines"))).isEqualTo(17 * 3);
List<Map<String, String>> projectCountByLanguage = (List<Map<String, String>>) json.get("projectCountByLanguage");
assertThat(projectCountByLanguage).extracting(p -> p.get("language"), p -> getInteger(p.get("count")))
.contains(tuple("xoo", 2), tuple("xoo2", 1));
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-
-import static java.util.Arrays.asList;
-
-public class XooProjectBuilder {
- private final String key;
- private final List<String> moduleKeys = new ArrayList<>();
- private int filesPerModule = 1;
-
- public XooProjectBuilder(String projectKey) {
- this.key = projectKey;
- }
-
- public XooProjectBuilder addModules(String key, String... otherKeys) {
- this.moduleKeys.add(key);
- this.moduleKeys.addAll(asList(otherKeys));
- return this;
- }
-
- public XooProjectBuilder setFilesPerModule(int i) {
- this.filesPerModule = i;
- return this;
- }
-
- public File build(File dir) {
- for (String moduleKey : moduleKeys) {
- generateModule(moduleKey, new File(dir, moduleKey), new Properties());
- }
- Properties additionalProps = new Properties();
- additionalProps.setProperty("sonar.modules", StringUtils.join(moduleKeys, ","));
- generateModule(key, dir, additionalProps);
- return dir;
- }
-
- private void generateModule(String key, File dir, Properties additionalProps) {
- try {
- File sourceDir = new File(dir, "src");
- FileUtils.forceMkdir(sourceDir);
- for (int i = 0; i < filesPerModule; i++) {
- File sourceFile = new File(sourceDir, "File" + i + ".xoo");
- FileUtils.write(sourceFile, "content of " + sourceFile.getName());
-
- File measuresFile = new File(sourceFile + ".measures");
- FileUtils.write(measuresFile, "ncloc:10\n" +
- "comment_lines:3\n");
- }
- Properties props = new Properties();
- props.setProperty("sonar.projectKey", key);
- props.setProperty("sonar.projectName", key);
- props.setProperty("sonar.projectVersion", "1.0");
- props.setProperty("sonar.sources", sourceDir.getName());
- props.putAll(additionalProps);
- File propsFile = new File(dir, "sonar-project.properties");
- try (OutputStream output = FileUtils.openOutputStream(propsFile)) {
- props.store(output, "generated");
- }
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-}