package org.sagebionetworks.tool.migration.v3;

import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
 * Test for BatchUtility
 * 
 * @author John
 *
 */
public class BatchUtilityTest {

	
	private BatchWorker mockWorker;
	
	@Before
	public void before(){
		mockWorker = Mockito.mock(BatchWorker.class);
	}
	
	@Ignore
	@Test(expected=DaemonFailedException.class)
	public void testAttemptBatchWithRetryRetryDenominatorTooSmall() throws Exception{
		List<Long> batch = Arrays.asList(1l,2l);
		// Only one attempt should be made
		when(mockWorker.attemptBatch(any(List.class))).thenThrow(new DaemonFailedException(), new IllegalArgumentException());
		BatchUtility.attemptBatchWithRetry(mockWorker, batch);
	}
	
	@Test
	public void testAttemptBatchWithRetryHappyCase() throws Exception{
		List<Long> batch = Arrays.asList(1l,2l);
		// Only one attempt should be made
		when(mockWorker.attemptBatch(batch)).thenReturn(2L);
		BatchUtility.attemptBatchWithRetry(mockWorker, batch);
		verify(mockWorker, times(1)).attemptBatch(batch);
	}
	
	@Test
	public void testAttemptBatchWithRetryRetryLessThanList() throws Exception{
		List<Long> batch = Arrays.asList(1l,2l,3l,4l);
		// The full list should fail.
		when(mockWorker.attemptBatch(batch)).thenThrow(new DaemonFailedException());
		// One is okay
		when(mockWorker.attemptBatch(Arrays.asList(1l))).thenReturn(1L);
		// two should fail
		when(mockWorker.attemptBatch(Arrays.asList(2l))).thenThrow(new DaemonFailedException("two failed"));
		// three and four are okay
		when(mockWorker.attemptBatch(Arrays.asList(3l))).thenReturn(1L);
		when(mockWorker.attemptBatch(Arrays.asList(4l))).thenReturn(1L);
		try{
			BatchUtility.attemptBatchWithRetry(mockWorker, batch);
			fail("should have failed");
		}catch(DaemonFailedException e){
			// expected
			assertEquals("two failed", e.getMessage());
		}
		verify(mockWorker).attemptBatch(Arrays.asList(1l,2l,3l,4l));

	}
	
	@Test
	public void testAttemptBatchWithRetryOdd() throws Exception{
		List<Long> batch = Arrays.asList(1l,2l,3l,4l,5l);
		// The full list should fail.
		when(mockWorker.attemptBatch(batch)).thenThrow(new DaemonFailedException());
		// First two okay
		when(mockWorker.attemptBatch(Arrays.asList(1l,2l))).thenReturn(2L);
		// Last next two okay
		when(mockWorker.attemptBatch(Arrays.asList(3l,4l))).thenReturn(2L);
		// Last fail
		when(mockWorker.attemptBatch(Arrays.asList(5l))).thenThrow(new DaemonFailedException("five failed"));
		try{
			BatchUtility.attemptBatchWithRetry(mockWorker, batch);
			fail("should have failed");
		}catch(DaemonFailedException e){
			// expected
			assertEquals("five failed", e.getMessage());
		}

	}
}

@@ -508,425 +508,16 @@
 %0A%09%0D%0A
-%09@Ignore%0D%0A%09@Test(expected=DaemonFailedException.class)%0D%0A%09public void testAttemptBatchWithRetryRetryDenominatorTooSmall() throws Exception%7B%0D%0A%09%09List%3CLong%3E batch = Arrays.asList(1l,2l);%0D%0A%09%09// Only one attempt should be made%0D%0A%09%09when(mockWorker.attemptBatch(any(List.class))).thenThrow(new DaemonFailedException(), new IllegalArgumentException());%0D%0A%09%09BatchUtility.attemptBatchWithRetry(mockWorker, batch);%0D%0A%09%7D%0D%0A%09%0D%0A
 %09@Test%0D%0A
 %09pub
@@ -504,32 +504,32 @@
 %0A%09%7D%0D%0A%09%0D%0A%09@Test%0D%0A
+
 %09public void tes
@@ -1631,26 +1631,46 @@
 Equals(%22
-two failed
+Failed ids in batch retry:%09%5B2%5D
 %22, e.get
@@ -2474,27 +2474,948 @@
 Equals(%22
-five failed
+Failed ids in batch retry:%09%5B5%5D%22, e.getMessage());%0D%0A%09%09%7D%0D%0A%0D%0A%09%7D%0D%0A%0D%0A%09@Test%0D%0A%09public void testAttemptBatchWithMultipleFailsOnRetry() throws Exception%7B%0D%0A%09%09List%3CLong%3E batch = Arrays.asList(1l,2l,3l,4l,5l,6l);%0D%0A%09%09// The full list should fail.%0D%0A%09%09when(mockWorker.attemptBatch(batch)).thenThrow(new DaemonFailedException());%0D%0A%09%09// First two okay%0D%0A%09%09when(mockWorker.attemptBatch(Arrays.asList(1l,2l))).thenReturn(2L);%0D%0A%09%09// Last next two okay%0D%0A%09%09when(mockWorker.attemptBatch(Arrays.asList(3l,4l))).thenReturn(2L);%0D%0A%09%09// Last 2 fail%0D%0A%09%09when(mockWorker.attemptBatch(Arrays.asList(5l))).thenThrow(new DaemonFailedException(%22five failed%22));%0D%0A%09%09when(mockWorker.attemptBatch(Arrays.asList(6l))).thenThrow(new DaemonFailedException(%22six failed%22));%0D%0A%09%09try%7B%0D%0A%09%09%09BatchUtility.attemptBatchWithRetry(mockWorker, batch);%0D%0A%09%09%09fail(%22should have failed%22);%0D%0A%09%09%7Dcatch(DaemonFailedException e)%7B%0D%0A%09%09%09// expected%0D%0A%09%09%09assertEquals(%22Failed ids in batch retry:%09%5B5, 6%5D
 %22, e.get

Fix test