/*
* Copyright 2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.api.internal.tasks;
import org.gradle.api.Action;
import org.gradle.api.Task;
import org.gradle.api.execution.TaskActionListener;
import org.gradle.api.internal.TaskInternal;
import org.gradle.api.internal.project.ProjectInternal;
import org.gradle.logging.StandardOutputCapture;
import org.gradle.api.tasks.StopActionException;
import org.gradle.api.tasks.StopExecutionException;
import org.gradle.api.tasks.TaskExecutionException;
import org.gradle.groovy.scripts.ScriptSource;
import org.gradle.util.JUnit4GroovyMockery;
import org.jmock.Expectations;
import org.jmock.Sequence;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.gradle.util.Matchers.*;
import static org.gradle.util.WrapUtil.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@RunWith(JMock.class)
public class DefaultTaskExecuterTest {
private final JUnit4Mockery context = new JUnit4GroovyMockery();
private final TaskInternal task = context.mock(TaskInternal.class, "<task>");
private final Action<Task> action1 = context.mock(Action.class, "action1");
private final Action<Task> action2 = context.mock(Action.class, "action2");
private final TaskStateInternal state = context.mock(TaskStateInternal.class);
private final ScriptSource scriptSource = context.mock(ScriptSource.class);
private final StandardOutputCapture standardOutputCapture = context.mock(StandardOutputCapture.class);
private final Sequence sequence = context.sequence("seq");
private final TaskActionListener listener = context.mock(TaskActionListener.class);
private final DefaultTaskExecuter executer = new DefaultTaskExecuter(listener);
@Before
public void setUp() {
context.checking(new Expectations(){{
ProjectInternal project = context.mock(ProjectInternal.class);
allowing(task).getProject();
will(returnValue(project));
allowing(project).getBuildScriptSource();
will(returnValue(scriptSource));
allowing(task).getStandardOutputCapture();
will(returnValue(standardOutputCapture));
ignoring(scriptSource);
}});
}
@Test
public void doesNothingWhenTaskHasNoActions() {
context.checking(new Expectations() {{
allowing(task).getActions();
will(returnValue(toList()));
one(listener).beforeActions(task);
inSequence(sequence);
one(state).setExecuting(true);
inSequence(sequence);
one(state).executed(null);
inSequence(sequence);
one(state).setExecuting(false);
inSequence(sequence);
one(listener).afterActions(task);
inSequence(sequence);
}});
executer.execute(task, state);
}
@Test
public void executesEachActionInOrder() {
context.checking(new Expectations() {{
allowing(task).getActions();
will(returnValue(toList(action1, action2)));
one(listener).beforeActions(task);
inSequence(sequence);
one(state).setExecuting(true);
inSequence(sequence);
one(state).setDidWork(true);
inSequence(sequence);
one(standardOutputCapture).start();
inSequence(sequence);
one(action1).execute(task);
inSequence(sequence);
one(standardOutputCapture).stop();
inSequence(sequence);
one(state).setDidWork(true);
inSequence(sequence);
one(standardOutputCapture).start();
inSequence(sequence);
one(action2).execute(task);
inSequence(sequence);
one(standardOutputCapture).stop();
inSequence(sequence);
one(state).executed(null);
inSequence(sequence);
one(state).setExecuting(false);
inSequence(sequence);
one(listener).afterActions(task);
inSequence(sequence);
}});
executer.execute(task, state);
}
@Test
public void stopsAtFirstActionWhichThrowsException() {
final Throwable failure = new RuntimeException("failure");
final Collector<Throwable> wrappedFailure = collector();
context.checking(new Expectations() {{
allowing(task).getActions();
will(returnValue(toList(action1, action2)));
one(listener).beforeActions(task);
inSequence(sequence);
one(state).setExecuting(true);
inSequence(sequence);
one(state).setDidWork(true);
inSequence(sequence);
one(standardOutputCapture).start();
inSequence(sequence);
one(action1).execute(task);
will(throwException(failure));
inSequence(sequence);
one(standardOutputCapture).stop();
inSequence(sequence);
one(state).executed(with(notNullValue(Throwable.class)));
will(collectTo(wrappedFailure));
inSequence(sequence);
one(state).setExecuting(false);
inSequence(sequence);
one(listener).afterActions(task);
inSequence(sequence);
}});
executer.execute(task, state);
assertThat(wrappedFailure.get(), instanceOf(TaskExecutionException.class));
TaskExecutionException exception = (TaskExecutionException) wrappedFailure.get();
assertThat(exception.getTask(), equalTo((Task) task));
assertThat(exception.getMessage(), equalTo("Execution failed for <task>."));
assertThat(exception.getCause(), sameInstance(failure));
}
@Test
public void stopsAtFirstActionWhichThrowsStopExecutionException() {
context.checking(new Expectations() {{
allowing(task).getActions();
will(returnValue(toList(action1, action2)));
one(listener).beforeActions(task);
inSequence(sequence);
one(state).setExecuting(true);
inSequence(sequence);
one(state).setDidWork(true);
inSequence(sequence);
one(standardOutputCapture).start();
inSequence(sequence);
one(action1).execute(task);
will(throwException(new StopExecutionException("stop")));
inSequence(sequence);
one(standardOutputCapture).stop();
inSequence(sequence);
one(state).executed(null);
inSequence(sequence);
one(state).setExecuting(false);
inSequence(sequence);
one(listener).afterActions(task);
inSequence(sequence);
}});
executer.execute(task, state);
}
@Test
public void skipsActionWhichThrowsStopActionException() {
context.checking(new Expectations() {{
allowing(task).getActions();
will(returnValue(toList(action1, action2)));
one(listener).beforeActions(task);
inSequence(sequence);
one(state).setExecuting(true);
inSequence(sequence);
one(state).setDidWork(true);
inSequence(sequence);
one(standardOutputCapture).start();
inSequence(sequence);
one(action1).execute(task);
will(throwException(new StopActionException("stop")));
inSequence(sequence);
one(standardOutputCapture).stop();
inSequence(sequence);
one(state).setDidWork(true);
inSequence(sequence);
one(standardOutputCapture).start();
inSequence(sequence);
one(action2).execute(task);
inSequence(sequence);
one(standardOutputCapture).stop();
inSequence(sequence);
one(state).executed(null);
inSequence(sequence);
one(state).setExecuting(false);
inSequence(sequence);
one(listener).afterActions(task);
inSequence(sequence);
}});
executer.execute(task, state);
}
}