TaskCarousel java
Помогите разобраться почему не проходит тест, хотя при запуске кода в Main вручную, вывод валидный.
Каждый раз при вызове метода execute(), карусель должна переключаться на следующую задачу внутри и выполнять ее. Класс каждый раз, когда вызывается метод execute() класса CountDownLatch, это значение уменьшается на единицу, пока не достигнет нуля. После этого метод execute больше не уменьшает значение, и задача считается завершенной.
Исключение теста: org.opentest4j.AssertionFailedError: Assertion fail on step [false, false, 3, 2, 1, 0, true] ==> Expected :3 Actual :4
public class Main {
public static void main(String[] args) {
TaskCarousel carousel = new TaskCarousel(4);
CountDownTask task1 = new CountDownTask(4);
CountDownTask task2 = new CountDownTask(3);
CountDownTask task3 = new CountDownTask(2);
CountDownTask task4 = new CountDownTask(1);
System.out.println(carousel.addTask(task1));
System.out.println(carousel.addTask(task2));
System.out.println(carousel.addTask(task3));
System.out.println(carousel.addTask(task4));
System.out.println(task1.getValue());
System.out.println(task2.getValue());
System.out.println(task3.getValue());
System.out.println(task4.getValue());
System.out.println(carousel.execute()); // 3
System.out.println(carousel.execute()); // 2
System.out.println(carousel.execute()); // 1
System.out.println(carousel.execute()); // 0
// System.out.println(carousel.execute()); // 2
// System.out.println(carousel.execute()); // 1
// System.out.println(carousel.execute()); // 0
//
// System.out.println(carousel.execute()); // 1
// System.out.println(carousel.execute()); // 0
//
// System.out.println(carousel.execute()); // 0
System.out.println(task1.getValue());
System.out.println(task2.getValue());
System.out.println(task3.getValue());
System.out.println(task4.getValue());
}
}
public class TaskCarousel {
private final List<Task> tasks;
private final int capacity;
private int counter = -1;
public TaskCarousel(int capacity) {
this.capacity = capacity;
this.tasks = new LinkedList<>();
}
public boolean addTask(Task task) {
int value = 1;
if(task instanceof CountDownTask) value = ((CountDownTask) task).getValue();
if(!task.isFinished() && !isFull() && value != 0) {
return tasks.add(task);
}
return false;
}
public boolean execute() {
counter++;
if (!isEmpty()) {
if(counter == tasks.size()) counter = 0;
Task task = tasks.get(counter);
// вызывается метод CountDownLatch
task.execute();
if(task.isFinished()) {
tasks.remove(task);
counter--;
}
return true;
}
return false;
}
public boolean isFull() {
return tasks.size() == capacity;
}
public boolean isEmpty() {
return tasks.isEmpty();
}
}
public class CountDownTask implements Task{
private int value;
public CountDownTask(int value) {
if(value < 0) this.value = 0;
else this.value = value;
}
public int getValue() {
return value;
}
@Override
public void execute() {
if(!isFinished()) value--;
}
@Override
public boolean isFinished() {
return value == 0;
}
}
А вот код теста:
@Test
void testFourTasksWorkflow2() {
TaskCarousel carousel = new TaskCarousel(4);
assertTrue(carousel.isEmpty());
assertFalse(carousel.isFull());
assertFalse(carousel.execute());
CountDownTask[] tasks = new CountDownTask[4];
for (int i = 0; i < 4; i++) {
tasks[i] = new CountDownTask(4 - i);
assertTrue(carousel.addTask(tasks[i]));
}
Object[][] expectedSteps = new Object[][]{
{false, true, 4, 3, 2, 1, true},
{false, false, 3, 2, 1, 0, true},
{false, false, 2, 1, 0, 0, true},
{false, false, 1, 0, 0, 0, true},
{true, false, 0, 0, 0, 0, false}
};
for (Object[] expectedStep : expectedSteps) {
String errMsg = "Assertion fail on step " + Arrays.deepToString(expectedStep);
assertEquals(expectedStep[0], carousel.isEmpty(), errMsg);
assertEquals(expectedStep[1], carousel.isFull(), errMsg);
assertEquals(expectedStep[2], tasks[0].getValue(), errMsg);
assertEquals(expectedStep[3], tasks[1].getValue(), errMsg);
assertEquals(expectedStep[4], tasks[2].getValue(), errMsg);
assertEquals(expectedStep[5], tasks[3].getValue(), errMsg);
for (final CountDownTask task : tasks) {
if (!task.isFinished()) {
assertEquals(expectedStep[6], carousel.execute(), errMsg);
}
}
}
}
Ответы (1 шт):
Автор решения: 丹尼尔
→ Ссылка
Просто добавьте counter в проверку if (!isEmpty()) в методе execute:
public boolean execute() {
if (!isEmpty()) {counter++;
if(counter == tasks.size()) counter = 0;
Task task = tasks.get(counter);
// вызывается метод CountDownLatch
task.execute();
if(task.isFinished()) {
tasks.remove(task);
counter--;
}
return true;
}
return false;
}