@ -15,10 +15,18 @@ import com.atlassian.stash.setting.Settings;
import com.atlassian.stash.setting.SettingsValidationErrors ;
import com.atlassian.stash.setting.SettingsValidationErrors ;
import org.junit.Before ;
import org.junit.Before ;
import org.junit.Test ;
import org.junit.Test ;
import org.junit.runner.RunWith ;
import org.mockito.ArgumentCaptor ;
import org.mockito.Captor ;
import org.mockito.Mock ;
import org.mockito.runners.MockitoJUnitRunner ;
import java.net.URI ;
import java.net.URI ;
import java.util.ArrayList ;
import java.util.ArrayList ;
import java.util.Collection ;
import java.util.Collection ;
import java.util.concurrent.Callable ;
import java.util.concurrent.ScheduledExecutorService ;
import java.util.concurrent.TimeUnit ;
import static org.junit.Assert.assertEquals ;
import static org.junit.Assert.assertEquals ;
import static org.mockito.Mockito.* ;
import static org.mockito.Mockito.* ;
@ -26,22 +34,28 @@ import static org.mockito.Mockito.*;
/ * *
/ * *
* Unit tests for { @link MirrorRepositoryHook }
* Unit tests for { @link MirrorRepositoryHook }
* /
* /
@RunWith ( MockitoJUnitRunner . class )
public class MirrorRepositoryHookTest {
public class MirrorRepositoryHookTest {
private MirrorRepositoryHook hook ;
private MirrorRepositoryHook hook ;
private GitScmCommandBuilder builder ;
private GitScmCommandBuilder builder ;
@Mock
private GitCommand < String > cmd ;
private GitCommand < String > cmd ;
@Mock
private ScheduledExecutorService executor ;
private final String mirrorRepoUrl = "https://stash-mirror.englishtown.com/scm/test/test.git" ;
private final String mirrorRepoUrl = "https://stash-mirror.englishtown.com/scm/test/test.git" ;
private final String username = "test-user" ;
private final String username = "test-user" ;
private final String password = "test-password" ;
private final String password = "test-password" ;
private final String repository = "https://test-user:test-password@stash-mirror.englishtown.com/scm/test/test.git" ;
private final String repository = "https://test-user:test-password@stash-mirror.englishtown.com/scm/test/test.git" ;
@SuppressWarnings ( "unchecked" )
@SuppressWarnings ( "UnusedDeclaration" )
@Captor
ArgumentCaptor < Callable < Void > > argumentCaptor ;
@Before
@Before
public void setup ( ) {
public void setup ( ) {
cmd = mock ( GitCommand . class ) ;
builder = mock ( GitScmCommandBuilder . class ) ;
builder = mock ( GitScmCommandBuilder . class ) ;
when ( builder . command ( anyString ( ) ) ) . thenReturn ( builder ) ;
when ( builder . command ( anyString ( ) ) ) . thenReturn ( builder ) ;
when ( builder . argument ( anyString ( ) ) ) . thenReturn ( builder ) ;
when ( builder . argument ( anyString ( ) ) ) . thenReturn ( builder ) ;
@ -55,7 +69,7 @@ public class MirrorRepositoryHookTest {
GitScm gitScm = mock ( GitScm . class ) ;
GitScm gitScm = mock ( GitScm . class ) ;
when ( gitScm . getCommandBuilderFactory ( ) ) . thenReturn ( builderFactory ) ;
when ( gitScm . getCommandBuilderFactory ( ) ) . thenReturn ( builderFactory ) ;
hook = new MirrorRepositoryHook ( gitScm , mock ( I18nService . class ) ) ;
hook = new MirrorRepositoryHook ( gitScm , mock ( I18nService . class ) , executor ) ;
}
}
@ -67,12 +81,62 @@ public class MirrorRepositoryHookTest {
when ( settings . getString ( eq ( MirrorRepositoryHook . SETTING_USERNAME ) ) ) . thenReturn ( username ) ;
when ( settings . getString ( eq ( MirrorRepositoryHook . SETTING_USERNAME ) ) ) . thenReturn ( username ) ;
when ( settings . getString ( eq ( MirrorRepositoryHook . SETTING_PASSWORD ) ) ) . thenReturn ( password ) ;
when ( settings . getString ( eq ( MirrorRepositoryHook . SETTING_PASSWORD ) ) ) . thenReturn ( password ) ;
Repository repo = mock ( Repository . class ) ;
when ( repo . getName ( ) ) . thenReturn ( "test" ) ;
RepositoryHookContext context = mock ( RepositoryHookContext . class ) ;
RepositoryHookContext context = mock ( RepositoryHookContext . class ) ;
when ( context . getSettings ( ) ) . thenReturn ( settings ) ;
when ( context . getSettings ( ) ) . thenReturn ( settings ) ;
when ( context . getRepository ( ) ) . thenReturn ( repo ) ;
Collection < RefChange > refChanges = new ArrayList < RefChange > ( ) ;
Collection < RefChange > refChanges = new ArrayList < RefChange > ( ) ;
hook . postReceive ( context , refChanges ) ;
hook . postReceive ( context , refChanges ) ;
verifyExecutor ( ) ;
}
@Test
public void testRunMirrorCommand_Retries ( ) throws Exception {
GitScm gitScm = mock ( GitScm . class ) ;
when ( gitScm . getCommandBuilderFactory ( ) ) . thenThrow ( new RuntimeException ( "Intentional unit test exception" ) ) ;
MirrorRepositoryHook hook = new MirrorRepositoryHook ( gitScm , mock ( I18nService . class ) , executor ) ;
hook . runMirrorCommand ( mirrorRepoUrl , username , password , mock ( Repository . class ) ) ;
verify ( executor ) . submit ( argumentCaptor . capture ( ) ) ;
Callable < Void > callable = argumentCaptor . getValue ( ) ;
callable . call ( ) ;
verify ( executor , times ( 1 ) ) . schedule ( argumentCaptor . capture ( ) , anyInt ( ) , any ( TimeUnit . class ) ) ;
callable = argumentCaptor . getValue ( ) ;
callable . call ( ) ;
verify ( executor , times ( 2 ) ) . schedule ( argumentCaptor . capture ( ) , anyInt ( ) , any ( TimeUnit . class ) ) ;
callable = argumentCaptor . getValue ( ) ;
callable . call ( ) ;
verify ( executor , times ( 3 ) ) . schedule ( argumentCaptor . capture ( ) , anyInt ( ) , any ( TimeUnit . class ) ) ;
callable = argumentCaptor . getValue ( ) ;
callable . call ( ) ;
verify ( executor , times ( 4 ) ) . schedule ( argumentCaptor . capture ( ) , anyInt ( ) , any ( TimeUnit . class ) ) ;
callable = argumentCaptor . getValue ( ) ;
callable . call ( ) ;
verify ( executor , times ( 5 ) ) . schedule ( argumentCaptor . capture ( ) , anyInt ( ) , any ( TimeUnit . class ) ) ;
callable = argumentCaptor . getValue ( ) ;
callable . call ( ) ;
// Make sure it is only called 5 times
verify ( executor , times ( 5 ) ) . schedule ( argumentCaptor . capture ( ) , anyInt ( ) , any ( TimeUnit . class ) ) ;
}
private void verifyExecutor ( ) throws Exception {
verify ( executor ) . submit ( argumentCaptor . capture ( ) ) ;
Callable < Void > callable = argumentCaptor . getValue ( ) ;
callable . call ( ) ;
verify ( builder , times ( 1 ) ) . command ( eq ( "push" ) ) ;
verify ( builder , times ( 1 ) ) . command ( eq ( "push" ) ) ;
verify ( builder , times ( 1 ) ) . argument ( eq ( "--mirror" ) ) ;
verify ( builder , times ( 1 ) ) . argument ( eq ( "--mirror" ) ) ;
verify ( builder , times ( 1 ) ) . argument ( eq ( repository ) ) ;
verify ( builder , times ( 1 ) ) . argument ( eq ( repository ) ) ;
@ -96,7 +160,7 @@ public class MirrorRepositoryHookTest {
Settings settings = mock ( Settings . class ) ;
Settings settings = mock ( Settings . class ) ;
when ( settings . getString ( eq ( MirrorRepositoryHook . SETTING_MIRROR_REPO_URL ) , eq ( "" ) ) )
when ( settings . getString ( eq ( MirrorRepositoryHook . SETTING_MIRROR_REPO_URL ) , eq ( "" ) ) )
. thenThrow ( new RuntimeException ( ) )
. thenThrow ( new RuntimeException ( "Intentional unit test exception" ) )
. thenReturn ( "" )
. thenReturn ( "" )
. thenReturn ( "invalid uri" )
. thenReturn ( "invalid uri" )
. thenReturn ( "http://should-not:have-user@stash-mirror.englishtown.com/scm/test/test.git" )
. thenReturn ( "http://should-not:have-user@stash-mirror.englishtown.com/scm/test/test.git" )