From fc5316370c39e4433f3ce6c01e5ced949d2ea2c5 Mon Sep 17 00:00:00 2001 From: Adrian Gonzalez Date: Fri, 25 Sep 2015 17:00:03 -0400 Subject: [PATCH] Upgrade to bitbucket server 4.0.1 (WIP) --- README.md | 4 +- pom.xml | 134 +++++------------- .../hook/DefaultPasswordEncryptor.java | 12 +- .../hook/DefaultSettingsReflectionHelper.java | 4 +- .../hook/MirrorRepositoryHook.java | 66 +++++---- .../hook/PasswordEncryptor.java | 2 +- .../hook/PasswordHandler.java | 8 +- .../hook/SettingsReflectionHelper.java | 4 +- src/main/resources/atlassian-plugin.xml | 20 ++- ...rties => bitbucket-hook-mirror.properties} | 2 +- .../static/mirror-repository-hook.soy | 16 +-- .../hook/DefaultPasswordEncryptorTest.java | 2 +- .../DefaultSettingsReflectionHelperTest.java | 107 ++++++++++++++ .../hook/MirrorRepositoryHookTest.java | 108 +++++++------- .../hook/PasswordHandlerTest.java | 4 +- .../DefaultSettingsReflectionHelperTest.java | 36 ----- 16 files changed, 263 insertions(+), 266 deletions(-) rename src/main/java/com/englishtown/{stash => bitbucket}/hook/DefaultPasswordEncryptor.java (88%) rename src/main/java/com/englishtown/{stash => bitbucket}/hook/DefaultSettingsReflectionHelper.java (92%) rename src/main/java/com/englishtown/{stash => bitbucket}/hook/MirrorRepositoryHook.java (85%) rename src/main/java/com/englishtown/{stash => bitbucket}/hook/PasswordEncryptor.java (96%) rename src/main/java/com/englishtown/{stash => bitbucket}/hook/PasswordHandler.java (86%) rename src/main/java/com/englishtown/{stash => bitbucket}/hook/SettingsReflectionHelper.java (80%) rename src/main/resources/{stash-hook-mirror.properties => bitbucket-hook-mirror.properties} (50%) rename src/test/java/com/englishtown/{stash => bitbucket}/hook/DefaultPasswordEncryptorTest.java (98%) create mode 100644 src/test/java/com/englishtown/bitbucket/hook/DefaultSettingsReflectionHelperTest.java rename src/test/java/com/englishtown/{stash => bitbucket}/hook/MirrorRepositoryHookTest.java (75%) rename src/test/java/com/englishtown/{stash => bitbucket}/hook/PasswordHandlerTest.java (94%) delete mode 100644 src/test/java/com/englishtown/stash/hook/DefaultSettingsReflectionHelperTest.java diff --git a/README.md b/README.md index e50125c..43e11d1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ [![Build Status](https://travis-ci.org/englishtown/stash-hook-mirror.png)](https://travis-ci.org/englishtown/stash-hook-mirror) -#Stash Repository Hook for Mirroring +#Bitbucket Server Repository Hook for Mirroring -The following is a plugin for Atlassian Stash to provide repository mirroring to a remote repository. +The following is a plugin for Atlassian Bitbucket Server to provide repository mirroring to a remote repository. * `atlas-run` -- installs this plugin into the product and starts it on localhost diff --git a/pom.xml b/pom.xml index c1ce9a0..a0a8a78 100644 --- a/pom.xml +++ b/pom.xml @@ -6,15 +6,15 @@ com.englishtown stash-hook-mirror - 1.10.0-SNAPSHOT + 2.0.0-SNAPSHOT Englishtown http://www.englishtown.com/ - Repository Mirror Plugin for Stash - A Stash repository hook for mirroring to one or more remote repositories. + Repository Mirror Plugin for Bitbucket Server + A Bitbucket Server repository hook for mirroring to one or more remote repositories. https://github.com/englishtown/stash-hook-mirror 2013 @@ -27,26 +27,20 @@ UTF-8 - 2.6.0 - 2.6.0 - 4.2.20 - 1.1.7 - - 4.10 - 2.6 - 3.1 - 1.8.5 - 2.2.2-atlassian-1 - 1.1.1 - 1.7.5 + + 4.0.1 + ${bitbucket.version} + 3.0.5 + 6.1.0 + - com.atlassian.stash - stash-parent - ${stash.version} + com.atlassian.bitbucket.server + bitbucket-parent + ${bitbucket.version} pom import @@ -55,116 +49,64 @@ - com.atlassian.stash - stash-scm-git-api - provided - - - org.slf4j - slf4j-api - ${slf4j.version} + com.atlassian.bitbucket.server + bitbucket-api provided - com.atlassian.stash - stash-api + com.atlassian.bitbucket.server + bitbucket-spi provided - com.atlassian.stash - stash-spi + com.atlassian.bitbucket.server + bitbucket-git-api provided - com.atlassian.stash - stash-page-objects - provided - - - javax.servlet - servlet-api + com.atlassian.sal + sal-api + ${atlassian-sal-api.version} provided + junit junit - ${junit.version} - test - - - commons-lang - commons-lang - ${common-lang.version} - - - - - com.atlassian.stash - stash-service-impl - test - - - com.atlassian.plugins - atlassian-plugins-osgi-testrunner - ${plugin.testrunner.version} test - - javax.ws.rs - jsr311-api - ${jsr311.version} - provided - - - com.google.code.gson - gson - ${gson.version} - org.mockito - mockito-all - ${mockito.version} - test - - - org.slf4j - slf4j-simple - ${slf4j.version} + mockito-core test + - com.atlassian.maven.plugins - maven-amps-plugin - ${amps.version} - true - - - com.atlassian.maven.plugins - maven-stash-plugin + bitbucket-maven-plugin ${amps.version} true - stash - stash - ${stash.version} - ${stash.data.version} + bitbucket + bitbucket + ${bitbucket.version} + ${bitbucket.data.version} maven-compiler-plugin - ${plugin.compiler.version} + 3.2 - 1.6 - 1.6 + 1.8 + 1.8 @@ -173,12 +115,7 @@ atlassian-public - https://m2proxy.atlassian.com/repository/public - - true - daily - warn - + https://maven.atlassian.com/content/groups/public true warn @@ -189,14 +126,11 @@ atlassian-public - https://m2proxy.atlassian.com/repository/public + https://maven.atlassian.com/content/groups/public true warn - - warn - diff --git a/src/main/java/com/englishtown/stash/hook/DefaultPasswordEncryptor.java b/src/main/java/com/englishtown/bitbucket/hook/DefaultPasswordEncryptor.java similarity index 88% rename from src/main/java/com/englishtown/stash/hook/DefaultPasswordEncryptor.java rename to src/main/java/com/englishtown/bitbucket/hook/DefaultPasswordEncryptor.java index 1f85d2b..0877e2d 100644 --- a/src/main/java/com/englishtown/stash/hook/DefaultPasswordEncryptor.java +++ b/src/main/java/com/englishtown/bitbucket/hook/DefaultPasswordEncryptor.java @@ -1,13 +1,13 @@ -package com.englishtown.stash.hook; +package com.englishtown.bitbucket.hook; import com.atlassian.sal.api.pluginsettings.PluginSettings; -import org.apache.commons.codec.binary.Base64; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.util.Base64; /** * Service to encrypt/decrypt git user passwords @@ -29,11 +29,11 @@ public class DefaultPasswordEncryptor implements PasswordEncryptor { if (value == null || value.toString().isEmpty()) { KeyGenerator gen = KeyGenerator.getInstance("AES"); secretKey = gen.generateKey(); - keyBase64 = Base64.encodeBase64String(secretKey.getEncoded()); + keyBase64 = Base64.getEncoder().encodeToString(secretKey.getEncoded()); pluginSettings.put(SETTINGS_CRYPTO_KEY, keyBase64); } else { keyBase64 = value.toString(); - byte[] data = Base64.decodeBase64(keyBase64); + byte[] data = Base64.getDecoder().decode(keyBase64); secretKey = new SecretKeySpec(data, 0, data.length, "AES"); } @@ -92,7 +92,7 @@ public class DefaultPasswordEncryptor implements PasswordEncryptor { } try { byte[] encryptedData = runCipher(password.getBytes("UTF-8"), true); - return ENCRYPTED_PREFIX + Base64.encodeBase64String(encryptedData); + return ENCRYPTED_PREFIX + Base64.getEncoder().encodeToString(encryptedData); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } @@ -104,7 +104,7 @@ public class DefaultPasswordEncryptor implements PasswordEncryptor { return password; } try { - byte[] encryptedData = Base64.decodeBase64(password.substring(ENCRYPTED_PREFIX.length())); + byte[] encryptedData = Base64.getDecoder().decode(password.substring(ENCRYPTED_PREFIX.length())); byte[] clearData = runCipher(encryptedData, false); return new String(clearData, "UTF-8"); } catch (UnsupportedEncodingException e) { diff --git a/src/main/java/com/englishtown/stash/hook/DefaultSettingsReflectionHelper.java b/src/main/java/com/englishtown/bitbucket/hook/DefaultSettingsReflectionHelper.java similarity index 92% rename from src/main/java/com/englishtown/stash/hook/DefaultSettingsReflectionHelper.java rename to src/main/java/com/englishtown/bitbucket/hook/DefaultSettingsReflectionHelper.java index 00110da..accaf8d 100644 --- a/src/main/java/com/englishtown/stash/hook/DefaultSettingsReflectionHelper.java +++ b/src/main/java/com/englishtown/bitbucket/hook/DefaultSettingsReflectionHelper.java @@ -1,6 +1,6 @@ -package com.englishtown.stash.hook; +package com.englishtown.bitbucket.hook; -import com.atlassian.stash.setting.Settings; +import com.atlassian.bitbucket.setting.Settings; import java.lang.reflect.Field; import java.util.Map; diff --git a/src/main/java/com/englishtown/stash/hook/MirrorRepositoryHook.java b/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java similarity index 85% rename from src/main/java/com/englishtown/stash/hook/MirrorRepositoryHook.java rename to src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java index baf2a74..c337db2 100644 --- a/src/main/java/com/englishtown/stash/hook/MirrorRepositoryHook.java +++ b/src/main/java/com/englishtown/bitbucket/hook/MirrorRepositoryHook.java @@ -1,20 +1,21 @@ -package com.englishtown.stash.hook; - +package com.englishtown.bitbucket.hook; + +import com.atlassian.bitbucket.hook.repository.AsyncPostReceiveRepositoryHook; +import com.atlassian.bitbucket.hook.repository.RepositoryHookContext; +import com.atlassian.bitbucket.i18n.I18nService; +import com.atlassian.bitbucket.repository.RefChange; +import com.atlassian.bitbucket.repository.Repository; +import com.atlassian.bitbucket.repository.RepositoryService; +import com.atlassian.bitbucket.scm.CommandExitHandler; +import com.atlassian.bitbucket.scm.DefaultCommandExitHandler; +import com.atlassian.bitbucket.scm.ScmCommandBuilder; +import com.atlassian.bitbucket.scm.ScmService; +import com.atlassian.bitbucket.scm.git.command.GitScmCommandBuilder; +import com.atlassian.bitbucket.setting.RepositorySettingsValidator; +import com.atlassian.bitbucket.setting.Settings; +import com.atlassian.bitbucket.setting.SettingsValidationErrors; import com.atlassian.sal.api.pluginsettings.PluginSettings; import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory; -import com.atlassian.stash.hook.repository.AsyncPostReceiveRepositoryHook; -import com.atlassian.stash.hook.repository.RepositoryHookContext; -import com.atlassian.stash.i18n.I18nService; -import com.atlassian.stash.repository.RefChange; -import com.atlassian.stash.repository.Repository; -import com.atlassian.stash.repository.RepositoryMetadataService; -import com.atlassian.stash.scm.CommandExitHandler; -import com.atlassian.stash.scm.DefaultCommandExitHandler; -import com.atlassian.stash.scm.git.GitScm; -import com.atlassian.stash.scm.git.GitScmCommandBuilder; -import com.atlassian.stash.setting.RepositorySettingsValidator; -import com.atlassian.stash.setting.Settings; -import com.atlassian.stash.setting.SettingsValidationErrors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,7 +24,6 @@ import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; import java.util.*; -import java.util.concurrent.Callable; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -42,33 +42,33 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep static final String SETTING_PASSWORD = "password"; static final int MAX_ATTEMPTS = 5; - private final GitScm gitScm; + private final ScmService scmService; private final I18nService i18nService; private final ScheduledExecutorService executor; private final PasswordEncryptor passwordEncryptor; private final SettingsReflectionHelper settingsReflectionHelper; - private final RepositoryMetadataService repositoryMetadataService; + private final RepositoryService repositoryService; private static final Logger logger = LoggerFactory.getLogger(MirrorRepositoryHook.class); public MirrorRepositoryHook( - GitScm gitScm, + ScmService scmService, I18nService i18nService, ScheduledExecutorService executor, PasswordEncryptor passwordEncryptor, SettingsReflectionHelper settingsReflectionHelper, PluginSettingsFactory pluginSettingsFactory, - RepositoryMetadataService repositoryMetadataService + RepositoryService repositoryService ) { logger.debug("MirrorRepositoryHook: init started"); // Set fields - this.gitScm = gitScm; + this.scmService = scmService; this.i18nService = i18nService; this.executor = executor; this.passwordEncryptor = passwordEncryptor; this.settingsReflectionHelper = settingsReflectionHelper; - this.repositoryMetadataService = repositoryMetadataService; + this.repositoryService = repositoryService; // Init password encryptor PluginSettings pluginSettings = pluginSettingsFactory.createSettingsForKey(PLUGIN_SETTINGS_KEY); @@ -78,11 +78,11 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep } /** - * Calls the remote stash instance(s) to push the latest changes - *

+ * Calls the remote bitbucket instance(s) to push the latest changes + *

* Callback method that is called just after a push is completed (or a pull request accepted). * This hook executes after the processing of a push and will not block the user client. - *

+ *

* Despite being asynchronous, the user who initiated this change is still available from * * @param context the context which the hook is being run with @@ -104,7 +104,7 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep } void runMirrorCommand(MirrorSettings settings, final Repository repository) { - if (repositoryMetadataService.isEmpty(repository)) { + if (repositoryService.isEmpty(repository)) { return; } @@ -112,14 +112,19 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep final String password = passwordEncryptor.decrypt(settings.password); final String authenticatedUrl = getAuthenticatedUrl(settings.mirrorRepoUrl, settings.username, password); - executor.submit(new Callable() { + executor.submit(new Runnable() { int attempts = 0; @Override - public Void call() throws Exception { + public void run() { try { - GitScmCommandBuilder builder = gitScm.getCommandBuilderFactory().builder(repository); + ScmCommandBuilder obj = scmService.createBuilder(repository); + if (!(obj instanceof GitScmCommandBuilder)) { + logger.warn("Repository " + repository.getName() + " is not a git repo, cannot mirror"); + return; + } + GitScmCommandBuilder builder = (GitScmCommandBuilder) obj; PasswordHandler passwordHandler = getPasswordHandler(builder, password); // Call push command with the prune flag and refspecs for heads and tags @@ -149,7 +154,6 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep } } - return null; } }); @@ -215,7 +219,7 @@ public class MirrorRepositoryHook implements AsyncPostReceiveRepositoryHook, Rep protected List getMirrorSettings(Settings settings) { - List results = new ArrayList(); + List results = new ArrayList<>(); Map allSettings = settings.asMap(); int count = 0; diff --git a/src/main/java/com/englishtown/stash/hook/PasswordEncryptor.java b/src/main/java/com/englishtown/bitbucket/hook/PasswordEncryptor.java similarity index 96% rename from src/main/java/com/englishtown/stash/hook/PasswordEncryptor.java rename to src/main/java/com/englishtown/bitbucket/hook/PasswordEncryptor.java index 4e61575..326e727 100644 --- a/src/main/java/com/englishtown/stash/hook/PasswordEncryptor.java +++ b/src/main/java/com/englishtown/bitbucket/hook/PasswordEncryptor.java @@ -1,4 +1,4 @@ -package com.englishtown.stash.hook; +package com.englishtown.bitbucket.hook; import com.atlassian.sal.api.pluginsettings.PluginSettings; diff --git a/src/main/java/com/englishtown/stash/hook/PasswordHandler.java b/src/main/java/com/englishtown/bitbucket/hook/PasswordHandler.java similarity index 86% rename from src/main/java/com/englishtown/stash/hook/PasswordHandler.java rename to src/main/java/com/englishtown/bitbucket/hook/PasswordHandler.java index b935c97..99ae952 100644 --- a/src/main/java/com/englishtown/stash/hook/PasswordHandler.java +++ b/src/main/java/com/englishtown/bitbucket/hook/PasswordHandler.java @@ -1,8 +1,8 @@ -package com.englishtown.stash.hook; +package com.englishtown.bitbucket.hook; -import com.atlassian.stash.scm.CommandErrorHandler; -import com.atlassian.stash.scm.CommandExitHandler; -import com.atlassian.stash.scm.CommandOutputHandler; +import com.atlassian.bitbucket.scm.CommandErrorHandler; +import com.atlassian.bitbucket.scm.CommandExitHandler; +import com.atlassian.bitbucket.scm.CommandOutputHandler; import com.atlassian.utils.process.StringOutputHandler; import javax.annotation.Nonnull; diff --git a/src/main/java/com/englishtown/stash/hook/SettingsReflectionHelper.java b/src/main/java/com/englishtown/bitbucket/hook/SettingsReflectionHelper.java similarity index 80% rename from src/main/java/com/englishtown/stash/hook/SettingsReflectionHelper.java rename to src/main/java/com/englishtown/bitbucket/hook/SettingsReflectionHelper.java index f7c57c6..4e4de53 100644 --- a/src/main/java/com/englishtown/stash/hook/SettingsReflectionHelper.java +++ b/src/main/java/com/englishtown/bitbucket/hook/SettingsReflectionHelper.java @@ -1,6 +1,6 @@ -package com.englishtown.stash.hook; +package com.englishtown.bitbucket.hook; -import com.atlassian.stash.setting.Settings; +import com.atlassian.bitbucket.setting.Settings; import java.util.Map; diff --git a/src/main/resources/atlassian-plugin.xml b/src/main/resources/atlassian-plugin.xml index c581e4a..4b097d1 100644 --- a/src/main/resources/atlassian-plugin.xml +++ b/src/main/resources/atlassian-plugin.xml @@ -8,31 +8,27 @@ - + + - - - - - - - com.englishtown.stash.hook.PasswordEncryptor + + com.englishtown.bitbucket.hook.PasswordEncryptor - - com.englishtown.stash.hook.SettingsReflectionHelper + + com.englishtown.bitbucket.hook.SettingsReflectionHelper + key="mirror-repository-hook" class="com.englishtown.bitbucket.hook.MirrorRepositoryHook"> Mirror Hook /icons/mirror-icon.png - com.englishtown.stash.hook.mirrorrepositoryhook.view + com.englishtown.bitbucket.hook.mirrorrepositoryhook.view diff --git a/src/main/resources/stash-hook-mirror.properties b/src/main/resources/bitbucket-hook-mirror.properties similarity index 50% rename from src/main/resources/stash-hook-mirror.properties rename to src/main/resources/bitbucket-hook-mirror.properties index a792f41..4199862 100644 --- a/src/main/resources/stash-hook-mirror.properties +++ b/src/main/resources/bitbucket-hook-mirror.properties @@ -1,4 +1,4 @@ #put any key/value pairs here my.plugin.name=stash-hook-mirror mirror-repository-hook.name=Mirror Hook -mirror-repository-hook.description=Mirrors a stash repository to one or more remote repositories. +mirror-repository-hook.description=Mirrors a bitbucket repository to one or more remote repositories. diff --git a/src/main/resources/static/mirror-repository-hook.soy b/src/main/resources/static/mirror-repository-hook.soy index 0bff37c..2c8a63c 100644 --- a/src/main/resources/static/mirror-repository-hook.soy +++ b/src/main/resources/static/mirror-repository-hook.soy @@ -1,4 +1,4 @@ -{namespace com.englishtown.stash.hook.mirrorrepositoryhook} +{namespace com.englishtown.bitbucket.hook.mirrorrepositoryhook} /** * @param config @@ -29,7 +29,7 @@ // Call init method with subview callback {/template} @@ -44,10 +44,10 @@ {param id: 'mirrorRepoUrl' + $index /} {param value: $config['mirrorRepoUrl' + $index] /} {param labelContent} - {stash_i18n('com.englishtown.stash.hook.mirror.strings.mirrorRepoUrl.label', 'Mirror Repo URL')} + {stash_i18n('com.englishtown.bitbucket.hook.mirror.strings.mirrorRepoUrl.label', 'Mirror Repo URL')} {/param} {param isRequired: true /} - {param descriptionText: stash_i18n('com.englishtown.stash.hook.mirror.strings.mirrorRepoUrl.description', + {param descriptionText: stash_i18n('com.englishtown.bitbucket.hook.mirror.strings.mirrorRepoUrl.description', 'The GIT URL (ssh, git, http(s), file) to the remote mirrored repo') /} {param extraClasses: 'long et-mirror-repo' /} {param errorTexts: $errors ? $errors['mirrorRepoUrl' + $index] : null /} @@ -56,9 +56,9 @@ {param id: 'username' + $index /} {param value: $config['username' + $index] /} {param labelContent} - {stash_i18n('com.englishtown.stash.hook.mirror.strings.username.label', 'Username')} + {stash_i18n('com.englishtown.bitbucket.hook.mirror.strings.username.label', 'Username')} {/param} - {param descriptionText: stash_i18n('com.englishtown.stash.hook.mirror.strings.username.description', + {param descriptionText: stash_i18n('com.englishtown.bitbucket.hook.mirror.strings.username.description', 'The username to use for pushing to the mirror over http(s)') /} {param extraClasses: 'long' /} {param errorTexts: $errors ? $errors['username' + $index] : null /} @@ -67,9 +67,9 @@ {param id: 'password' + $index /} {param value: $config['password' + $index] /} {param labelContent} - {stash_i18n('com.englishtown.stash.hook.mirror.strings.password.label', 'Password')} + {stash_i18n('com.englishtown.bitbucket.hook.mirror.strings.password.label', 'Password')} {/param} - {param descriptionText: stash_i18n('com.englishtown.stash.hook.mirror.strings.password.description', + {param descriptionText: stash_i18n('com.englishtown.bitbucket.hook.mirror.strings.password.description', 'The password to use for pushing to the mirror over http(s)') /} {param extraClasses: 'long' /} {param errorTexts: $errors ? $errors['password' + $index] : null /} diff --git a/src/test/java/com/englishtown/stash/hook/DefaultPasswordEncryptorTest.java b/src/test/java/com/englishtown/bitbucket/hook/DefaultPasswordEncryptorTest.java similarity index 98% rename from src/test/java/com/englishtown/stash/hook/DefaultPasswordEncryptorTest.java rename to src/test/java/com/englishtown/bitbucket/hook/DefaultPasswordEncryptorTest.java index def9378..b945d92 100644 --- a/src/test/java/com/englishtown/stash/hook/DefaultPasswordEncryptorTest.java +++ b/src/test/java/com/englishtown/bitbucket/hook/DefaultPasswordEncryptorTest.java @@ -1,4 +1,4 @@ -package com.englishtown.stash.hook; +package com.englishtown.bitbucket.hook; import com.atlassian.sal.api.pluginsettings.PluginSettings; import org.junit.Before; diff --git a/src/test/java/com/englishtown/bitbucket/hook/DefaultSettingsReflectionHelperTest.java b/src/test/java/com/englishtown/bitbucket/hook/DefaultSettingsReflectionHelperTest.java new file mode 100644 index 0000000..64bce75 --- /dev/null +++ b/src/test/java/com/englishtown/bitbucket/hook/DefaultSettingsReflectionHelperTest.java @@ -0,0 +1,107 @@ +package com.englishtown.bitbucket.hook; + +import com.atlassian.bitbucket.setting.Settings; +import com.google.common.collect.ImmutableMap; +import org.junit.Test; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +/** + * Unit tests for {@link DefaultSettingsReflectionHelper} + */ +public class DefaultSettingsReflectionHelperTest { + + @Test + public void testSet() throws Exception { + + DefaultSettingsReflectionHelper helper = new DefaultSettingsReflectionHelper(); + Map original = new HashMap<>(); + original.put("old", "old"); + TestSettings settings = new TestSettings(original); + Map values = new HashMap<>(); + + values.put("new", "new"); + + helper.set(values, settings); + + assertNull(settings.getString("old")); + assertEquals("new", settings.getString("new")); + + } + + private static class TestSettings implements Settings { + private final Map values; + + public TestSettings(Map values) { + this.values = ImmutableMap.copyOf(values); + } + + @Nullable + @Override + public String getString(@Nonnull String key) { + return (String) values.get(key); + } + + @Nonnull + @Override + public String getString(@Nonnull String key, @Nonnull String defaultValue) { + return null; + } + + @Nullable + @Override + public Boolean getBoolean(@Nonnull String key) { + return null; + } + + @Override + public boolean getBoolean(@Nonnull String key, boolean defaultValue) { + return false; + } + + @Nullable + @Override + public Integer getInt(@Nonnull String key) { + return null; + } + + @Override + public int getInt(@Nonnull String key, int defaultValue) { + return 0; + } + + @Nullable + @Override + public Long getLong(@Nonnull String key) { + return null; + } + + @Override + public long getLong(@Nonnull String key, long defaultValue) { + return 0; + } + + @Nullable + @Override + public Double getDouble(@Nonnull String key) { + return null; + } + + @Override + public double getDouble(@Nonnull String key, double defaultValue) { + return 0; + } + + @Override + public Map asMap() { + return values; + } + } + +} diff --git a/src/test/java/com/englishtown/stash/hook/MirrorRepositoryHookTest.java b/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java similarity index 75% rename from src/test/java/com/englishtown/stash/hook/MirrorRepositoryHookTest.java rename to src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java index daef955..9113283 100644 --- a/src/test/java/com/englishtown/stash/hook/MirrorRepositoryHookTest.java +++ b/src/test/java/com/englishtown/bitbucket/hook/MirrorRepositoryHookTest.java @@ -1,21 +1,19 @@ -package com.englishtown.stash.hook; - +package com.englishtown.bitbucket.hook; + +import com.atlassian.bitbucket.hook.repository.RepositoryHookContext; +import com.atlassian.bitbucket.i18n.I18nService; +import com.atlassian.bitbucket.repository.Repository; +import com.atlassian.bitbucket.repository.RepositoryService; +import com.atlassian.bitbucket.scm.CommandErrorHandler; +import com.atlassian.bitbucket.scm.CommandExitHandler; +import com.atlassian.bitbucket.scm.CommandOutputHandler; +import com.atlassian.bitbucket.scm.ScmService; +import com.atlassian.bitbucket.scm.git.command.GitCommand; +import com.atlassian.bitbucket.scm.git.command.GitScmCommandBuilder; +import com.atlassian.bitbucket.setting.Settings; +import com.atlassian.bitbucket.setting.SettingsValidationErrors; import com.atlassian.sal.api.pluginsettings.PluginSettings; import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory; -import com.atlassian.stash.hook.repository.RepositoryHookContext; -import com.atlassian.stash.i18n.I18nService; -import com.atlassian.stash.repository.RefChange; -import com.atlassian.stash.repository.Repository; -import com.atlassian.stash.repository.RepositoryMetadataService; -import com.atlassian.stash.scm.CommandErrorHandler; -import com.atlassian.stash.scm.CommandExitHandler; -import com.atlassian.stash.scm.CommandOutputHandler; -import com.atlassian.stash.scm.git.GitCommand; -import com.atlassian.stash.scm.git.GitCommandBuilderFactory; -import com.atlassian.stash.scm.git.GitScm; -import com.atlassian.stash.scm.git.GitScmCommandBuilder; -import com.atlassian.stash.setting.Settings; -import com.atlassian.stash.setting.SettingsValidationErrors; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,12 +23,9 @@ import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import java.net.URI; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.Callable; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -45,6 +40,9 @@ public class MirrorRepositoryHookTest { private MirrorRepositoryHook hook; private GitScmCommandBuilder builder; + + @Mock + private ScmService scmService; @Mock private GitCommand cmd; @Mock @@ -58,17 +56,16 @@ public class MirrorRepositoryHookTest { @Mock private PluginSettings pluginSettings; @Mock - private RepositoryMetadataService repositoryMetadataService; + private RepositoryService repositoryService; - private final String mirrorRepoUrlHttp = "https://stash-mirror.englishtown.com/scm/test/test.git"; - private final String mirrorRepoUrlSsh = "ssh://git@stash-mirror.englishtown.com/scm/test/test.git"; + private final String mirrorRepoUrlHttp = "https://bitbucket-mirror.englishtown.com/scm/test/test.git"; + private final String mirrorRepoUrlSsh = "ssh://git@bitbucket-mirror.englishtown.com/scm/test/test.git"; private final String username = "test-user"; 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@bitbucket-mirror.englishtown.com/scm/test/test.git"; - @SuppressWarnings("UnusedDeclaration") @Captor - ArgumentCaptor> argumentCaptor; + ArgumentCaptor argumentCaptor; @Before public void setup() { @@ -78,18 +75,14 @@ public class MirrorRepositoryHookTest { when(builder.argument(anyString())).thenReturn(builder); when(builder.errorHandler(any(CommandErrorHandler.class))).thenReturn(builder); when(builder.exitHandler(any(CommandExitHandler.class))).thenReturn(builder); - when(builder.build(any(CommandOutputHandler.class))).thenReturn(cmd); - - GitCommandBuilderFactory builderFactory = mock(GitCommandBuilderFactory.class); - when(builderFactory.builder(any(Repository.class))).thenReturn(builder); + when(builder.build(any(CommandOutputHandler.class))).thenReturn(cmd); - GitScm gitScm = mock(GitScm.class); - when(gitScm.getCommandBuilderFactory()).thenReturn(builderFactory); + doReturn(builder).when(scmService).createBuilder(any()); when(pluginSettingsFactory.createSettingsForKey(anyString())).thenReturn(pluginSettings); - hook = new MirrorRepositoryHook(gitScm, mock(I18nService.class), executor, passwordEncryptor - , settingsReflectionHelper, pluginSettingsFactory, repositoryMetadataService); + hook = new MirrorRepositoryHook(scmService, mock(I18nService.class), executor, passwordEncryptor + , settingsReflectionHelper, pluginSettingsFactory, repositoryService); } @@ -100,27 +93,26 @@ public class MirrorRepositoryHookTest { Repository repo = mock(Repository.class); when(repo.getName()).thenReturn("test"); - hook.postReceive(buildContext(repo), new ArrayList()); + hook.postReceive(buildContext(repo), new ArrayList<>()); verifyExecutor(); } @Test public void testEmptyRepositoriesNotMirrored() { Repository repo = mock(Repository.class); - when(repositoryMetadataService.isEmpty(repo)).thenReturn(true); + when(repositoryService.isEmpty(repo)).thenReturn(true); - hook.postReceive(buildContext(repo), new ArrayList()); + hook.postReceive(buildContext(repo), new ArrayList<>()); - verify(executor, never()).submit(Matchers.>any()); + verify(executor, never()).submit(Matchers.any()); } @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, - passwordEncryptor, settingsReflectionHelper, pluginSettingsFactory, repositoryMetadataService); + when(scmService.createBuilder(any())).thenThrow(new RuntimeException("Intentional unit test exception")); + MirrorRepositoryHook hook = new MirrorRepositoryHook(scmService, mock(I18nService.class), executor, + passwordEncryptor, settingsReflectionHelper, pluginSettingsFactory, repositoryService); MirrorRepositoryHook.MirrorSettings ms = new MirrorRepositoryHook.MirrorSettings(); ms.mirrorRepoUrl = mirrorRepoUrlHttp; ms.username = username; @@ -128,29 +120,29 @@ public class MirrorRepositoryHookTest { hook.runMirrorCommand(ms, mock(Repository.class)); verify(executor).submit(argumentCaptor.capture()); - Callable callable = argumentCaptor.getValue(); - callable.call(); + Runnable runnable = argumentCaptor.getValue(); + runnable.run(); verify(executor, times(1)).schedule(argumentCaptor.capture(), anyInt(), any(TimeUnit.class)); - callable = argumentCaptor.getValue(); - callable.call(); + runnable = argumentCaptor.getValue(); + runnable.run(); verify(executor, times(2)).schedule(argumentCaptor.capture(), anyInt(), any(TimeUnit.class)); - callable = argumentCaptor.getValue(); - callable.call(); + runnable = argumentCaptor.getValue(); + runnable.run(); verify(executor, times(3)).schedule(argumentCaptor.capture(), anyInt(), any(TimeUnit.class)); - callable = argumentCaptor.getValue(); - callable.call(); + runnable = argumentCaptor.getValue(); + runnable.run(); verify(executor, times(4)).schedule(argumentCaptor.capture(), anyInt(), any(TimeUnit.class)); - callable = argumentCaptor.getValue(); - callable.call(); + runnable = argumentCaptor.getValue(); + runnable.run(); // Make sure it is only called 5 times - callable.call(); - callable.call(); - callable.call(); + runnable.run(); + runnable.run(); + runnable.run(); verify(executor, times(4)).schedule(argumentCaptor.capture(), anyInt(), any(TimeUnit.class)); } @@ -158,8 +150,8 @@ public class MirrorRepositoryHookTest { private void verifyExecutor() throws Exception { verify(executor).submit(argumentCaptor.capture()); - Callable callable = argumentCaptor.getValue(); - callable.call(); + Runnable runnable = argumentCaptor.getValue(); + runnable.run(); verify(builder, times(1)).command(eq("push")); verify(builder, times(1)).argument(eq("--prune")); @@ -193,8 +185,8 @@ public class MirrorRepositoryHookTest { .thenReturn("") .thenReturn(mirrorRepoUrlHttp) .thenReturn("invalid uri") - .thenReturn("http://should-not:have-user@stash-mirror.englishtown.com/scm/test/test.git") - .thenReturn("ssh://user@stash-mirror.englishtown.com/scm/test/test.git") + .thenReturn("http://should-not:have-user@bitbucket-mirror.englishtown.com/scm/test/test.git") + .thenReturn("ssh://user@bitbucket-mirror.englishtown.com/scm/test/test.git") .thenReturn(mirrorRepoUrlSsh) .thenReturn(mirrorRepoUrlHttp); diff --git a/src/test/java/com/englishtown/stash/hook/PasswordHandlerTest.java b/src/test/java/com/englishtown/bitbucket/hook/PasswordHandlerTest.java similarity index 94% rename from src/test/java/com/englishtown/stash/hook/PasswordHandlerTest.java rename to src/test/java/com/englishtown/bitbucket/hook/PasswordHandlerTest.java index bb8931c..260ff79 100644 --- a/src/test/java/com/englishtown/stash/hook/PasswordHandlerTest.java +++ b/src/test/java/com/englishtown/bitbucket/hook/PasswordHandlerTest.java @@ -1,6 +1,6 @@ -package com.englishtown.stash.hook; +package com.englishtown.bitbucket.hook; -import com.atlassian.stash.scm.CommandExitHandler; +import com.atlassian.bitbucket.scm.CommandExitHandler; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/com/englishtown/stash/hook/DefaultSettingsReflectionHelperTest.java b/src/test/java/com/englishtown/stash/hook/DefaultSettingsReflectionHelperTest.java deleted file mode 100644 index 798be36..0000000 --- a/src/test/java/com/englishtown/stash/hook/DefaultSettingsReflectionHelperTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.englishtown.stash.hook; - -import com.atlassian.stash.internal.setting.MapSettingsBuilder; -import com.atlassian.stash.setting.Settings; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -/** - * Unit tests for {@link DefaultSettingsReflectionHelper} - */ -public class DefaultSettingsReflectionHelperTest { - - @Test - public void testSet() throws Exception { - - DefaultSettingsReflectionHelper helper = new DefaultSettingsReflectionHelper(); - MapSettingsBuilder builder = new MapSettingsBuilder(); - Map values = new HashMap(); - - builder.add("old", "old"); - values.put("new", "new"); - - Settings settings = builder.build(); - helper.set(values, settings); - - assertNull(settings.getString("old")); - assertEquals("new", settings.getString("new")); - - } - -}