*/
package org.sonar.server.edition.ws;
-import java.util.Collections;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.server.edition.MutableEditionManagementState;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.license.LicenseCommit;
+import org.sonar.server.plugins.edition.EditionInstaller;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.WsEditions;
private final UserSession userSession;
private final MutableEditionManagementState editionManagementState;
+ private final EditionInstaller editionInstaller;
@CheckForNull
private final LicenseCommit licenseCommit;
- public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState) {
- this(userSession, editionManagementState, null);
+ public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState, EditionInstaller editionInstaller) {
+ this(userSession, editionManagementState, editionInstaller, null);
}
- public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState,
+ public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState, EditionInstaller editionInstaller,
@Nullable LicenseCommit licenseCommit) {
this.userSession = userSession;
this.editionManagementState = editionManagementState;
+ this.editionInstaller = editionInstaller;
this.licenseCommit = licenseCommit;
}
throw BadRequestException.create("Can't apply a license when applying one is already in progress");
}
- String license = request.mandatoryParam(PARAM_LICENSE);
- License newLicense = new License(license, Collections.emptyList(), license);
- if (license.contains("manual")) {
- editionManagementState.startManualInstall(newLicense);
- } else if (license.contains("done")) {
+ String licenseParam = request.mandatoryParam(PARAM_LICENSE);
+ License newLicense = License.parse(licenseParam).orElseThrow(() -> BadRequestException.create("The license provided is invalid"));
+
+ if (!editionInstaller.requiresInstallationChange(newLicense.getPluginKeys())) {
+ editionManagementState.newEditionWithoutInstall(newLicense.getEditionKey());
checkState(licenseCommit != null,
"Can't decide edition does not require install if LicenseCommit instance is null. " +
"License-manager plugin should be installed.");
- licenseCommit.update(newLicense.getContent());
- editionManagementState.newEditionWithoutInstall(newLicense.getEditionKey());
- } else {
- editionManagementState.startAutomaticInstall(newLicense);
+ licenseCommit.update(newLicense.getContent()); } else {
+ boolean online = editionInstaller.install(newLicense.getPluginKeys());
+ if (online) {
+ editionManagementState.startAutomaticInstall(newLicense);
+ } else {
+ editionManagementState.startManualInstall(newLicense);
+ }
}
WsUtils.writeProtobuf(buildResponse(), request, response);
*/
package org.sonar.server.plugins.edition;
+import com.google.common.base.Optional;
+import java.util.Collection;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.server.edition.MutableEditionManagementState;
import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.updatecenter.common.UpdateCenter;
public class EditionInstaller {
private final ReentrantLock lock = new ReentrantLock();
private final EditionPluginDownloader editionPluginDownloader;
private final EditionPluginUninstaller editionPluginUninstaller;
private final ServerPluginRepository pluginRepository;
+ private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
+ private final MutableEditionManagementState editionManagementState;
public EditionInstaller(EditionPluginDownloader editionDownloader, EditionPluginUninstaller editionPluginUninstaller,
- ServerPluginRepository pluginRepository, EditionInstallerExecutor executor) {
+ ServerPluginRepository pluginRepository, EditionInstallerExecutor executor, UpdateCenterMatrixFactory updateCenterMatrixFactory,
+ MutableEditionManagementState editionManagementState) {
this.editionPluginDownloader = editionDownloader;
this.editionPluginUninstaller = editionPluginUninstaller;
this.pluginRepository = pluginRepository;
this.executor = executor;
+ this.updateCenterMatrixFactory = updateCenterMatrixFactory;
+ this.editionManagementState = editionManagementState;
}
- public void install(Set<String> editionPlugins) {
+ /**
+ * Refreshes the update center, and submits in a executor a task to download all the needed plugins (asynchronously).
+ * If the update center is disabled or if we are offline, the task is not submitted and false is returned.
+ * @return true if a task was submitted to perform the download, false if update center is unavailable.
+ * @throws IllegalStateException if an installation is already in progress
+ */
+ public boolean install(Set<String> editionPluginKeys) {
if (lock.tryLock()) {
try {
- if (!requiresInstallationChange(editionPlugins)) {
- return;
+ Optional<UpdateCenter> updateCenter = updateCenterMatrixFactory.getUpdateCenter(true);
+ if (!updateCenter.isPresent()) {
+ return false;
}
-
- executor.execute(() -> asyncInstall(editionPlugins));
+ executor.execute(() -> asyncInstall(editionPluginKeys, updateCenter.get()));
+ return true;
} catch (RuntimeException e) {
lock.unlock();
throw e;
}
}
+ public boolean isOffline() {
+ return !updateCenterMatrixFactory.getUpdateCenter(true).isPresent();
+ }
+
public boolean requiresInstallationChange(Set<String> editionPluginKeys) {
- return !pluginsToInstall(editionPluginKeys).isEmpty() || !pluginsToRemove(editionPluginKeys).isEmpty();
+ Map<String, PluginInfo> pluginInfosByKeys = pluginRepository.getPluginInfosByKeys();
+
+ return !pluginsToInstall(editionPluginKeys, pluginInfosByKeys.keySet()).isEmpty()
+ || !pluginsToRemove(editionPluginKeys, pluginInfosByKeys.values()).isEmpty();
}
- private void asyncInstall(Set<String> editionPluginKeys) {
+ private void asyncInstall(Set<String> editionPluginKeys, UpdateCenter updateCenter) {
+ Map<String, PluginInfo> pluginInfosByKeys = pluginRepository.getPluginInfosByKeys();
+ Set<String> pluginsToRemove = pluginsToRemove(editionPluginKeys, pluginInfosByKeys.values());
+ Set<String> pluginsToInstall = pluginsToInstall(editionPluginKeys, pluginInfosByKeys.keySet());
+
try {
- // TODO clean previously staged edition installations, or fail?
- // editionPluginDownloader.cancelDownloads();
- // editionPluginUninstaller.cancelUninstalls();
- editionPluginDownloader.installEdition(pluginsToInstall(editionPluginKeys));
- for (String pluginKey : pluginsToRemove(editionPluginKeys)) {
+ editionPluginDownloader.downloadEditionPlugins(pluginsToInstall, updateCenter);
+ for (String pluginKey : pluginsToRemove) {
editionPluginUninstaller.uninstall(pluginKey);
}
+ editionManagementState.automaticInstallReady();
} finally {
lock.unlock();
+ // TODO: catch exceptions and set error status
}
}
- private Set<String> pluginsToInstall(Set<String> editionPluginKeys) {
- Set<String> installedKeys = pluginRepository.getPluginInfosByKeys().keySet();
+ private Set<String> pluginsToInstall(Set<String> editionPluginKeys, Set<String> installedPluginKeys) {
return editionPluginKeys.stream()
- .filter(p -> !installedKeys.contains(p))
+ .filter(p -> !installedPluginKeys.contains(p))
.collect(Collectors.toSet());
}
- private Set<String> pluginsToRemove(Set<String> editionPluginKeys) {
- Set<String> installedCommercialPluginKeys = pluginRepository.getPluginInfos().stream()
+ private Set<String> pluginsToRemove(Set<String> editionPluginKeys, Collection<PluginInfo> installedPluginInfos) {
+ Set<String> installedCommercialPluginKeys = installedPluginInfos.stream()
.filter(EditionInstaller::isSonarSourceCommercialPlugin)
.map(PluginInfo::getKey)
.collect(Collectors.toSet());
*/
package org.sonar.server.plugins.edition;
-import com.google.common.base.Optional;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.util.FileUtils;
import org.sonar.server.platform.ServerFileSystem;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.updatecenter.common.Release;
import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
private static final Logger LOG = Loggers.get(EditionPluginDownloader.class);
private static final String PLUGIN_EXTENSION = "jar";
- private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
private final Path tmpDir;
private final Path downloadDir;
private final HttpDownloader downloader;
- public EditionPluginDownloader(UpdateCenterMatrixFactory updateCenterMatrixFactory, HttpDownloader downloader, ServerFileSystem fileSystem) {
+ public EditionPluginDownloader(HttpDownloader downloader, ServerFileSystem fileSystem) {
this.downloadDir = fileSystem.getEditionDownloadedPluginsDir().toPath();
- this.updateCenterMatrixFactory = updateCenterMatrixFactory;
this.downloader = downloader;
this.tmpDir = downloadDir.resolveSibling(downloadDir.getFileName() + "_tmp");
}
- public void installEdition(Set<String> pluginKeys) {
+ public void downloadEditionPlugins(Set<String> pluginKeys, UpdateCenter updateCenter) {
try {
- Optional<UpdateCenter> updateCenter = updateCenterMatrixFactory.getUpdateCenter(true);
- if (updateCenter.isPresent()) {
- Set<Release> pluginsToInstall = new HashSet<>();
- for (String pluginKey : pluginKeys) {
- pluginsToInstall.addAll(updateCenter.get().findInstallablePlugins(pluginKey, Version.create("")));
- }
-
- FileUtils.deleteQuietly(tmpDir);
- Files.createDirectories(tmpDir);
+ Set<Release> pluginsToInstall = new HashSet<>();
+ for (String pluginKey : pluginKeys) {
+ pluginsToInstall.addAll(updateCenter.findInstallablePlugins(pluginKey, Version.create("")));
+ }
- for (Release r : pluginsToInstall) {
- download(r);
- }
+ FileUtils.deleteQuietly(tmpDir);
+ Files.createDirectories(tmpDir);
- FileUtils.deleteQuietly(downloadDir);
- Files.move(tmpDir, downloadDir);
+ for (Release r : pluginsToInstall) {
+ download(r);
}
+
+ FileUtils.deleteQuietly(downloadDir);
+ Files.move(tmpDir, downloadDir);
} catch (Exception e) {
FileUtils.deleteQuietly(tmpDir);
throw new IllegalStateException("Failed to install edition", e);
}
@Test
- public void parse_is_empty_if_no_plugin() throws IOException {
+ public void parse_is_empty_if_license_has_no_plugin() throws IOException {
Properties props = new Properties();
props.setProperty("Plugins", "");
props.setProperty("Edition", "dev");
assertThat(license).isEmpty();
}
+ @Test
+ public void parse_is_empty_if_license_has_no_edition_key() throws IOException {
+ Properties props = new Properties();
+ props.setProperty("Plugins", "plugin1,plugin2");
+ StringWriter writer = new StringWriter();
+ props.store(writer, "");
+
+ byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes());
+
+ Optional<License> license = License.parse(new String(encoded));
+ assertThat(license).isEmpty();
+ }
+
@Test
public void verify_getters() {
ImmutableSet<String> pluginKeys = ImmutableSet.of("a", "b", "c");
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collections;
import java.util.Optional;
+import java.util.Properties;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.edition.EditionManagementState;
+import org.sonar.server.edition.EditionManagementState.PendingStatus;
+import org.sonar.server.edition.License;
import org.sonar.server.edition.MutableEditionManagementState;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.license.LicenseCommit;
+import org.sonar.server.plugins.edition.EditionInstaller;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonar.test.JsonAssert;
+import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.WsEditions;
+import org.sonarqube.ws.WsEditions.StatusResponse;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_IN_PROGRESS;
import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE;
@RunWith(DataProviderRunner.class)
public class ApplyLicenseActionTest {
private static final String PARAM_LICENSE = "license";
+ private static final String PENDING_EDITION_NAME = "developer-edition";
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ private EditionInstaller editionInstaller = mock(EditionInstaller.class);
private MutableEditionManagementState mutableEditionManagementState = mock(MutableEditionManagementState.class);
private LicenseCommit licenseCommit = mock(LicenseCommit.class);
- private ApplyLicenseAction underTest = new ApplyLicenseAction(userSessionRule, mutableEditionManagementState, licenseCommit);
+ private ApplyLicenseAction underTest = new ApplyLicenseAction(userSessionRule, mutableEditionManagementState, editionInstaller, licenseCommit);
private WsActionTester actionTester = new WsActionTester(underTest);
@Test
}
@Test
- public void verify_example() {
+ public void request_fails_with_BadRequestException_if_license_is_invalid() {
userSessionRule.logIn().setSystemAdministrator();
- when(mutableEditionManagementState.getCurrentEditionKey()).thenReturn(Optional.empty());
- when(mutableEditionManagementState.getPendingEditionKey()).thenReturn(Optional.of("developer-edition"));
- when(mutableEditionManagementState.getPendingInstallationStatus())
- .thenReturn(NONE)
- .thenReturn(AUTOMATIC_IN_PROGRESS);
+ TestRequest request = actionTester.newRequest()
+ .setParam(PARAM_LICENSE, "invalid");
+ when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(NONE);
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("The license provided is invalid");
+ request.execute();
+ }
+
+ @Test
+ public void verify_example() throws IOException {
+ userSessionRule.logIn().setSystemAdministrator();
+ setPendingLicense(AUTOMATIC_IN_PROGRESS);
TestRequest request = actionTester.newRequest()
- .setParam(PARAM_LICENSE, "foo");
+ .setParam(PARAM_LICENSE, createLicenseParam("dev", "plugin1"));
JsonAssert.assertJson(request.execute().getInput()).isSimilarTo(actionTester.getDef().responseExampleAsString());
}
+ @Test
+ public void apply_without_need_to_install() throws IOException {
+ userSessionRule.logIn().setSystemAdministrator();
+ setPendingLicense(NONE);
+ when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(false);
+
+ TestRequest request = actionTester.newRequest()
+ .setMediaType(MediaTypes.PROTOBUF)
+ .setParam(PARAM_LICENSE, createLicenseParam(PENDING_EDITION_NAME, "plugin1"));
+
+ TestResponse response = request.execute();
+ assertResponse(response, PENDING_EDITION_NAME, "", NONE);
+ verify(mutableEditionManagementState).newEditionWithoutInstall(PENDING_EDITION_NAME);
+ }
+
+ @Test
+ public void apply_offline() throws IOException {
+ userSessionRule.logIn().setSystemAdministrator();
+ setPendingLicense(PendingStatus.MANUAL_IN_PROGRESS);
+ when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(true);
+ when(editionInstaller.install(Collections.singleton("plugin1"))).thenReturn(false);
+
+ TestRequest request = actionTester.newRequest()
+ .setMediaType(MediaTypes.PROTOBUF)
+ .setParam(PARAM_LICENSE, createLicenseParam(PENDING_EDITION_NAME, "plugin1"));
+
+ TestResponse response = request.execute();
+
+ assertResponse(response, PENDING_EDITION_NAME, "", PendingStatus.MANUAL_IN_PROGRESS);
+ verify(mutableEditionManagementState).startManualInstall(any(License.class));
+ }
+
+ @Test
+ public void apply_successfully_auto_installation() throws IOException {
+ userSessionRule.logIn().setSystemAdministrator();
+ setPendingLicense(PendingStatus.AUTOMATIC_IN_PROGRESS);
+ when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(true);
+ when(editionInstaller.install(Collections.singleton("plugin1"))).thenReturn(true);
+
+ TestRequest request = actionTester.newRequest()
+ .setMediaType(MediaTypes.PROTOBUF)
+ .setParam(PARAM_LICENSE, createLicenseParam(PENDING_EDITION_NAME, "plugin1"));
+
+ TestResponse response = request.execute();
+
+ assertResponse(response, PENDING_EDITION_NAME, "", PendingStatus.AUTOMATIC_IN_PROGRESS);
+ verify(mutableEditionManagementState).startAutomaticInstall(any(License.class));
+ }
+
+ private void assertResponse(TestResponse response, String expectedNextEditionKey, String expectedEditionKey,
+ PendingStatus expectedPendingStatus) throws IOException {
+ StatusResponse parsedResponse = WsEditions.StatusResponse.parseFrom(response.getInputStream());
+ assertThat(parsedResponse.getCurrentEditionKey()).isEqualTo(expectedEditionKey);
+ assertThat(parsedResponse.getNextEditionKey()).isEqualTo(expectedNextEditionKey);
+ assertThat(parsedResponse.getInstallationStatus()).isEqualTo(WsEditions.InstallationStatus.valueOf(expectedPendingStatus.toString()));
+ }
+
+ private void setPendingLicense(PendingStatus pendingStatus) {
+ when(mutableEditionManagementState.getCurrentEditionKey()).thenReturn(Optional.empty());
+ when(mutableEditionManagementState.getPendingEditionKey()).thenReturn(Optional.of(PENDING_EDITION_NAME));
+ when(mutableEditionManagementState.getPendingInstallationStatus())
+ .thenReturn(NONE)
+ .thenReturn(pendingStatus);
+ }
+
+ private static String createLicenseParam(String editionKey, String... pluginKeys) throws IOException {
+ Properties props = new Properties();
+ props.setProperty("Plugins", String.join(",", pluginKeys));
+ props.setProperty("Edition", editionKey);
+ StringWriter writer = new StringWriter();
+ props.store(writer, "");
+
+ byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes());
+ return new String(encoded, StandardCharsets.UTF_8);
+ }
+
@DataProvider
public static Object[][] notNonePendingInstallationStatuses() {
return Arrays.stream(EditionManagementState.PendingStatus.values())
- .filter(s -> s != NONE)
- .map(s -> new Object[] {s})
- .toArray(Object[][]::new);
+ .filter(s -> s != NONE)
+ .map(s -> new Object[] {s})
+ .toArray(Object[][]::new);
}
}
*/
package org.sonar.server.plugins.edition;
+import com.google.common.base.Optional;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.server.edition.MutableEditionManagementState;
import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.updatecenter.common.UpdateCenter;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class EditionInstallerTest {
- private static final String pluginKey = "key";
- @Mock
- private EditionPluginDownloader downloader;
- @Mock
- private EditionPluginUninstaller uninstaller;
- @Mock
- private ServerPluginRepository pluginRepository;
+ private static final String PLUGIN_KEY = "key";
+
+ private EditionPluginDownloader downloader = mock(EditionPluginDownloader.class);
+ private EditionPluginUninstaller uninstaller = mock(EditionPluginUninstaller.class);
+ private UpdateCenterMatrixFactory updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class);
+ private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class);
+ private UpdateCenter updateCenter = mock(UpdateCenter.class);
+ private MutableEditionManagementState editionManagementState = mock(MutableEditionManagementState.class);
private EditionInstallerExecutor executor = new EditionInstallerExecutor() {
public void execute(Runnable r) {
}
};
- private EditionInstaller installer;
+ private EditionInstaller installer = new EditionInstaller(downloader, uninstaller, pluginRepository, executor, updateCenterMatrixFactory, editionManagementState);
@Before
- public void before() {
- MockitoAnnotations.initMocks(this);
- installer = new EditionInstaller(downloader, uninstaller, pluginRepository, executor);
+ public void setUp() {
+ when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
}
@Test
- public void install() {
- installer.install(Collections.singleton(pluginKey));
- verify(downloader).installEdition(Collections.singleton(pluginKey));
+ public void launch_task_download_plugins() {
+ assertThat(installer.install(Collections.singleton(PLUGIN_KEY))).isTrue();
+ verify(downloader).downloadEditionPlugins(Collections.singleton(PLUGIN_KEY), updateCenter);
}
@Test
editionPlugins.add("p4");
installer.install(editionPlugins);
- verify(downloader).installEdition(Collections.singleton("p4"));
+ verify(editionManagementState).automaticInstallReady();
+ verify(downloader).downloadEditionPlugins(Collections.singleton("p4"), updateCenter);
verify(uninstaller).uninstall("p2");
verifyNoMoreInteractions(uninstaller);
verifyNoMoreInteractions(downloader);
+ }
+
+ @Test
+ public void do_nothing_if_offline() {
+ mockPluginRepository(createPluginInfo("p1", true));
+ executor = mock(EditionInstallerExecutor.class);
+ when(updateCenterMatrixFactory.getUpdateCenter(true)).thenReturn(Optional.absent());
+ installer = new EditionInstaller(downloader, uninstaller, pluginRepository, executor, updateCenterMatrixFactory, editionManagementState);
+ assertThat(installer.install(Collections.singleton("p1"))).isFalse();
+
+ verifyZeroInteractions(executor);
+ verifyZeroInteractions(uninstaller);
+ verifyZeroInteractions(downloader);
+ verifyZeroInteractions(editionManagementState);
+ }
+
+ @Test
+ public void is_offline() {
+ when(updateCenterMatrixFactory.getUpdateCenter(true)).thenReturn(Optional.absent());
+ assertThat(installer.isOffline()).isTrue();
+ }
+
+ @Test
+ public void is_not_offline() {
+ assertThat(installer.isOffline()).isFalse();
+ }
+
+ @Test
+ public void requires_installation_change() {
+ PluginInfo commercial1 = createPluginInfo("p1", true);
+ PluginInfo commercial2 = createPluginInfo("p2", true);
+ PluginInfo open1 = createPluginInfo("p3", false);
+ mockPluginRepository(commercial1, commercial2, open1);
+
+ Set<String> editionPlugins = new HashSet<>();
+ editionPlugins.add("p1");
+ editionPlugins.add("p4");
+
+ assertThat(installer.requiresInstallationChange(editionPlugins)).isTrue();
+ verifyZeroInteractions(downloader);
+ verifyZeroInteractions(uninstaller);
+ verifyZeroInteractions(editionManagementState);
+ }
+
+ @Test
+ public void does_not_require_installation_change() {
+ PluginInfo commercial1 = createPluginInfo("p1", true);
+ PluginInfo commercial2 = createPluginInfo("p2", true);
+ PluginInfo open1 = createPluginInfo("p3", false);
+ mockPluginRepository(commercial1, commercial2, open1);
+
+ Set<String> editionPlugins = new HashSet<>();
+ editionPlugins.add("p1");
+ editionPlugins.add("p2");
+ assertThat(installer.requiresInstallationChange(editionPlugins)).isFalse();
+ verifyZeroInteractions(downloader);
+ verifyZeroInteractions(uninstaller);
+ verifyZeroInteractions(editionManagementState);
}
private void mockPluginRepository(PluginInfo... installedPlugins) {
*/
package org.sonar.server.plugins.edition;
-import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.sonar.api.utils.HttpDownloader;
import org.sonar.server.platform.ServerFileSystem;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.updatecenter.common.Plugin;
import org.sonar.updatecenter.common.Release;
import org.sonar.updatecenter.common.UpdateCenter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
-import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class EditionPluginDownloaderTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- @Mock
- private UpdateCenterMatrixFactory updateCenterMatrixFactory;
- @Mock
- private UpdateCenter updateCenter;
- @Mock
- private ServerFileSystem fs;
- @Mock
- private HttpDownloader httpDownloader;
+
+ private ServerFileSystem fs = mock(ServerFileSystem.class);
+ private HttpDownloader httpDownloader = mock(HttpDownloader.class);
+ private UpdateCenter updateCenter = mock(UpdateCenter.class);
private File downloadDir;
private File tmpDir;
@Before
public void setUp() throws IOException {
- MockitoAnnotations.initMocks(this);
- downloadDir = temp.newFolder();
+ downloadDir = temp.newFolder("download");
tmpDir = new File(downloadDir.getParentFile(), downloadDir.getName() + "_tmp");
- when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
when(fs.getEditionDownloadedPluginsDir()).thenReturn(downloadDir);
- downloader = new EditionPluginDownloader(updateCenterMatrixFactory, httpDownloader, fs);
+ downloader = new EditionPluginDownloader(httpDownloader, fs);
}
@Test
createRelease("plugin2", "1.0", "http://host/plugin2.jar"));
when(updateCenter.findInstallablePlugins("plugins", Version.create(""))).thenReturn(releases);
- downloader.installEdition(Collections.singleton("plugins"));
+ downloader.downloadEditionPlugins(Collections.singleton("plugins"), updateCenter);
verify(httpDownloader).download(new URI("http://host/plugin1.jar"), new File(tmpDir, "plugin1.jar"));
verify(httpDownloader).download(new URI("http://host/plugin2.jar"), new File(tmpDir, "plugin2.jar"));
when(updateCenter.findInstallablePlugins("plugins", Version.create(""))).thenReturn(releases);
try {
- downloader.installEdition(Collections.singleton("plugins"));
+ downloader.downloadEditionPlugins(Collections.singleton("plugins"), updateCenter);
fail("expecting exception");
} catch (IllegalStateException e) {
}
verify(httpDownloader).download(new URI("http://host/plugin1.jar"), new File(tmpDir, "plugin1.jar"));
- verify(httpDownloader).download(new URI("http://host/plugin2.jar"), new File(tmpDir, "plugin2.jar"));
assertThat(downloadDir.list()).isEmpty();
assertThat(tmpDir).doesNotExist();