--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.ce.task.projectanalysis.taskprocessor;
+
+import java.util.Optional;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.ce.task.CeTask;
+import org.sonar.ce.task.step.ComputationStep;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+
+public final class IgnoreOrphanBranchStep implements ComputationStep {
+ private static final Logger LOG = Loggers.get(IgnoreOrphanBranchStep.class);
+ private final CeTask ceTask;
+ private final DbClient dbClient;
+
+ public IgnoreOrphanBranchStep(CeTask ceTask, DbClient dbClient) {
+ this.ceTask = ceTask;
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public void execute(Context context) {
+ String mainComponentUuid = ceTask.getMainComponent().orElseThrow(() -> new UnsupportedOperationException("main component not found in task")).getUuid();
+ String componentUuid = ceTask.getComponent().orElseThrow(() -> new UnsupportedOperationException("component not found in task")).getUuid();
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ Optional<ComponentDto> componentDto = dbClient.componentDao().selectByUuid(dbSession, mainComponentUuid);
+ if(!componentDto.isPresent()){
+ LOG.info("reindexation task has been trigger on an orphan branch. removing any exclude_from_purge flag, and skip the indexation");
+ dbClient.branchDao().updateExcludeFromPurge(dbSession, componentUuid, false);
+ dbClient.branchDao().updateNeedIssueSync(dbSession, componentUuid, false);
+ dbSession.commit();
+ }
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Ignore orphan component";
+ }
+}
LOG.debug("issues of branch {} are already in sync", branchUuid);
}
});
-
}
}
@Override
protected void configureModule() {
add(
+ IgnoreOrphanBranchStep.class,
IssueSyncTaskProcessor.class);
}
}
package org.sonar.ce.task.projectanalysis.taskprocessor;
import com.google.common.collect.ImmutableSet;
-import java.util.Collections;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.annotation.CheckForNull;
static ContainerPopulator<TaskContainer> newContainerPopulator(CeTask task) {
return taskContainer -> {
taskContainer.add(task);
+ taskContainer.add(IgnoreOrphanBranchStep.class);
taskContainer.add(IndexIssuesStep.class);
taskContainer.add(new SyncComputationSteps(taskContainer));
taskContainer.add(ComputationStepExecutor.class);
@Override
public List<Class<? extends ComputationStep>> orderedStepClasses() {
- return Collections.singletonList(IndexIssuesStep.class);
+ return Arrays.asList(IgnoreOrphanBranchStep.class, IndexIssuesStep.class);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.ce.task.projectanalysis.taskprocessor;
+
+import java.util.Optional;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.ce.task.CeTask;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.BranchDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.db.component.BranchType.BRANCH;
+
+public class IgnoreOrphanBranchStepTest {
+
+ private String BRANCH_UUID = "branch_uuid";
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+ private CeTask.Component component = new CeTask.Component(BRANCH_UUID, "component key", "component name");
+ private CeTask ceTask = new CeTask.Builder()
+ .setOrganizationUuid("organizationUuid")
+ .setType("type")
+ .setUuid("uuid")
+ .setComponent(component)
+ .setMainComponent(component)
+ .build();
+
+ private DbClient dbClient = dbTester.getDbClient();
+ private IgnoreOrphanBranchStep underTest = new IgnoreOrphanBranchStep(ceTask, dbClient);
+
+ @Test
+ public void execute() {
+ BranchDto branchDto = new BranchDto()
+ .setBranchType(BRANCH)
+ .setKey("branchName")
+ .setUuid(BRANCH_UUID)
+ .setProjectUuid("project_uuid")
+ .setNeedIssueSync(true);
+ dbClient.branchDao().insert(dbTester.getSession(), branchDto);
+ dbTester.commit();
+
+ underTest.execute(() -> null);
+
+ Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), BRANCH_UUID);
+ assertThat(branch.get().isNeedIssueSync()).isFalse();
+ assertThat(branch.get().isExcludeFromPurge()).isFalse();
+ }
+
+ @Test
+ public void execute_on_already_indexed_branch() {
+ BranchDto branchDto = new BranchDto()
+ .setBranchType(BRANCH)
+ .setKey("branchName")
+ .setUuid(BRANCH_UUID)
+ .setProjectUuid("project_uuid")
+ .setNeedIssueSync(false);
+ dbClient.branchDao().insert(dbTester.getSession(), branchDto);
+ dbTester.commit();
+
+ underTest.execute(() -> null);
+
+ Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), BRANCH_UUID);
+ assertThat(branch.get().isNeedIssueSync()).isFalse();
+ assertThat(branch.get().isExcludeFromPurge()).isFalse();
+ }
+
+ @Test
+ public void fail_if_missing_main_component_in_task() {
+ CeTask ceTask = new CeTask.Builder()
+ .setOrganizationUuid("organizationUuid")
+ .setType("type")
+ .setUuid("uuid")
+ .setComponent(null)
+ .setMainComponent(null)
+ .build();
+ IgnoreOrphanBranchStep underTest = new IgnoreOrphanBranchStep(ceTask, dbClient);
+
+ assertThatThrownBy(() -> underTest.execute(() -> null))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessage("main component not found in task");
+ }
+
+ @Test
+ public void verify_step_description() {
+ assertThat(underTest.getDescription()).isEqualTo("Ignore orphan component");
+ }
+
+}
.build();
IssueSyncTaskProcessor.newContainerPopulator(task).populateContainer(container);
- Mockito.verify(container, Mockito.times(4)).add(any());
+ Mockito.verify(container, Mockito.times(5)).add(any());
}
@Test
List<Class<? extends ComputationStep>> steps = syncComputationSteps.orderedStepClasses();
- Assertions.assertThat(steps).containsExactly(IndexIssuesStep.class);
+ Assertions.assertThat(steps).containsExactly(IgnoreOrphanBranchStep.class, IndexIssuesStep.class);
}
}
from
ce_queue cq
<if test="excludeViewRefresh">
- inner join components c on c.uuid = cq.main_component_uuid and c.qualifier <> 'VW'
+ left join components c on c.uuid = cq.main_component_uuid and c.qualifier <> 'VW'
</if>
where
cq.status='PENDING'
assertThat(peek2.get().getUuid()).isEqualTo(TASK_UUID_2);
}
+ @Test
+ public void excluding_view_pick_up_orphan_branches() {
+ insertPending(newCeQueueDto(TASK_UUID_1)
+ .setComponentUuid(MAIN_COMPONENT_UUID_1)
+ .setMainComponentUuid("non-existing-uuid")
+ .setStatus(PENDING)
+ .setTaskType(CeTaskTypes.BRANCH_ISSUE_SYNC)
+ .setCreatedAt(100_000L));
+
+ Optional<CeQueueDto> peek = underTest.peek(db.getSession(), WORKER_UUID_1, false, true);
+ assertThat(peek).isPresent();
+ assertThat(peek.get().getUuid()).isEqualTo(TASK_UUID_1);
+ }
+
@Test
public void hasAnyIssueSyncTaskPendingOrInProgress_PENDING() {
assertThat(underTest.hasAnyIssueSyncTaskPendingOrInProgress(db.getSession())).isFalse();