package com.ldbc.driver.runtime.executor; import com.ldbc.driver.Db; import com.ldbc.driver.Operation; import com.ldbc.driver.WorkloadStreams; import com.ldbc.driver.control.Log4jLoggingServiceFactory; import com.ldbc.driver.control.LoggingService; import com.ldbc.driver.runtime.ConcurrentErrorReporter; import com.ldbc.driver.runtime.DefaultQueues; import com.ldbc.driver.runtime.coordination.DummyGlobalCompletionTimeReader; import com.ldbc.driver.runtime.coordination.DummyLocalCompletionTimeWriter; import com.ldbc.driver.runtime.coordination.LocalCompletionTimeWriter; import com.ldbc.driver.runtime.metrics.DummyCountingMetricsService; import com.ldbc.driver.runtime.scheduling.Spinner; import com.ldbc.driver.temporal.SystemTimeSource; import com.ldbc.driver.temporal.TimeSource; import com.ldbc.driver.workloads.dummy.DummyDb; import com.ldbc.driver.workloads.dummy.DummyWorkload; import com.ldbc.driver.workloads.dummy.NothingOperation; import org.junit.Test; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; public class ThreadPoolOperationExecutorTest { @Test public void executorShouldReturnExpectedResult() throws Exception { // Given LoggingService loggingService = new Log4jLoggingServiceFactory( false ).loggingServiceFor( "Test" ); TimeSource timeSource = new SystemTimeSource(); boolean ignoreScheduledStartTime = false; ConcurrentErrorReporter errorReporter = new ConcurrentErrorReporter(); Spinner spinner = new Spinner( timeSource, Spinner.DEFAULT_SLEEP_DURATION_10_MILLI, ignoreScheduledStartTime ); LocalCompletionTimeWriter dummyLocalCompletionTimeWriter = new DummyLocalCompletionTimeWriter(); DummyGlobalCompletionTimeReader dummyGlobalCompletionTimeReader = new DummyGlobalCompletionTimeReader(); dummyGlobalCompletionTimeReader.setGlobalCompletionTimeAsMilli( Long.MAX_VALUE ); DummyCountingMetricsService metricsService = new DummyCountingMetricsService(); WorkloadStreams.WorkloadStreamDefinition streamDefinition = new WorkloadStreams.WorkloadStreamDefinition( new HashSet<Class<? extends Operation>>(), new HashSet<Class<? extends Operation>>(), Collections.<Operation>emptyIterator(), Collections.<Operation>emptyIterator(), null ); Db db = new DummyDb(); db.init( new HashMap<String,String>(), loggingService, DummyWorkload.OPERATION_TYPE_CLASS_MAPPING ); int threadCount = 1; int boundedQueueSize = DefaultQueues.DEFAULT_BOUND_1000; OperationExecutor executor = new ThreadPoolOperationExecutor( threadCount, boundedQueueSize, db, streamDefinition, dummyLocalCompletionTimeWriter, dummyGlobalCompletionTimeReader, spinner, timeSource, errorReporter, metricsService, streamDefinition.childOperationGenerator() ); Operation operation = new NothingOperation(); operation.setScheduledStartTimeAsMilli( timeSource.nowAsMilli() + 200 ); operation.setTimeStamp( timeSource.nowAsMilli() + 200 ); operation.setDependencyTimeStamp( 0l ); // When executor.execute( operation ); while ( executor.uncompletedOperationHandlerCount() > 0 ) { // wait for handler to finish Spinner.powerNap( 100 ); } // Then assertThat( metricsService.count(), is( 1l ) ); executor.shutdown( 1000l ); assertThat( errorReporter.toString(), errorReporter.errorEncountered(), is( false ) ); } @Test public void executorShouldReturnAllResults() throws Exception { // Given LoggingService loggingService = new Log4jLoggingServiceFactory( false ).loggingServiceFor( "Test" ); TimeSource timeSource = new SystemTimeSource(); boolean ignoreScheduledStartTime = false; ConcurrentErrorReporter errorReporter = new ConcurrentErrorReporter(); Spinner spinner = new Spinner( timeSource, Spinner.DEFAULT_SLEEP_DURATION_10_MILLI, ignoreScheduledStartTime ); LocalCompletionTimeWriter dummyLocalCompletionTimeWriter = new DummyLocalCompletionTimeWriter(); DummyGlobalCompletionTimeReader dummyGlobalCompletionTimeReader = new DummyGlobalCompletionTimeReader(); dummyGlobalCompletionTimeReader.setGlobalCompletionTimeAsMilli( Long.MAX_VALUE ); DummyCountingMetricsService metricsService = new DummyCountingMetricsService(); WorkloadStreams.WorkloadStreamDefinition streamDefinition = new WorkloadStreams.WorkloadStreamDefinition( new HashSet<Class<? extends Operation>>(), new HashSet<Class<? extends Operation>>(), Collections.<Operation>emptyIterator(), Collections.<Operation>emptyIterator(), null ); Db db = new DummyDb(); db.init( new HashMap<String,String>(), loggingService, DummyWorkload.OPERATION_TYPE_CLASS_MAPPING ); int threadCount = 1; int boundedQueueSize = DefaultQueues.DEFAULT_BOUND_1000; OperationExecutor executor = new ThreadPoolOperationExecutor( threadCount, boundedQueueSize, db, streamDefinition, dummyLocalCompletionTimeWriter, dummyGlobalCompletionTimeReader, spinner, timeSource, errorReporter, metricsService, streamDefinition.childOperationGenerator() ); Operation operation1 = new NothingOperation(); operation1.setScheduledStartTimeAsMilli( timeSource.nowAsMilli() + 100l ); operation1.setTimeStamp( operation1.scheduledStartTimeAsMilli() ); operation1.setDependencyTimeStamp( 0l ); Operation operation2 = new NothingOperation(); operation2.setScheduledStartTimeAsMilli( operation1.scheduledStartTimeAsMilli() + 100l ); operation2.setTimeStamp( operation2.scheduledStartTimeAsMilli() ); operation2.setDependencyTimeStamp( 0l ); // When executor.execute( operation1 ); executor.execute( operation2 ); while ( executor.uncompletedOperationHandlerCount() > 0 ) { // wait for handler to finish Spinner.powerNap( 100 ); } // Then assertThat( metricsService.count(), is( 2l ) ); executor.shutdown( 1000l ); assertThat( errorReporter.toString(), errorReporter.errorEncountered(), is( false ) ); } @Test public void executorShouldThrowExceptionIfShutdownMultipleTimes() throws Exception { // Given LoggingService loggingService = new Log4jLoggingServiceFactory( false ).loggingServiceFor( "Test" ); TimeSource timeSource = new SystemTimeSource(); boolean ignoreScheduledStartTime = false; ConcurrentErrorReporter errorReporter = new ConcurrentErrorReporter(); Spinner spinner = new Spinner( timeSource, Spinner.DEFAULT_SLEEP_DURATION_10_MILLI, ignoreScheduledStartTime ); LocalCompletionTimeWriter dummyLocalCompletionTimeWriter = new DummyLocalCompletionTimeWriter(); DummyGlobalCompletionTimeReader dummyGlobalCompletionTimeReader = new DummyGlobalCompletionTimeReader(); dummyGlobalCompletionTimeReader.setGlobalCompletionTimeAsMilli( Long.MAX_VALUE ); DummyCountingMetricsService metricsService = new DummyCountingMetricsService(); WorkloadStreams.WorkloadStreamDefinition streamDefinition = new WorkloadStreams.WorkloadStreamDefinition( new HashSet<Class<? extends Operation>>(), new HashSet<Class<? extends Operation>>(), Collections.<Operation>emptyIterator(), Collections.<Operation>emptyIterator(), null ); Db db = new DummyDb(); db.init( new HashMap<String,String>(), loggingService, DummyWorkload.OPERATION_TYPE_CLASS_MAPPING ); int threadCount = 1; int boundedQueueSize = DefaultQueues.DEFAULT_BOUND_1000; OperationExecutor executor = new ThreadPoolOperationExecutor( threadCount, boundedQueueSize, db, streamDefinition, dummyLocalCompletionTimeWriter, dummyGlobalCompletionTimeReader, spinner, timeSource, errorReporter, metricsService, streamDefinition.childOperationGenerator() ); Operation operation = new NothingOperation(); operation.setScheduledStartTimeAsMilli( timeSource.nowAsMilli() + 200l ); operation.setTimeStamp( timeSource.nowAsMilli() + 200l ); operation.setDependencyTimeStamp( 0l ); // When executor.execute( operation ); while ( executor.uncompletedOperationHandlerCount() > 0 ) { // wait for handler to finish Spinner.powerNap( 100 ); } // Then assertThat( metricsService.count(), is( 1l ) ); executor.shutdown( 1000l ); assertThat( errorReporter.toString(), errorReporter.errorEncountered(), is( false ) ); boolean exceptionThrown = false; try { executor.shutdown( 1000l ); } catch ( OperationExecutorException e ) { exceptionThrown = true; } assertThat( exceptionThrown, is( true ) ); assertThat( errorReporter.toString(), errorReporter.errorEncountered(), is( false ) ); } }