/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockitousage.serialization;
import org.junit.Test;
import org.mockitousage.IMethods;
import org.mockitoutil.SimpleSerializationUtil;
import java.nio.charset.CharacterCodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.withSettings;
public class ParallelSerializationTest {
@Test
public void single_mock_being_serialized_in_different_classloaders_by_multiple_threads() throws ExecutionException, InterruptedException {
// given
int iterations = 2;
int threadingFactor = 200;
final ExecutorService executorService = Executors.newFixedThreadPool(threadingFactor);
final IMethods iMethods_that_store_invocations = mock(IMethods.class, withSettings().serializable());
// when
for (int i = 0; i <= iterations; i++) {
List<Future> futures = new ArrayList<Future>(threadingFactor);
final CyclicBarrier barrier_that_will_wait_until_threads_are_ready = new CyclicBarrier(threadingFactor);
// prepare all threads by submitting a callable
// - that will serialize the mock a 'threadingFactor' times
// - that will use the mock a 'threadingFactor' times
for (int j = 0; j < threadingFactor; j++) {
// submit a callable that will serialize the mock 'iMethods'
futures.add(executorService.submit(new Callable<Object>() {
public Object call() throws Exception {
barrier_that_will_wait_until_threads_are_ready.await();
randomCallOn(iMethods_that_store_invocations);
return SimpleSerializationUtil.serializeMock(iMethods_that_store_invocations).toByteArray();
}
}));
// submit a callable that will only use the mock 'iMethods'
executorService.submit(new Callable<Object>() {
public Object call() throws Exception {
barrier_that_will_wait_until_threads_are_ready.await();
return iMethods_that_store_invocations.longObjectReturningMethod();
}
});
}
// ensure we are getting the futures
for (Future future : futures) {
future.get();
}
}
}
private void randomCallOn(IMethods iMethods) throws CharacterCodingException {
int random = new Random().nextInt(10);
switch (random) {
case 0 : iMethods.arrayReturningMethod(); break;
case 1 : iMethods.longObjectReturningMethod(); break;
case 2 : iMethods.linkedListReturningMethod(); break;
case 3 : iMethods.iMethodsReturningMethod(); break;
case 4 : iMethods.canThrowException(); break;
case 5 : iMethods.differentMethod(); break;
case 6 : iMethods.voidMethod(); break;
case 7 : iMethods.varargsString(1, ""); break;
case 8 : iMethods.forMap(null); break;
case 9 : iMethods.throwsNothing(false); break;
default:
}
}
}