]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9708 Return incremental field in api/ce/activity
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 11 Aug 2017 13:18:38 +0000 (15:18 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 11 Aug 2017 15:30:07 +0000 (17:30 +0200)
server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
server/sonar-server/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
sonar-ws/src/main/protobuf/ws-ce.proto

index 1a573ad89a5ef2edca3573a306533747a1bfe033..b1ac6073762e0481c6fe688e26f1a6c7507b7b40 100644 (file)
@@ -22,14 +22,15 @@ package org.sonar.server.ce.ws;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
 import java.util.Collections;
 import java.util.Date;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.sonar.api.resources.Qualifiers;
+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;
@@ -56,7 +57,9 @@ import static java.util.Collections.singletonList;
 import static org.apache.commons.lang.StringUtils.defaultString;
 import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime;
 import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime;
+import static org.sonar.core.util.stream.MoreCollectors.toList;
 import static org.sonar.db.Pagination.forPage;
+import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
 import static org.sonar.server.ws.WsUtils.checkRequest;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
@@ -69,7 +72,7 @@ import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_TYPE;
 
 public class ActivityAction implements CeWsAction {
   private static final int MAX_PAGE_SIZE = 1000;
-  private static final List<String> POSSIBLE_QUALIFIERS = ImmutableList.of(Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW, "DEV", Qualifiers.MODULE);
+  private static final String[] POSSIBLE_QUALIFIERS = new String[] {Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW, "DEV", Qualifiers.MODULE};
 
   private final UserSession userSession;
   private final DbClient dbClient;
@@ -92,11 +95,13 @@ public class ActivityAction implements CeWsAction {
     WebService.NewAction action = controller.createAction("activity")
       .setDescription(format("Search for tasks.<br> " +
         "Requires the system administration permission, " +
-        "or project administration permission if %s is set.<br/>" +
-        "Since 5.5, it's no more possible to specify the page parameter.<br/>" +
-        "Since 6.1, field \"logs\" is deprecated and its value is always false.", PARAM_COMPONENT_ID))
+        "or project administration permission if %s is set.", PARAM_COMPONENT_ID))
       .setResponseExample(getClass().getResource("activity-example.json"))
       .setHandler(this)
+      .setChangelog(
+        new Change("5.5", "it's no more possible to specify the page parameter.<"),
+        new Change("6.1", "field \"logs\" is deprecated and its value is always false"),
+        new Change("6.6", "field \"incremental\" is added"))
       .setSince("5.2");
 
     action.createParam(PARAM_COMPONENT_ID)
@@ -157,9 +162,10 @@ public class ActivityAction implements CeWsAction {
   }
 
   private ActivityResponse doHandle(ActivityWsRequest request) {
-    checkPermission(request);
 
     try (DbSession dbSession = dbClient.openSession(false)) {
+      ComponentDto component = loadComponent(dbSession, request);
+      checkPermission(component);
       // if a task searched by uuid is found all other parameters are ignored
       Optional<WsCe.Task> taskSearchedById = searchTaskByUuid(dbSession, request);
       if (taskSearchedById.isPresent()) {
@@ -169,10 +175,9 @@ public class ActivityAction implements CeWsAction {
           request.getPageSize());
       }
 
-      CeTaskQuery query = buildQuery(dbSession, request);
-      Iterable<WsCe.Task> queuedTasks = loadQueuedTasks(dbSession, request, query);
-      Iterable<WsCe.Task> pastTasks = loadPastTasks(dbSession, request, query);
-
+      CeTaskQuery query = buildQuery(dbSession, request, component);
+      List<WsCe.Task> queuedTasks = loadQueuedTasks(dbSession, request, query);
+      List<WsCe.Task> pastTasks = loadPastTasks(dbSession, request, query);
       return buildResponse(
         queuedTasks,
         pastTasks,
@@ -180,14 +185,23 @@ public class ActivityAction implements CeWsAction {
     }
   }
 
-  private void checkPermission(ActivityWsRequest request) {
+  @CheckForNull
+  private ComponentDto loadComponent(DbSession dbSession, ActivityWsRequest request) {
+    String componentId = request.getComponentId();
+    if (componentId == null) {
+      return null;
+    }
+    return checkFoundWithOptional(dbClient.componentDao().selectByUuid(dbSession, componentId), "Component '%s' does not exist", componentId);
+  }
+
+  private void checkPermission(@Nullable ComponentDto component) {
     // fail fast if not logged in
     userSession.checkLoggedIn();
 
-    if (request.getComponentId() == null) {
+    if (component == null) {
       userSession.checkIsSystemAdministrator();
     } else {
-      userSession.checkComponentUuidPermission(UserRole.ADMIN, request.getComponentId());
+      userSession.checkComponentPermission(UserRole.ADMIN, component);
     }
   }
 
@@ -203,14 +217,11 @@ public class ActivityAction implements CeWsAction {
     }
 
     java.util.Optional<CeActivityDto> activity = dbClient.ceActivityDao().selectByUuid(dbSession, textQuery);
-    if (activity.isPresent()) {
-      return Optional.of(formatter.formatActivity(dbSession, activity.get()));
-    }
+    return activity.map(ceActivityDto -> Optional.of(formatter.formatActivity(dbSession, ceActivityDto))).orElseGet(Optional::absent);
 
-    return Optional.absent();
   }
 
-  private CeTaskQuery buildQuery(DbSession dbSession, ActivityWsRequest request) {
+  private CeTaskQuery buildQuery(DbSession dbSession, ActivityWsRequest request, @Nullable ComponentDto component) {
     CeTaskQuery query = new CeTaskQuery();
     query.setType(request.getType());
     query.setOnlyCurrents(request.getOnlyCurrents());
@@ -224,28 +235,17 @@ public class ActivityAction implements CeWsAction {
       query.setStatuses(request.getStatus());
     }
 
-    query.setComponentUuids(loadComponentUuids(dbSession, request));
+    query.setComponentUuids(component == null ? loadComponentUuids(dbSession, request).stream().map(ComponentDto::uuid).collect(toList()) : singletonList(component.uuid()));
     return query;
   }
 
-  @CheckForNull
-  private List<String> loadComponentUuids(DbSession dbSession, ActivityWsRequest request) {
-    String componentUuid = request.getComponentId();
+  private List<ComponentDto> loadComponentUuids(DbSession dbSession, ActivityWsRequest request) {
     String componentQuery = request.getQuery();
-
-    if (componentUuid != null) {
-      return singletonList(componentUuid);
-    }
-    if (componentQuery != null) {
-      ComponentQuery componentDtoQuery = ComponentQuery.builder()
-        .setNameOrKeyQuery(componentQuery)
-        .setQualifiers(POSSIBLE_QUALIFIERS.toArray(new String[0]))
-        .build();
-      List<ComponentDto> componentDtos = dbClient.componentDao().selectByQuery(dbSession, componentDtoQuery, 0, CeTaskQuery.MAX_COMPONENT_UUIDS);
-      return Lists.transform(componentDtos, ComponentDto::uuid);
-    }
-
-    return null;
+    ComponentQuery componentDtoQuery = ComponentQuery.builder()
+      .setNameOrKeyQuery(componentQuery)
+      .setQualifiers(POSSIBLE_QUALIFIERS)
+      .build();
+    return dbClient.componentDao().selectByQuery(dbSession, componentDtoQuery, 0, CeTaskQuery.MAX_COMPONENT_UUIDS);
   }
 
   private List<WsCe.Task> loadQueuedTasks(DbSession dbSession, ActivityWsRequest request, CeTaskQuery query) {
index ed6f188082dc9471b5402bf0448d5d3f813a8039..16aead9298a75c772d346498e6bac10209583db1 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.ce.ws;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -37,12 +38,14 @@ import org.sonar.db.DbSession;
 import org.sonar.db.ce.CeActivityDto;
 import org.sonar.db.ce.CeQueueDto;
 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;
 
@@ -65,8 +68,8 @@ public class TaskFormatter {
     return dtos.stream().map(input -> formatQueue(input, cache)).collect(MoreCollectors.toList(dtos.size()));
   }
 
-  public WsCe.Task formatQueue(DbSession dbSession, CeQueueDto dto) {
-    return formatQueue(dto, ComponentDtoCache.forUuid(dbClient, dbSession, dto.getComponentUuid()));
+  public WsCe.Task formatQueue(DbSession dbSession, CeQueueDto queue) {
+    return formatQueue(queue, ComponentDtoCache.forQueueDtos(dbClient, dbSession, singletonList(queue)));
   }
 
   public WsCe.Task formatQueue(DbSession dbSession, CeQueueDto dto, Optional<ComponentDto> component) {
@@ -94,8 +97,8 @@ public class TaskFormatter {
     return builder.build();
   }
 
-  public WsCe.Task formatActivity(DbSession dbSession, CeActivityDto dto) {
-    return formatActivity(dto, ComponentDtoCache.forUuid(dbClient, dbSession, dto.getComponentUuid()), null);
+  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,
@@ -119,11 +122,13 @@ public class TaskFormatter {
     builder.setStatus(WsCe.TaskStatus.valueOf(dto.getStatus().name()));
     builder.setType(dto.getTaskType());
     builder.setLogs(false);
-    if (dto.getComponentUuid() != null) {
-      builder.setComponentId(dto.getComponentUuid());
-      buildComponent(builder, componentDtoCache.getComponent(dto.getComponentUuid()));
+    setNullable(dto.getComponentUuid(), uuid -> buildComponent(builder, componentDtoCache.getComponent(uuid)).setComponentId(uuid));
+    String analysisUuid = dto.getAnalysisUuid();
+    if (analysisUuid != null) {
+      builder.setAnalysisId(analysisUuid);
+      setNullable(componentDtoCache.getAnalysis(analysisUuid), analysis -> builder.setIncremental(analysis.getIncremental()));
     }
-    setNullable(dto.getAnalysisUuid(), builder::setAnalysisId);
+    setNullable(analysisUuid, builder::setAnalysisId);
     setNullable(dto.getSubmitterLogin(), builder::setSubmitterLogin);
     builder.setSubmittedAt(formatDateTime(new Date(dto.getSubmittedAt())));
     setNullable(dto.getStartedAt(), builder::setStartedAt, DateUtils::formatDateTime);
@@ -136,28 +141,31 @@ public class TaskFormatter {
     return builder.build();
   }
 
-  private static void buildComponent(WsCe.Task.Builder builder, @Nullable ComponentDto componentDto) {
+  private static WsCe.Task.Builder buildComponent(WsCe.Task.Builder builder, @Nullable ComponentDto componentDto) {
     if (componentDto != null) {
       builder.setComponentKey(componentDto.getDbKey());
       builder.setComponentName(componentDto.name());
       builder.setComponentQualifier(componentDto.qualifier());
     }
+    return builder;
   }
 
   private static class ComponentDtoCache {
     private final Map<String, ComponentDto> componentsByUuid;
     private final Map<String, OrganizationDto> organizationsByUuid;
+    private final Map<String, SnapshotDto> analysisByUuid;
 
-    private ComponentDtoCache(Map<String, ComponentDto> componentsByUuid, Map<String, OrganizationDto> organizationsByUuid) {
+    private ComponentDtoCache(Map<String, ComponentDto> componentsByUuid, Map<String, OrganizationDto> organizationsByUuid, Map<String, SnapshotDto> analysisByUuid) {
       this.componentsByUuid = componentsByUuid;
       this.organizationsByUuid = organizationsByUuid;
+      this.analysisByUuid = analysisByUuid;
     }
 
     static ComponentDtoCache 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));
+      return new ComponentDtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), Collections.emptyMap());
     }
 
     private static Set<String> uuidOfCeQueueDtos(Collection<CeQueueDto> ceQueueDtos) {
@@ -174,7 +182,9 @@ public class TaskFormatter {
         uuidOfCeActivityDtos(ceActivityDtos))
         .stream()
         .collect(MoreCollectors.uniqueIndex(ComponentDto::uuid));
-      return new ComponentDtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid));
+      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);
     }
 
     private static Set<String> uuidOfCeActivityDtos(Collection<CeActivityDto> ceActivityDtos) {
@@ -185,14 +195,9 @@ public class TaskFormatter {
         .collect(MoreCollectors.toSet(ceActivityDtos.size()));
     }
 
-    static ComponentDtoCache forUuid(DbClient dbClient, DbSession dbSession, String uuid) {
-      Optional<ComponentDto> component = dbClient.componentDao().selectByUuid(dbSession, uuid);
-      return forComponentDto(dbClient, dbSession, component);
-    }
-
     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));
+      return new ComponentDtoCache(componentsByUuid, buildOrganizationsByUuid(dbClient, dbSession, componentsByUuid), Collections.emptyMap());
     }
 
     private static Map<String, OrganizationDto> buildOrganizationsByUuid(DbClient dbClient, DbSession dbSession, Map<String, ComponentDto> componentsByUuid) {
@@ -227,6 +232,11 @@ public class TaskFormatter {
       checkState(organizationDto != null, "Organization with uuid '%s' not found", organizationUuid);
       return organizationDto.getKey();
     }
+
+    @CheckForNull
+    SnapshotDto getAnalysis(String analysisUuid) {
+      return analysisByUuid.get(analysisUuid);
+    }
   }
 
   /**
index c3e5b7edf97a6a92c6694e6c2897deb7b5b21ee5..c6f20d7bc1ea6af32cf75e5e524fea34599bacac 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.ce.ws;
 import java.io.IOException;
 import java.util.Date;
 import java.util.List;
+import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -39,6 +40,7 @@ import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
@@ -52,6 +54,7 @@ import org.sonarqube.ws.WsCe.Task;
 
 import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
 import static org.mockito.Mockito.mock;
 import static org.sonar.api.utils.DateUtils.formatDate;
 import static org.sonar.api.utils.DateUtils.formatDateTime;
@@ -88,8 +91,7 @@ public class ActivityActionTest {
     ComponentDto project2 = db.components().insertPrivateProject(org2);
     SnapshotDto analysisProject1 = db.components().insertSnapshot(project1);
     insertActivity("T1", project1, SUCCESS, analysisProject1);
-    SnapshotDto analysisProject2 = db.components().insertSnapshot(project2);
-    insertActivity("T2", project2, FAILED, analysisProject2);
+    insertActivity("T2", project2, FAILED, null);
 
     ActivityResponse activityResponse = call(ws.newRequest()
       .setParam(PARAM_MAX_EXECUTED_AT, formatDateTime(EXECUTED_AT + 2_000)));
@@ -101,15 +103,18 @@ public class ActivityActionTest {
     assertThat(task.getId()).isEqualTo("T2");
     assertThat(task.getStatus()).isEqualTo(WsCe.TaskStatus.FAILED);
     assertThat(task.getComponentId()).isEqualTo(project2.uuid());
-    assertThat(task.getAnalysisId()).isEqualTo(analysisProject2.getUuid());
+    assertThat(task.hasAnalysisId()).isFalse();
     assertThat(task.getExecutionTimeMs()).isEqualTo(500L);
     assertThat(task.getLogs()).isFalse();
+    assertThat(task.getIncremental()).isFalse();
+
     task = activityResponse.getTasks(1);
     assertThat(task.getId()).isEqualTo("T1");
     assertThat(task.getStatus()).isEqualTo(WsCe.TaskStatus.SUCCESS);
     assertThat(task.getComponentId()).isEqualTo(project1.uuid());
     assertThat(task.getLogs()).isFalse();
     assertThat(task.getOrganization()).isEqualTo(org1.getKey());
+    assertThat(task.getIncremental()).isFalse();
   }
 
   @Test
@@ -190,29 +195,6 @@ public class ActivityActionTest {
     assertPage(10, asList("T3", "T2", "T1"));
   }
 
-  @Test
-  public void throws_IAE_if_pageSize_is_0() {
-    logInAsSystemAdministrator();
-    expectedException.expect(IllegalArgumentException.class);
-    expectedException.expectMessage("page size must be >= 1");
-
-    call(ws.newRequest()
-      .setParam(Param.PAGE_SIZE, Integer.toString(0))
-      .setParam(PARAM_STATUS, "SUCCESS,FAILED,CANCELED,IN_PROGRESS,PENDING"));
-  }
-
-  private void assertPage(int pageSize, List<String> expectedOrderedTaskIds) {
-    ActivityResponse activityResponse = call(ws.newRequest()
-      .setParam(Param.PAGE_SIZE, Integer.toString(pageSize))
-      .setParam(PARAM_STATUS, "SUCCESS,FAILED,CANCELED,IN_PROGRESS,PENDING"));
-
-    assertThat(activityResponse.getTasksCount()).isEqualTo(expectedOrderedTaskIds.size());
-    for (int i = 0; i < expectedOrderedTaskIds.size(); i++) {
-      String expectedTaskId = expectedOrderedTaskIds.get(i);
-      assertThat(activityResponse.getTasks(i).getId()).isEqualTo(expectedTaskId);
-    }
-  }
-
   @Test
   public void project_administrator_can_access_his_project_activity() {
     ComponentDto project1 = db.components().insertPrivateProject();
@@ -340,6 +322,55 @@ public class ActivityActionTest {
     assertThat(result.getTasksCount()).isEqualTo(2);
   }
 
+  @Test
+  public void incremental_analysis_on_single_project() {
+    ComponentDto project = db.components().insertPrivateProject();
+    SnapshotDto incrementalAnalysis = db.components().insertSnapshot(project, s -> s.setIncremental(true));
+    insertActivity("T1", project, SUCCESS, incrementalAnalysis);
+    userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
+
+    ActivityResponse activityResponse = call(ws.newRequest()
+      .setParam(PARAM_COMPONENT_ID, project.uuid()));
+
+    assertThat(activityResponse.getTasksList())
+      .extracting(Task::getId, Task::getIncremental)
+    .containsExactlyInAnyOrder(tuple("T1", true));
+  }
+
+  @Test
+  public void incremental_analysis_on_search_text() {
+    ComponentDto project = db.components().insertPrivateProject();
+    SnapshotDto incrementalAnalysis = db.components().insertSnapshot(project, s -> s.setIncremental(true));
+    SnapshotDto standardAnalysis = db.components().insertSnapshot(project, s -> s.setIncremental(false));
+    insertActivity("T1", project, SUCCESS, incrementalAnalysis);
+    insertActivity("T2", project, SUCCESS, standardAnalysis);
+    logInAsSystemAdministrator();
+
+    ActivityResponse activityResponse = call(ws.newRequest()
+      .setParam(PARAM_COMPONENT_QUERY, project.name()));
+
+    assertThat(activityResponse.getTasksList())
+      .extracting(Task::getId, Task::getIncremental)
+      .containsExactlyInAnyOrder(
+        tuple("T1", true),
+        tuple("T2", false));
+  }
+
+  @Test
+  public void incremental_analysis_on_search_uuid() {
+    ComponentDto project = db.components().insertPrivateProject();
+    SnapshotDto incrementalAnalysis = db.components().insertSnapshot(project, s -> s.setIncremental(true));
+    insertActivity("T1", project, SUCCESS, incrementalAnalysis);
+    logInAsSystemAdministrator();
+
+    ActivityResponse activityResponse = call(ws.newRequest()
+      .setParam(PARAM_COMPONENT_QUERY, "T1"));
+
+    assertThat(activityResponse.getTasksList())
+      .extracting(Task::getId, Task::getIncremental)
+      .containsExactlyInAnyOrder(tuple("T1", true));
+  }
+
   @Test
   public void fail_if_both_filters_on_component_id_and_name() {
     expectedException.expect(BadRequestException.class);
@@ -374,6 +405,41 @@ public class ActivityActionTest {
       .execute();
   }
 
+  @Test
+  public void throws_IAE_if_pageSize_is_0() {
+    logInAsSystemAdministrator();
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("page size must be >= 1");
+
+    call(ws.newRequest()
+      .setParam(Param.PAGE_SIZE, Integer.toString(0))
+      .setParam(PARAM_STATUS, "SUCCESS,FAILED,CANCELED,IN_PROGRESS,PENDING"));
+  }
+
+  @Test
+  public void fail_when_project_does_not_exist() {
+    logInAsSystemAdministrator();
+
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage("Component 'unknown' does not exist");
+
+    ws.newRequest()
+      .setParam(PARAM_COMPONENT_ID, "unknown")
+      .execute();
+  }
+
+  private void assertPage(int pageSize, List<String> expectedOrderedTaskIds) {
+    ActivityResponse activityResponse = call(ws.newRequest()
+      .setParam(Param.PAGE_SIZE, Integer.toString(pageSize))
+      .setParam(PARAM_STATUS, "SUCCESS,FAILED,CANCELED,IN_PROGRESS,PENDING"));
+
+    assertThat(activityResponse.getTasksCount()).isEqualTo(expectedOrderedTaskIds.size());
+    for (int i = 0; i < expectedOrderedTaskIds.size(); i++) {
+      String expectedTaskId = expectedOrderedTaskIds.get(i);
+      assertThat(activityResponse.getTasks(i).getId()).isEqualTo(expectedTaskId);
+    }
+  }
+
   @Test
   public void support_json_response() {
     logInAsSystemAdministrator();
@@ -403,7 +469,7 @@ public class ActivityActionTest {
     return insertActivity(taskUuid, project, status, db.components().insertSnapshot(project));
   }
 
-  private CeActivityDto insertActivity(String taskUuid, ComponentDto project, Status status, SnapshotDto analysis) {
+  private CeActivityDto insertActivity(String taskUuid, ComponentDto project, Status status, @Nullable SnapshotDto analysis) {
     CeQueueDto queueDto = new CeQueueDto();
     queueDto.setTaskType(CeTaskTypes.REPORT);
     queueDto.setComponentUuid(project.uuid());
@@ -413,7 +479,7 @@ public class ActivityActionTest {
     activityDto.setStatus(status);
     activityDto.setExecutionTimeMs(500L);
     activityDto.setExecutedAt(EXECUTED_AT);
-    activityDto.setAnalysisUuid(analysis.getUuid());
+    activityDto.setAnalysisUuid(analysis == null ? null : analysis.getUuid());
     db.getDbClient().ceActivityDao(). insert(db.getSession(), activityDto);
     db.commit();
     return activityDto;
index cc38df268c78c4642d02330681be5f16b9a4ced5..e6f69926046391a08a8a45999e96e713e6e6d85c 100644 (file)
@@ -68,7 +68,6 @@ message WorkerCountResponse {
 }
 
 message Task {
-  optional string organization = 20;
   optional string id = 1;
   optional string type = 2;
   optional string componentId = 3;
@@ -88,6 +87,8 @@ message Task {
   optional string errorStacktrace = 17;
   optional string scannerContext = 18;
   optional bool hasScannerContext = 19;
+  optional string organization = 20;
+  optional bool incremental = 21;
 }
 
 enum TaskStatus {