/*
* 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.testing.worker;
import org.gradle.api.Action;
import org.gradle.api.internal.Factory;
import org.gradle.api.internal.tasks.testing.TestClassRunInfo;
import org.gradle.api.internal.tasks.testing.TestResultProcessor;
import org.gradle.api.internal.tasks.testing.WorkerTestClassProcessorFactory;
import org.gradle.messaging.remote.ObjectConnection;
import org.gradle.process.JavaForkOptions;
import org.gradle.process.internal.JavaExecHandleBuilder;
import org.gradle.process.internal.WorkerProcess;
import org.gradle.process.internal.WorkerProcessBuilder;
import org.jmock.Expectations;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.List;
import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.notNullValue;
@RunWith(JMock.class)
public class ForkingTestClassProcessorTest {
private final JUnit4Mockery context = new JUnit4Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
private final WorkerTestClassProcessorFactory processorFactory = context.mock(WorkerTestClassProcessorFactory.class);
private final Factory<WorkerProcessBuilder> workerFactory = context.mock(Factory.class);
private final WorkerProcess workerProcess = context.mock(WorkerProcess.class);
private final RemoteTestClassProcessor worker = context.mock(RemoteTestClassProcessor.class);
private final TestClassRunInfo test1 = context.mock(TestClassRunInfo.class, "test1");
private final TestClassRunInfo test2 = context.mock(TestClassRunInfo.class, "test2");
private final TestResultProcessor resultProcessor = context.mock(TestResultProcessor.class);
private final List<File> appClassPath = asList(new File("classpath.jar"));
private final JavaForkOptions options = context.mock(JavaForkOptions.class);
private final Action<WorkerProcessBuilder> action = context.mock(Action.class);
private final ForkingTestClassProcessor processor = new ForkingTestClassProcessor(workerFactory, processorFactory, options, appClassPath, action);
@Test
public void onFirstTestCaseStartsWorkerProcess() {
expectWorkerProcessStarted();
context.checking(new Expectations() {{
one(worker).processTestClass(test1);
}});
processor.startProcessing(resultProcessor);
processor.processTestClass(test1);
}
@Test
public void onSubsequentTestCaseForwardsTestToWorkerProcess() {
expectWorkerProcessStarted();
context.checking(new Expectations() {{
one(worker).processTestClass(test1);
one(worker).processTestClass(test2);
}});
processor.startProcessing(resultProcessor);
processor.processTestClass(test1);
processor.processTestClass(test2);
}
@Test
public void onEndProcessingWaitsForWorkerProcessToStop() {
expectWorkerProcessStarted();
context.checking(new Expectations() {{
one(worker).processTestClass(test1);
one(worker).stop();
one(workerProcess).waitForStop();
}});
processor.startProcessing(resultProcessor);
processor.processTestClass(test1);
processor.stop();
}
@Test
public void onEndProcessingDoesNothingIfNoTestsProcessed() {
processor.startProcessing(resultProcessor);
processor.stop();
}
private void expectWorkerProcessStarted() {
context.checking(new Expectations() {{
WorkerProcessBuilder builder = context.mock(WorkerProcessBuilder.class);
ObjectConnection connection = context.mock(ObjectConnection.class);
JavaExecHandleBuilder javaCommandBuilder = context.mock(JavaExecHandleBuilder.class);
one(workerFactory).create();
will(returnValue(builder));
one(builder).worker(with(notNullValue(TestWorker.class)));
one(builder).applicationClasspath(appClassPath);
one(builder).setLoadApplicationInSystemClassLoader(true);
one(action).execute(builder);
allowing(builder).getJavaCommand();
will(returnValue(javaCommandBuilder));
one(options).copyTo(javaCommandBuilder);
one(builder).build();
will(returnValue(workerProcess));
allowing(workerProcess).getConnection();
will(returnValue(connection));
one(connection).addIncoming(TestResultProcessor.class, resultProcessor);
one(connection).addOutgoing(RemoteTestClassProcessor.class);
will(returnValue(worker));
one(workerProcess).start();
one(worker).startProcessing();
}});
}
}