diff --git a/CHANGES.md b/CHANGES.md index c1e21103a..c1ac0ab51 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ ## Version 5.0.0 (Not yet released) +* Progress for on demand repair jobs is either 0% or 100% - Issue #593 * Make priority granularity configurable - Issue #599 * Bump springboot from 2.7.12 to 2.7.17 - Issue #604 * Bump io.micrometer from 1.9.2 to 1.9.16 - Issue #604 diff --git a/core/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/repair/VnodeOnDemandRepairJob.java b/core/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/repair/VnodeOnDemandRepairJob.java index 4a392a592..ca5f58cbe 100644 --- a/core/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/repair/VnodeOnDemandRepairJob.java +++ b/core/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/repair/VnodeOnDemandRepairJob.java @@ -15,6 +15,8 @@ package com.ericsson.bss.cassandra.ecchronos.core.repair; +import static com.ericsson.bss.cassandra.ecchronos.core.repair.OngoingJob.Status; + import com.ericsson.bss.cassandra.ecchronos.core.JmxProxyFactory; import com.ericsson.bss.cassandra.ecchronos.core.metrics.TableRepairMetrics; import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairHistory; @@ -52,7 +54,7 @@ public final class VnodeOnDemandRepairJob extends OnDemandRepairJob private static final Logger LOG = LoggerFactory.getLogger(VnodeOnDemandRepairJob.class); private final RepairHistory myRepairHistory; private final Map> myTasks; - private final int myTotalTasks; + private final int myTotalTokens; private VnodeOnDemandRepairJob(final Builder builder) { @@ -60,9 +62,8 @@ private VnodeOnDemandRepairJob(final Builder builder) builder.repairLockType, builder.onFinishedHook, builder.tableRepairMetrics, builder.ongoingJob); myRepairHistory = Preconditions.checkNotNull(builder.repairHistory, "Repair history must be set"); - + myTotalTokens = getOngoingJob().getTokens().size(); myTasks = createRepairTasks(getOngoingJob().getTokens(), getOngoingJob().getRepairedTokens()); - myTotalTasks = myTasks.size(); } private Map> createRepairTasks( @@ -187,8 +188,16 @@ public ScheduledJob.State getState() public double getProgress() { - int finishedTasks = myTotalTasks - myTasks.size(); - return myTotalTasks == 0 ? 1 : (double) finishedTasks / myTotalTasks; + if (myTotalTokens == 0) + { + LOG.debug("Total tokens for this job are 0"); + return 0; + } + + OngoingJob ongoingJob = getOngoingJob(); + Status state = ongoingJob.getStatus(); + int repairedTokens = ongoingJob.getRepairedTokens().size(); + return state == Status.finished ? 1 : (double) repairedTokens / myTotalTokens; } @Override diff --git a/core/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/repair/TestVnodeOnDemandRepairJob.java b/core/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/repair/TestVnodeOnDemandRepairJob.java index 449eeef4f..089640d0f 100644 --- a/core/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/repair/TestVnodeOnDemandRepairJob.java +++ b/core/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/repair/TestVnodeOnDemandRepairJob.java @@ -92,7 +92,7 @@ public void finalVerification() @Test public void testJobCorrectlyReturned() { - VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(); + VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(0); OnDemandRepairJobView expectedView = new OnDemandRepairJobView(repairJob.getId(), myHostId, myTableReference, OnDemandRepairJobView.Status.IN_QUEUE, 0, System.currentTimeMillis(), RepairOptions.RepairType.VNODE); assertThat(repairJob.getId()).isEqualTo(repairJob.getId()); @@ -106,7 +106,7 @@ public void testJobCorrectlyReturned() @Test public void testFailedJobCorrectlyReturned() { - VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(); + VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(0); Iterator it = repairJob.iterator(); repairJob.postExecute(false, it.next()); OnDemandRepairJobView expectedView = new OnDemandRepairJobView(repairJob.getId(), myHostId, myTableReference, @@ -121,7 +121,7 @@ public void testFailedJobCorrectlyReturned() @Test public void testJobFinishedAfterExecution() { - VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(); + VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(0); Iterator it = repairJob.iterator(); assertThat(repairJob.getState()).isEqualTo(ScheduledJob.State.RUNNABLE); repairJob.postExecute(true, it.next()); @@ -143,7 +143,7 @@ public void testJobFinishedAfterRestart() @Test public void testJobFailedWhenTopologyChange() { - VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(); + VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(0); when(myOngoingJob.hasTopologyChanged()).thenReturn(true); assertThat(repairJob.getState()).isEqualTo(ScheduledJob.State.FAILED); } @@ -151,7 +151,7 @@ public void testJobFailedWhenTopologyChange() @Test public void testJobUnsuccessful() { - VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(); + VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(0); Iterator it = repairJob.iterator(); repairJob.postExecute(true, it.next()); assertThat(repairJob.getState()).isEqualTo(ScheduledJob.State.RUNNABLE); @@ -162,16 +162,20 @@ public void testJobUnsuccessful() @Test public void testGetProgress() { - VnodeOnDemandRepairJob repairJob = createVnodeOnDemandRepairJob(); - assertThat(repairJob.getProgress()).isEqualTo(0); - Iterator it = repairJob.iterator(); - repairJob.postExecute(true, it.next()); - assertThat(repairJob.getProgress()).isEqualTo(0.5); - repairJob.postExecute(true, it.next()); - assertThat(repairJob.getProgress()).isEqualTo(1); + VnodeOnDemandRepairJob repairJobZeroProgress = createVnodeOnDemandRepairJob(0); + assertThat(repairJobZeroProgress.getProgress()).isEqualTo(0); + + VnodeOnDemandRepairJob repairJobHalfProgress = createVnodeOnDemandRepairJob(50); + assertThat(repairJobHalfProgress.getProgress()).isEqualTo(0.5); + + VnodeOnDemandRepairJob repairJobFullProgress = createVnodeOnDemandRepairJob(100); + assertThat(repairJobFullProgress.getProgress()).isEqualTo(1.0); + + when(repairJobHalfProgress.getOngoingJob().getStatus()).thenReturn(OngoingJob.Status.finished); + assertThat(repairJobHalfProgress.getProgress()).isEqualTo(1.0); } - private VnodeOnDemandRepairJob createVnodeOnDemandRepairJob() + private VnodeOnDemandRepairJob createVnodeOnDemandRepairJob(int repairedTokenPercentage) { LongTokenRange range1 = new LongTokenRange(1, 2); LongTokenRange range2 = new LongTokenRange(1, 3); @@ -180,7 +184,19 @@ private VnodeOnDemandRepairJob createVnodeOnDemandRepairJob() ImmutableSet.of(mockReplica1, mockReplica2, mockReplica3)); tokenRangeToReplicas.put(range2, ImmutableSet.of(mockReplica1, mockReplica2)); + + Set repairedTokens = new HashSet<>(); + if (repairedTokenPercentage >= 50) + { + repairedTokens.add(range1); + } + if (repairedTokenPercentage == 100) + { + repairedTokens.add(range2); + } + when(myOngoingJob.getTokens()).thenReturn(tokenRangeToReplicas); + when(myOngoingJob.getRepairedTokens()).thenReturn(repairedTokens); return new VnodeOnDemandRepairJob.Builder() .withJmxProxyFactory(myJmxProxyFactory)