package pl.allegro.tech.search.elasticsearch.tools.reindex.process; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.junit.Test; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.IntStream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class ProcessSynchronizerTest { public static final int QUERY_SEGMENT_SIZE = 3; @Test public void shouldHasDataToBeIndexedBeTrueWhenWorkingQueueIsNotEmpty() throws Exception { //given ProcessSynchronizer processSynchronizer = new ProcessSynchronizer(QUERY_SEGMENT_SIZE); //when boolean result = processSynchronizer.hasDataToBeIndexed(); //then assertTrue(result); } @Test public void shouldHasDataToBeIndexedBeTrueWhenDataQueueIsNotEmpty() throws Exception { //given ProcessSynchronizer processSynchronizer = new ProcessSynchronizer(QUERY_SEGMENT_SIZE); setupDataQueueForProcessSynchronizer(processSynchronizer); //when boolean result = processSynchronizer.hasDataToBeIndexed(); //then assertTrue(result); } private void setupDataQueueForProcessSynchronizer(ProcessSynchronizer processSynchronizer) { IntStream.range(0, QUERY_SEGMENT_SIZE).forEach(i -> processSynchronizer.subtractWorkingQueryProcess()); IntStream.range(0, ProcessConfiguration.getInstance().getUpdateThreadsCount()).forEach(i -> processSynchronizer .subtractWorkingUpdatesProcess()); processSynchronizer.tryFillQueueWithSearchHits(createSearchResponse()); } @Test public void shouldHasDataToBeIndexedBeFalseWhenDataQueueIsEmptyAndDataQueueIsEmpty() throws Exception { //given ProcessSynchronizer processSynchronizer = new ProcessSynchronizer(QUERY_SEGMENT_SIZE); IntStream.range(0, QUERY_SEGMENT_SIZE).forEach(i -> processSynchronizer.subtractWorkingQueryProcess()); //when boolean result = processSynchronizer.hasDataToBeIndexed(); //then assertFalse(result); } @Test public void shouldPollWhatHasPulled() throws Exception { //given ProcessSynchronizer processSynchronizer = new ProcessSynchronizer(QUERY_SEGMENT_SIZE); SearchResponse searchResponse = createSearchResponse(); processSynchronizer.tryFillQueueWithSearchHits(searchResponse); //when SearchHits searchHits = processSynchronizer.pollDataToIndexed(); //then assertEquals(searchResponse.getHits(), searchHits); } @Test public void shouldReturnEmptyHitsWhenPoolingWithTimeout() throws Exception { //given ProcessSynchronizer processSynchronizer = new ProcessSynchronizer(QUERY_SEGMENT_SIZE); //when SearchHits searchHits = processSynchronizer.pollDataToIndexed(); //then assertEquals(0, searchHits.getTotalHits()); } @Test public void shouldNotWaitForProcessesToEndWhenWorkingQueueIsEmpty() throws Exception { //given ProcessSynchronizer processSynchronizer = new ProcessSynchronizer(QUERY_SEGMENT_SIZE); IntStream.range(0, QUERY_SEGMENT_SIZE).forEach(i -> processSynchronizer.subtractWorkingQueryProcess()); IntStream.range(0, ProcessConfiguration.getInstance().getUpdateThreadsCount()).forEach(i -> processSynchronizer.subtractWorkingUpdatesProcess()); //when processSynchronizer.waitForProcessesToEnd(); //then assertFalse(Thread.currentThread().isInterrupted()); } @Test public void shouldWaitTillQueriesLatchReleased() throws Exception { //given ProcessSynchronizer processSynchronizer = new ProcessSynchronizer(QUERY_SEGMENT_SIZE); final AtomicBoolean waitedTillSubtractWorkingQueryProcessDone = new AtomicBoolean(); createTimerReleasingAllProcessesAfterSecond(processSynchronizer, waitedTillSubtractWorkingQueryProcessDone); //when processSynchronizer.waitForProcessesToEnd(); //then assertEquals(true, waitedTillSubtractWorkingQueryProcessDone.get()); } private void createTimerReleasingAllProcessesAfterSecond(ProcessSynchronizer processSynchronizer, AtomicBoolean waitedTillSubtractWorkingQueryProcessDone) { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { waitedTillSubtractWorkingQueryProcessDone.set(true); IntStream.range(0, QUERY_SEGMENT_SIZE).forEach(i -> processSynchronizer.subtractWorkingQueryProcess()); IntStream.range(0, ProcessConfiguration.getInstance().getUpdateThreadsCount()).forEach(i -> processSynchronizer.subtractWorkingUpdatesProcess()); } }, 1000); } private SearchResponse createSearchResponse() { SearchResponse searchResponse = mock(SearchResponse.class); SearchHits searchHits = mock(SearchHits.class); when(searchHits.getHits()).thenReturn(new SearchHit[0]); when(searchResponse.getHits()).thenReturn(searchHits); return searchResponse; } }