package org.sonar.db.ce;
import java.util.Collection;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
-
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
+import static org.sonar.db.DatabaseUtils.executeLargeInputs;
+
public class CeTaskCharacteristicDao implements Dao {
+
public void insert(DbSession dbSession, Collection<CeTaskCharacteristicDto> characteristics) {
for (CeTaskCharacteristicDto dto : characteristics) {
mapper(dbSession).insert(dto);
}
}
- public Map<String, String> getTaskCharacteristics(DbSession dbSession, String taskUuid) {
- Map<String, String> map = new LinkedHashMap<>();
- List<CeTaskCharacteristicDto> characteristics = mapper(dbSession).selectTaskCharacteristics(taskUuid);
- characteristics.stream().forEach(dto -> map.put(dto.getKey(), dto.getValue()));
- return map;
+ public List<CeTaskCharacteristicDto> selectByTaskUuid(DbSession dbSession, String taskUuid) {
+ return mapper(dbSession).selectByTaskUuid(taskUuid);
+ }
+
+ public List<CeTaskCharacteristicDto> selectByTaskUuids(DbSession dbSession, List<String> taskUuids) {
+ return executeLargeInputs(taskUuids, uuid -> mapper(dbSession).selectByTaskUuids(uuid));
}
private static CeTaskCharacteristicMapper mapper(DbSession session) {
package org.sonar.db.ce;
public class CeTaskCharacteristicDto {
+
+ public static final String INCREMENTAL_KEY = "incremental";
+
private String uuid;
private String taskUuid;
private String key;
return uuid;
}
- public void setUuid(String uuid) {
+ public CeTaskCharacteristicDto setUuid(String uuid) {
this.uuid = uuid;
+ return this;
}
public String getTaskUuid() {
return taskUuid;
}
- public void setTaskUuid(String taskUuid) {
+ public CeTaskCharacteristicDto setTaskUuid(String taskUuid) {
this.taskUuid = taskUuid;
+ return this;
}
public String getKey() {
return key;
}
- public void setKey(String key) {
+ public CeTaskCharacteristicDto setKey(String key) {
this.key = key;
+ return this;
}
public String getValue() {
return value;
}
- public void setValue(String value) {
+ public CeTaskCharacteristicDto setValue(String value) {
this.value = value;
+ return this;
}
}
package org.sonar.db.ce;
import java.util.List;
-
import org.apache.ibatis.annotations.Param;
public interface CeTaskCharacteristicMapper {
- List<CeTaskCharacteristicDto> selectTaskCharacteristics(@Param("taskUuid") String taskUuid);
+
+ List<CeTaskCharacteristicDto> selectByTaskUuid(@Param("taskUuid") String taskUuid);
+
+ List<CeTaskCharacteristicDto> selectByTaskUuids(@Param("taskUuids") List<String> taskUuids);
void insert(CeTaskCharacteristicDto taskCharacteristic);
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
<mapper namespace="org.sonar.db.ce.CeTaskCharacteristicMapper">
- <insert id="insert" parameterType="CeTaskCharacteristic" useGeneratedKeys="false">
- insert into ce_task_characteristics (
- uuid,
- task_uuid,
- kee,
- text_value
- )
- values (
- #{uuid,jdbcType=VARCHAR},
- #{taskUuid,jdbcType=VARCHAR},
- #{key,jdbcType=VARCHAR},
- #{value,jdbcType=VARCHAR}
- )
- </insert>
-
- <select id="selectTaskCharacteristics" parameterType="map" resultType="CeTaskCharacteristic">
+
+ <sql id="columns">
+ c.uuid as "uuid",
+ c.task_uuid as "taskUuid",
+ c.kee as "key",
+ c.text_value as "value"
+ </sql>
+
+ <select id="selectByTaskUuid" parameterType="map" resultType="CeTaskCharacteristic">
SELECT
- c.uuid as "uuid",
- c.task_uuid as "taskUuid",
- c.kee as "key",
- c.text_value as "value"
+ <include refid="columns"/>
FROM
ce_task_characteristics c
WHERE
c.task_uuid = #{taskUuid,jdbcType=VARCHAR}
</select>
+
+ <select id="selectByTaskUuids" parameterType="map" resultType="CeTaskCharacteristic">
+ SELECT
+ <include refid="columns"/>
+ FROM
+ ce_task_characteristics c
+ WHERE
+ c.task_uuid in <foreach collection="taskUuids" open="(" close=")" item="taskUuid" separator=",">#{taskUuid,jdbcType=VARCHAR}</foreach>
+ </select>
+
+ <insert id="insert" parameterType="CeTaskCharacteristic" useGeneratedKeys="false">
+ insert into ce_task_characteristics (
+ uuid,
+ task_uuid,
+ kee,
+ text_value
+ )
+ values (
+ #{uuid,jdbcType=VARCHAR},
+ #{taskUuid,jdbcType=VARCHAR},
+ #{key,jdbcType=VARCHAR},
+ #{value,jdbcType=VARCHAR}
+ )
+ </insert>
+
</mapper>
*/
package org.sonar.db.ce;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-
-import java.util.Collections;
-
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+
public class CeTaskCharacteristicDaoTest {
@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE);
private CeTaskCharacteristicDao underTest = new CeTaskCharacteristicDao();
@Test
- public void test_insert() {
- CeTaskCharacteristicDto dto = new CeTaskCharacteristicDto();
- dto.setKey("key");
- dto.setValue("value");
- dto.setUuid("uuid");
- dto.setTaskUuid("task");
- underTest.insert(dbTester.getSession(), Collections.singletonList(dto));
+ public void selectByTaskUuid() {
+ CeTaskCharacteristicDto dto1 = new CeTaskCharacteristicDto()
+ .setKey("key1")
+ .setValue("value1")
+ .setUuid("uuid1")
+ .setTaskUuid("task");
+ CeTaskCharacteristicDto dto2 = new CeTaskCharacteristicDto()
+ .setKey("key2")
+ .setValue("value2")
+ .setUuid("uuid2")
+ .setTaskUuid("task");
+ underTest.insert(dbTester.getSession(), asList(dto1, dto2));
dbTester.getSession().commit();
- assertThat(underTest.getTaskCharacteristics(dbTester.getSession(), "task")).containsOnly(entry("key", "value"));
+ assertThat(underTest.selectByTaskUuid(dbTester.getSession(), "task"))
+ .extracting(CeTaskCharacteristicDto::getTaskUuid, CeTaskCharacteristicDto::getUuid, CeTaskCharacteristicDto::getKey, CeTaskCharacteristicDto::getValue)
+ .containsOnly(
+ tuple("task", "uuid1", "key1", "value1"),
+ tuple("task", "uuid2", "key2", "value2"));
+ assertThat(underTest.selectByTaskUuid(dbTester.getSession(), "unknown")).isEmpty();
}
@Test
- public void test_no_result() {
- assertThat(underTest.getTaskCharacteristics(dbTester.getSession(), "task")).isEmpty();
+ public void selectByTaskUuids() {
+ CeTaskCharacteristicDto dto1 = new CeTaskCharacteristicDto()
+ .setKey("key1")
+ .setValue("value1")
+ .setUuid("uuid1")
+ .setTaskUuid("task1");
+ CeTaskCharacteristicDto dto2 = new CeTaskCharacteristicDto()
+ .setKey("key2")
+ .setValue("value2")
+ .setUuid("uuid2")
+ .setTaskUuid("task2");
+ underTest.insert(dbTester.getSession(), asList(dto1, dto2));
+ dbTester.getSession().commit();
+ assertThat(underTest.selectByTaskUuids(dbTester.getSession(), asList("task1", "task2")))
+ .extracting(CeTaskCharacteristicDto::getTaskUuid, CeTaskCharacteristicDto::getUuid, CeTaskCharacteristicDto::getKey, CeTaskCharacteristicDto::getValue)
+ .containsOnly(
+ tuple("task1", "uuid1", "key1", "value1"),
+ tuple("task2", "uuid2", "key2", "value2"));
+ assertThat(underTest.selectByTaskUuids(dbTester.getSession(), singletonList("unknown"))).isEmpty();
}
+
}
}
java.util.Optional<CeActivityDto> activity = dbClient.ceActivityDao().selectByUuid(dbSession, textQuery);
- return activity.map(ceActivityDto -> Optional.of(formatter.formatActivity(dbSession, ceActivityDto))).orElseGet(Optional::absent);
-
+ return activity.map(ceActivityDto -> Optional.of(formatter.formatActivity(dbSession, ceActivityDto, null))).orElseGet(Optional::absent);
}
private CeTaskQuery buildQuery(DbSession dbSession, ActivityWsRequest request, @Nullable ComponentDto component) {
package org.sonar.server.ce.ws;
import java.util.List;
+import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
WebService.NewAction action = controller.createAction("component")
.setDescription("Get the pending tasks, in-progress tasks and the last executed task of a given component (usually a project).<br>" +
"Requires the following permission: 'Browse' on the specified component.<br>" +
- "Either '%s' or '%s' must be provided, not both.<br>" +
- "Since 6.1, field \"logs\" is deprecated and its value is always false.",
+ "Either '%s' or '%s' must be provided, not both.",
PARAM_COMPONENT_ID, PARAM_COMPONENT_KEY)
.setSince("5.2")
.setResponseExample(getClass().getResource("component-example.json"))
+ .setChangelog(
+ new Change("6.1", "field \"logs\" is deprecated and its value is always false"),
+ new Change("6.6", "field \"incremental\" is added"))
.setHandler(this);
action.createParam(PARAM_COMPONENT_ID)
ProjectResponse.Builder wsResponseBuilder = ProjectResponse.newBuilder();
wsResponseBuilder.addAllQueue(formatter.formatQueue(dbSession, queueDtos));
if (activityDtos.size() == 1) {
- wsResponseBuilder.setCurrent(formatter.formatActivity(dbSession, activityDtos.get(0)));
+ wsResponseBuilder.setCurrent(formatter.formatActivity(dbSession, activityDtos.get(0), null));
}
writeProtobuf(wsResponseBuilder.build(), wsRequest, wsResponse);
}
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
"Since 6.1, field \"logs\" is deprecated and its value is always false.")
.setResponseExample(getClass().getResource("task-example.json"))
.setSince("5.2")
+ .setChangelog(new Change("6.6", "field \"incremental\" is added"))
.setHandler(this);
action
if (queueDto.isPresent()) {
com.google.common.base.Optional<ComponentDto> component = loadComponent(dbSession, queueDto.get().getComponentUuid());
checkPermission(component);
- wsTaskResponse.setTask(wsTaskFormatter.formatQueue(dbSession, queueDto.get(), component));
+ wsTaskResponse.setTask(wsTaskFormatter.formatQueue(dbSession, queueDto.get()));
} else {
CeActivityDto ceActivityDto = WsUtils.checkFoundWithOptional(dbClient.ceActivityDao().selectByUuid(dbSession, taskUuid), "No activity found for task '%s'", taskUuid);
com.google.common.base.Optional<ComponentDto> component = loadComponent(dbSession, ceActivityDto.getComponentUuid());
Set<AdditionalField> additionalFields = AdditionalField.getFromRequest(wsRequest);
maskErrorStacktrace(ceActivityDto, additionalFields);
wsTaskResponse.setTask(
- wsTaskFormatter.formatActivity(dbSession, ceActivityDto, component, extractScannerContext(dbSession, ceActivityDto, additionalFields)));
+ wsTaskFormatter.formatActivity(dbSession, ceActivityDto, extractScannerContext(dbSession, ceActivityDto, additionalFields)));
}
writeProtobuf(wsTaskResponse.build(), wsRequest, wsResponse);
}
*/
package org.sonar.server.ce.ws;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.utils.DateUtils;
import org.sonar.db.DbSession;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonarqube.ws.WsCe;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
-import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.core.util.Protobuf.setNullable;
}
public List<WsCe.Task> formatQueue(DbSession dbSession, List<CeQueueDto> dtos) {
- ComponentDtoCache cache = ComponentDtoCache.forQueueDtos(dbClient, dbSession, dtos);
+ DtoCache cache = DtoCache.forQueueDtos(dbClient, dbSession, dtos);
return dtos.stream().map(input -> formatQueue(input, cache)).collect(MoreCollectors.toList(dtos.size()));
}
public WsCe.Task formatQueue(DbSession dbSession, CeQueueDto queue) {
- return formatQueue(queue, ComponentDtoCache.forQueueDtos(dbClient, dbSession, singletonList(queue)));
+ return formatQueue(queue, DtoCache.forQueueDtos(dbClient, dbSession, singletonList(queue)));
}
- public WsCe.Task formatQueue(DbSession dbSession, CeQueueDto dto, Optional<ComponentDto> component) {
- checkArgument(Objects.equals(dto.getComponentUuid(), component.transform(ComponentDto::uuid).orNull()));
- return formatQueue(dto, ComponentDtoCache.forComponentDto(dbClient, dbSession, component));
- }
-
- private WsCe.Task formatQueue(CeQueueDto dto, ComponentDtoCache componentDtoCache) {
+ private WsCe.Task formatQueue(CeQueueDto dto, DtoCache componentDtoCache) {
WsCe.Task.Builder builder = WsCe.Task.newBuilder();
String organizationKey = componentDtoCache.getOrganizationKey(dto.getComponentUuid());
// FIXME organization field should be set from the CeQueueDto rather than from the ComponentDto
builder.setSubmittedAt(formatDateTime(new Date(dto.getCreatedAt())));
setNullable(dto.getStartedAt(), builder::setStartedAt, DateUtils::formatDateTime);
setNullable(computeExecutionTimeMs(dto), builder::setExecutionTimeMs);
+ builder.setIncremental(componentDtoCache.hasIncrementalCharacteristic(dto.getUuid()));
return builder.build();
}
- public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto activity) {
- return formatActivity(activity, ComponentDtoCache.forActivityDtos(dbClient, dbSession, singletonList(activity)), null);
- }
-
- public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto dto, Optional<ComponentDto> component,
- @Nullable String scannerContext) {
- return formatActivity(dto, ComponentDtoCache.forComponentDto(dbClient, dbSession, component), scannerContext);
+ public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto dto, @Nullable String scannerContext) {
+ return formatActivity(dto, DtoCache.forActivityDtos(dbClient, dbSession, singletonList(dto)), scannerContext);
}
public List<WsCe.Task> formatActivity(DbSession dbSession, List<CeActivityDto> dtos) {
- ComponentDtoCache cache = ComponentDtoCache.forActivityDtos(dbClient, dbSession, dtos);
+ DtoCache cache = DtoCache.forActivityDtos(dbClient, dbSession, dtos);
return dtos.stream()
.map(input -> formatActivity(input, cache, null))
.collect(MoreCollectors.toList(dtos.size()));
}
- private static WsCe.Task formatActivity(CeActivityDto dto, ComponentDtoCache componentDtoCache, @Nullable String scannerContext) {
+ private static WsCe.Task formatActivity(CeActivityDto dto, DtoCache componentDtoCache, @Nullable String scannerContext) {
WsCe.Task.Builder builder = WsCe.Task.newBuilder();
String organizationKey = componentDtoCache.getOrganizationKey(dto.getComponentUuid());
// FIXME organization field should be set from the CeActivityDto rather than from the ComponentDto
String analysisUuid = dto.getAnalysisUuid();
if (analysisUuid != null) {
builder.setAnalysisId(analysisUuid);
- setNullable(componentDtoCache.getAnalysis(analysisUuid), analysis -> builder.setIncremental(analysis.getIncremental()));
}
+ SnapshotDto analysis = analysisUuid == null ? null : componentDtoCache.getAnalysis(analysisUuid);
+ builder.setIncremental(analysis != null && analysis.getIncremental());
setNullable(analysisUuid, builder::setAnalysisId);
setNullable(dto.getSubmitterLogin(), builder::setSubmitterLogin);
builder.setSubmittedAt(formatDateTime(new Date(dto.getSubmittedAt())));
return builder;
}
- private static class ComponentDtoCache {
+ private static class DtoCache {
private final Map<String, ComponentDto> componentsByUuid;
private final Map<String, OrganizationDto> organizationsByUuid;
private final Map<String, SnapshotDto> analysisByUuid;
+ private final Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid;
- private ComponentDtoCache(Map<String, ComponentDto> componentsByUuid, Map<String, OrganizationDto> organizationsByUuid, Map<String, SnapshotDto> analysisByUuid) {
+ private DtoCache(Map<String, ComponentDto> componentsByUuid, Map<String, OrganizationDto> organizationsByUuid, Map<String, SnapshotDto> analysisByUuid,
+ Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid) {
this.componentsByUuid = componentsByUuid;
this.organizationsByUuid = organizationsByUuid;
this.analysisByUuid = analysisByUuid;
+ this.characteristicsByTaskUuid = characteristicsByTaskUuid;
}
- static ComponentDtoCache forQueueDtos(DbClient dbClient, DbSession dbSession, Collection<CeQueueDto> ceQueueDtos) {
+ static DtoCache forQueueDtos(DbClient dbClient, DbSession dbSession, Collection<CeQueueDto> ceQueueDtos) {
Map<String, ComponentDto> componentsByUuid = dbClient.componentDao().selectByUuids(dbSession, uuidOfCeQueueDtos(ceQueueDtos))
.stream()
.collect(MoreCollectors.uniqueIndex(ComponentDto::uuid));
- return new ComponentDtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), Collections.emptyMap());
+ Multimap<String, CeTaskCharacteristicDto> characteristicsByTaskUuid = dbClient.ceTaskCharacteristicsDao()
+ .selectByTaskUuids(dbSession, ceQueueDtos.stream().map(CeQueueDto::getUuid).collect(Collectors.toList()))
+ .stream().collect(MoreCollectors.index(CeTaskCharacteristicDto::getTaskUuid));
+ return new DtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), Collections.emptyMap(), characteristicsByTaskUuid);
}
private static Set<String> uuidOfCeQueueDtos(Collection<CeQueueDto> ceQueueDtos) {
.collect(MoreCollectors.toSet(ceQueueDtos.size()));
}
- static ComponentDtoCache forActivityDtos(DbClient dbClient, DbSession dbSession, Collection<CeActivityDto> ceActivityDtos) {
+ static DtoCache forActivityDtos(DbClient dbClient, DbSession dbSession, Collection<CeActivityDto> ceActivityDtos) {
Map<String, ComponentDto> componentsByUuid = dbClient.componentDao().selectByUuids(
dbSession,
uuidOfCeActivityDtos(ceActivityDtos))
.collect(MoreCollectors.uniqueIndex(ComponentDto::uuid));
Set<String> analysisUuids = ceActivityDtos.stream().map(CeActivityDto::getAnalysisUuid).filter(Objects::nonNull).collect(MoreCollectors.toSet());
Map<String, SnapshotDto> analysisByUuid = dbClient.snapshotDao().selectByUuids(dbSession, analysisUuids).stream().collect(MoreCollectors.uniqueIndex(SnapshotDto::getUuid));
- return new ComponentDtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), analysisByUuid);
+ return new DtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), analysisByUuid,
+ ImmutableMultimap.<String, CeTaskCharacteristicDto>builder().build());
}
private static Set<String> uuidOfCeActivityDtos(Collection<CeActivityDto> ceActivityDtos) {
.collect(MoreCollectors.toSet(ceActivityDtos.size()));
}
- static ComponentDtoCache forComponentDto(DbClient dbClient, DbSession dbSession, Optional<ComponentDto> component) {
- Map<String, ComponentDto> componentsByUuid = component.isPresent() ? ImmutableMap.of(component.get().uuid(), component.get()) : emptyMap();
- return new ComponentDtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), Collections.emptyMap());
- }
-
private static Map<String, OrganizationDto> buildOrganizationsByUuid(DbClient dbClient, DbSession dbSession, Map<String, ComponentDto> componentsByUuid) {
return dbClient.organizationDao().selectByUuids(
dbSession,
SnapshotDto getAnalysis(String analysisUuid) {
return analysisByUuid.get(analysisUuid);
}
+
+ boolean hasIncrementalCharacteristic(String taskUuid) {
+ return characteristicsByTaskUuid.get(taskUuid).stream()
+ .filter(c -> c.getKey().equals(CeTaskCharacteristicDto.INCREMENTAL_KEY))
+ .anyMatch(c -> c.getValue().equals("true"));
+ }
}
/**
package org.sonar.server.ce.ws;
import java.io.IOException;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.ce.taskprocessor.CeTaskProcessor;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeActivityDto.Status;
import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.db.ce.CeActivityDto.Status.FAILED;
import static org.sonar.db.ce.CeActivityDto.Status.SUCCESS;
+import static org.sonar.db.ce.CeQueueDto.Status.IN_PROGRESS;
+import static org.sonar.db.ce.CeQueueDto.Status.PENDING;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.INCREMENTAL_KEY;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT;
ComponentDto project2 = db.components().insertPrivateProject();
insertActivity("T1", project1, SUCCESS);
insertActivity("T2", project2, FAILED);
- insertQueue("T3", project1, CeQueueDto.Status.IN_PROGRESS);
+ insertQueue("T3", project1, IN_PROGRESS);
ActivityResponse activityResponse = call(ws.newRequest()
.setParam("status", "FAILED,IN_PROGRESS"));
ComponentDto project2 = db.components().insertPrivateProject();
insertActivity("T1", project1, SUCCESS);
insertActivity("T2", project2, FAILED);
- insertQueue("T3", project1, CeQueueDto.Status.IN_PROGRESS);
+ insertQueue("T3", project1, IN_PROGRESS);
ActivityResponse activityResponse = call(ws.newRequest()
.setParam("status", "FAILED,IN_PROGRESS,SUCCESS")
// T2 is the current activity (the most recent one)
insertActivity("T1", project, SUCCESS);
insertActivity("T2", project, FAILED);
- insertQueue("T3", project, CeQueueDto.Status.PENDING);
+ insertQueue("T3", project, PENDING);
ActivityResponse activityResponse = call(
ws.newRequest()
ComponentDto project2 = db.components().insertPrivateProject();
insertActivity("T1", project1, SUCCESS);
insertActivity("T2", project2, FAILED);
- insertQueue("T3", project1, CeQueueDto.Status.IN_PROGRESS);
+ insertQueue("T3", project1, IN_PROGRESS);
assertPage(1, asList("T3"));
assertPage(2, asList("T3", "T2"));
public void search_task_id_in_queue_ignoring_other_parameters() throws IOException {
logInAsSystemAdministrator();
ComponentDto project = db.components().insertPrivateProject();
- insertQueue("T1", project, CeQueueDto.Status.IN_PROGRESS);
+ insertQueue("T1", project, IN_PROGRESS);
ActivityResponse result = call(
ws.newRequest()
.setParam(Param.TEXT_QUERY, "T1")
- .setParam(PARAM_STATUS, CeQueueDto.Status.PENDING.name()));
+ .setParam(PARAM_STATUS, PENDING.name()));
assertThat(result.getTasksCount()).isEqualTo(1);
assertThat(result.getTasks(0).getId()).isEqualTo("T1");
@Test
public void search_task_by_component_id() {
ComponentDto project = db.components().insertPrivateProject();
- insertQueue("T1", project, CeQueueDto.Status.IN_PROGRESS);
+ insertQueue("T1", project, IN_PROGRESS);
insertActivity("T1", project, SUCCESS);
userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
assertThat(activityResponse.getTasksList())
.extracting(Task::getId, Task::getIncremental)
- .containsExactlyInAnyOrder(tuple("T1", true));
+ .containsExactlyInAnyOrder(tuple("T1", true));
}
@Test
.containsExactlyInAnyOrder(tuple("T1", true));
}
+ @Test
+ public void incremental_on_in_queue_analysis() {
+ ComponentDto project = db.components().insertPrivateProject();
+ CeQueueDto queue1 = insertQueue("T1", project, PENDING);
+ insertCharacteristic(queue1, INCREMENTAL_KEY, "true");
+ CeQueueDto queue2 = insertQueue("T2", project, IN_PROGRESS);
+ insertCharacteristic(queue2, INCREMENTAL_KEY, "true");
+ userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
+
+ ActivityResponse activityResponse = call(ws.newRequest()
+ .setParam(PARAM_COMPONENT_ID, project.uuid())
+ .setParam("status", "PENDING,FAILED,IN_PROGRESS"));
+
+ assertThat(activityResponse.getTasksList())
+ .extracting(Task::getId, Task::getIncremental)
+ .containsExactlyInAnyOrder(
+ tuple("T1", true),
+ tuple("T2", true)
+ );
+ }
+
@Test
public void fail_if_both_filters_on_component_id_and_name() {
expectedException.expect(BadRequestException.class);
activityDto.setExecutionTimeMs(500L);
activityDto.setExecutedAt(EXECUTED_AT);
activityDto.setAnalysisUuid(analysis == null ? null : analysis.getUuid());
- db.getDbClient().ceActivityDao(). insert(db.getSession(), activityDto);
+ db.getDbClient().ceActivityDao().insert(db.getSession(), activityDto);
db.commit();
return activityDto;
}
+ private CeTaskCharacteristicDto insertCharacteristic(CeQueueDto queueDto, String key, String value) {
+ CeTaskCharacteristicDto dto = new CeTaskCharacteristicDto()
+ .setUuid(Uuids.createFast())
+ .setTaskUuid(queueDto.getUuid())
+ .setKey(key)
+ .setValue(value);
+ db.getDbClient().ceTaskCharacteristicsDao().insert(db.getSession(), Collections.singletonList(dto));
+ db.commit();
+ return dto;
+ }
+
private static ActivityResponse call(TestRequest request) {
return request.executeProtobuf(ActivityResponse.class);
}
*/
package org.sonar.server.ce.ws;
+import java.util.Collections;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonarqube.ws.WsCe;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Java6Assertions.tuple;
import static org.sonar.db.ce.CeActivityDto.Status.SUCCESS;
+import static org.sonar.db.ce.CeTaskCharacteristicDto.INCREMENTAL_KEY;
import static org.sonar.server.ce.ws.ComponentAction.PARAM_COMPONENT_ID;
import static org.sonar.server.ce.ws.ComponentAction.PARAM_COMPONENT_KEY;
SnapshotDto analysisProject1 = db.components().insertSnapshot(project1);
ComponentDto project2 = db.components().insertPrivateProject(organization);
userSession.addProjectPermission(UserRole.USER, project1);
- insertActivity("T1", project1,CeActivityDto.Status.SUCCESS, analysisProject1);
+ insertActivity("T1", project1, CeActivityDto.Status.SUCCESS, analysisProject1);
insertActivity("T2", project2, CeActivityDto.Status.FAILED, null);
- insertActivity("T3", project1,CeActivityDto.Status.FAILED, null);
- insertQueue("T4", project1,CeQueueDto.Status.IN_PROGRESS);
- insertQueue("T5", project1,CeQueueDto.Status.PENDING);
+ insertActivity("T3", project1, CeActivityDto.Status.FAILED, null);
+ insertQueue("T4", project1, CeQueueDto.Status.IN_PROGRESS);
+ insertQueue("T5", project1, CeQueueDto.Status.PENDING);
WsCe.ProjectResponse response = ws.newRequest()
.setParam("componentId", project1.uuid())
.extracting(WsCe.Task::getOrganization)
.containsOnly(organization.getKey());
assertThat(response.getCurrent().getOrganization()).isEqualTo(organization.getKey());
+ assertThat(response.getCurrent().getIncremental()).isFalse();
}
@Test
.containsExactlyInAnyOrder("T1", true);
}
+ @Test
+ public void incremental_on_in_queue_analysis() {
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ userSession.addProjectPermission(UserRole.USER, project);
+ CeQueueDto queue1 = insertQueue("T1", project, CeQueueDto.Status.IN_PROGRESS);
+ insertCharacteristic(queue1, INCREMENTAL_KEY, "true");
+ CeQueueDto queue2 = insertQueue("T2", project, CeQueueDto.Status.PENDING);
+ insertCharacteristic(queue2, INCREMENTAL_KEY, "true");
+
+ WsCe.ProjectResponse response = ws.newRequest()
+ .setParam("componentId", project.uuid())
+ .executeProtobuf(WsCe.ProjectResponse.class);
+
+ assertThat(response.getQueueList())
+ .extracting(WsCe.Task::getId, WsCe.Task::getIncremental)
+ .containsOnly(
+ tuple("T1", true),
+ tuple("T2", true)
+ );
+ }
+
@Test
public void fail_with_404_when_component_does_not_exist() throws Exception {
expectedException.expect(NotFoundException.class);
db.getSession().commit();
return activityDto;
}
+
+ private CeTaskCharacteristicDto insertCharacteristic(CeQueueDto queueDto, String key, String value) {
+ CeTaskCharacteristicDto dto = new CeTaskCharacteristicDto()
+ .setUuid(Uuids.createFast())
+ .setTaskUuid(queueDto.getUuid())
+ .setKey(key)
+ .setValue(value);
+ db.getDbClient().ceTaskCharacteristicsDao().insert(db.getSession(), Collections.singletonList(dto));
+ db.commit();
+ return dto;
+ }
}
*/
package org.sonar.server.ce.ws;
+import java.util.Collections;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Rule;
import org.sonar.api.utils.System2;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
public ExpectedException expectedException = ExpectedException.none();
@Rule
- public DbTester dbTester = DbTester.create(System2.INSTANCE);
+ public DbTester db = DbTester.create(System2.INSTANCE);
private OrganizationDto organizationDto;
private ComponentDto project;
- private TaskFormatter formatter = new TaskFormatter(dbTester.getDbClient(), System2.INSTANCE);
- private TaskAction underTest = new TaskAction(dbTester.getDbClient(), formatter, userSession);
+ private TaskFormatter formatter = new TaskFormatter(db.getDbClient(), System2.INSTANCE);
+ private TaskAction underTest = new TaskAction(db.getDbClient(), formatter, userSession);
private WsActionTester ws = new WsActionTester(underTest);
@Before
public void setUp() {
- organizationDto = dbTester.organizations().insert();
- project = dbTester.components().insertPrivateProject(organizationDto);
+ organizationDto = db.organizations().insert();
+ project = db.components().insertPrivateProject(organizationDto);
}
@Test
assertThat(taskResponse.getTask().getComponentName()).isEqualTo(project.name());
assertThat(taskResponse.getTask().hasExecutionTimeMs()).isFalse();
assertThat(taskResponse.getTask().getLogs()).isFalse();
+ assertThat(taskResponse.getTask().getIncremental()).isFalse();
}
@Test
assertThat(task.getLogs()).isFalse();
}
+ @Test
+ public void incremental_on_queued_task() {
+ logInAsRoot();
+
+ ComponentDto project = db.components().insertPrivateProject();
+ CeQueueDto queueDto = createAndPersistQueueTask(project);
+ insertCharacteristic(queueDto, "incremental", "true");
+
+ WsCe.TaskResponse taskResponse = ws.newRequest()
+ .setParam("id", SOME_TASK_UUID)
+ .executeProtobuf(WsCe.TaskResponse.class);
+
+ assertThat(taskResponse.getTask().getIncremental()).isTrue();
+ }
+
+ @Test
+ public void incremental_on_archived_task() {
+ logInAsRoot();
+
+ ComponentDto project = db.components().insertPrivateProject();
+ SnapshotDto analysis = db.components().insertSnapshot(project, s -> s.setIncremental(true));
+ CeQueueDto queueDto = new CeQueueDto()
+ .setTaskType(CeTaskTypes.REPORT)
+ .setUuid(SOME_TASK_UUID)
+ .setComponentUuid(project.uuid());
+ CeActivityDto activityDto = new CeActivityDto(queueDto)
+ .setStatus(CeActivityDto.Status.FAILED)
+ .setExecutionTimeMs(500L)
+ .setAnalysisUuid(analysis.getUuid());
+ persist(activityDto);
+
+ WsCe.TaskResponse taskResponse = ws.newRequest()
+ .setParam("id", SOME_TASK_UUID)
+ .executeProtobuf(WsCe.TaskResponse.class);
+
+ assertThat(taskResponse.getTask().getIncremental()).isTrue();
+ }
+
@Test
public void return_stacktrace_of_failed_activity_with_stacktrace_when_additionalField_is_set() {
logInAsRoot();
return dto;
}
+ private CeTaskCharacteristicDto insertCharacteristic(CeQueueDto queueDto, String key, String value) {
+ CeTaskCharacteristicDto dto = new CeTaskCharacteristicDto()
+ .setUuid(Uuids.createFast())
+ .setTaskUuid(queueDto.getUuid())
+ .setKey(key)
+ .setValue(value);
+ db.getDbClient().ceTaskCharacteristicsDao().insert(db.getSession(), Collections.singletonList(dto));
+ db.commit();
+ return dto;
+ }
+
private void persist(CeQueueDto queueDto) {
- dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
- dbTester.commit();
+ db.getDbClient().ceQueueDao().insert(db.getSession(), queueDto);
+ db.commit();
}
private CeActivityDto persist(CeActivityDto activityDto) {
- dbTester.getDbClient().ceActivityDao().insert(dbTester.getSession(), activityDto);
- dbTester.commit();
+ db.getDbClient().ceActivityDao().insert(db.getSession(), activityDto);
+ db.commit();
return activityDto;
}
private void persistScannerContext(String taskUuid, String scannerContext) {
- dbTester.getDbClient().ceScannerContextDao().insert(dbTester.getSession(), taskUuid, CloseableIterator.from(singleton(scannerContext).iterator()));
- dbTester.commit();
+ db.getDbClient().ceScannerContextDao().insert(db.getSession(), taskUuid, CloseableIterator.from(singleton(scannerContext).iterator()));
+ db.commit();
}
private void logInAsSystemAdministrator() {
*/
package org.sonar.server.ce.ws;
-import com.google.common.base.Optional;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
public void formatActivity() {
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED);
- WsCe.Task wsTask = underTest.formatActivity(db.getSession(), dto);
+ WsCe.Task wsTask = underTest.formatActivity(db.getSession(), dto, null);
assertThat(wsTask.getType()).isEqualTo(CeTaskTypes.REPORT);
assertThat(wsTask.getId()).isEqualTo("UUID");
CeActivityDto dto = newActivity("UUID", "COMPONENT_UUID", CeActivityDto.Status.FAILED);
String expected = "scanner context baby!";
- WsCe.Task wsTask = underTest.formatActivity(db.getSession(), dto, Optional.absent(), expected);
+ WsCe.Task wsTask = underTest.formatActivity(db.getSession(), dto, expected);
assertThat(wsTask.hasScannerContext()).isTrue();
assertThat(wsTask.getScannerContext()).isEqualTo(expected);
*/
package org.sonar.server.computation.queue;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
-import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
-import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
-import static org.sonar.db.permission.OrganizationPermission.SCAN;
-
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-
import org.apache.commons.io.IOUtils;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.sonar.core.util.UuidFactory;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.tester.UserSessionRule;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
+import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
+import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
+import static org.sonar.db.permission.OrganizationPermission.SCAN;
+
public class ReportSubmitterTest {
private static final String PROJECT_KEY = "MY_PROJECT";
verify(queue).submit(submittedTask.capture());
String taskUuid = submittedTask.getValue().getUuid();
- Map<String, String> insertedCharacteristics = db.getDbClient().ceTaskCharacteristicsDao().getTaskCharacteristics(db.getSession(), taskUuid);
- assertThat(insertedCharacteristics).containsOnly(entry("incremental", "true"), entry("pr", "mypr"));
+ List<CeTaskCharacteristicDto> insertedCharacteristics = db.getDbClient().ceTaskCharacteristicsDao().selectByTaskUuid(db.getSession(), taskUuid);
+ assertThat(insertedCharacteristics)
+ .extracting(CeTaskCharacteristicDto::getKey, CeTaskCharacteristicDto::getValue)
+ .containsOnly(tuple("incremental", "true"), tuple("pr", "mypr"));
}
@Test
import org.sonarqube.ws.WsCe;
import org.sonarqube.ws.WsCe.ActivityResponse;
+import org.sonarqube.ws.WsCe.ProjectResponse;
import org.sonarqube.ws.WsCe.TaskTypesWsResponse;
import org.sonarqube.ws.WsCe.WorkerCountResponse;
import org.sonarqube.ws.client.BaseService;
return call(new GetRequest(path(ACTION_WORKER_COUNT)), WorkerCountResponse.parser());
}
+ public ProjectResponse component(String componentKey) {
+ return call(
+ new GetRequest(path("component"))
+ .setParam(PARAM_COMPONENT_KEY, componentKey),
+ ProjectResponse.parser());
+ }
+
}
import static org.assertj.core.data.MapEntry.entry;
import static org.mockito.Mockito.mock;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_KEY;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MIN_SUBMITTED_AT;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_ONLY_CURRENTS;
assertThat(serviceTester.getGetRequest().getPath()).isEqualTo("api/ce/worker_count");
assertThat(serviceTester.getGetParser()).isSameAs(WsCe.WorkerCountResponse.parser());
}
+
+ @Test
+ public void component() {
+ underTest.component("my_component");
+ GetRequest result = serviceTester.getGetRequest();
+
+ assertThat(serviceTester.getGetParser()).isSameAs(WsCe.ProjectResponse.parser());
+ serviceTester.assertThat(result)
+ .hasPath("component")
+ .hasParam(PARAM_COMPONENT_KEY, "my_component")
+ .andNoOtherParam();
+ }
}