From f4d47d3d82b331c1a79db68b8eb50f6a1962128b Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Thu, 12 Oct 2017 20:00:04 +0200 Subject: [PATCH] SONAR-9951 finalize edition install at startup (mocked implem.) --- .../sonar/db/property/PropertyDbTester.java | 6 + .../CommitPendingEditionOnStartup.java | 56 ++ .../EditionManagementCommitModule.java | 33 + .../server/edition/EditionsWsModule.java | 1 - .../StandaloneEditionManagementStateImpl.java | 48 +- .../platformlevel/PlatformLevel3.java | 4 +- .../EditionManagementCommitModuleTest.java | 40 ++ .../server/edition/EditionsWsModuleTest.java | 2 +- ...ndaloneEditionManagementStateImplTest.java | 611 ++++++++++++++++++ 9 files changed, 782 insertions(+), 19 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/edition/CommitPendingEditionOnStartup.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementCommitModule.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/edition/EditionManagementCommitModuleTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertyDbTester.java b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertyDbTester.java index b2bb7b7c5a4..0fcc80db723 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertyDbTester.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertyDbTester.java @@ -104,4 +104,10 @@ public class PropertyDbTester { dbSession.commit(); return this; } + + public PropertyDbTester insertEmptyInternal(String key) { + dbClient.internalPropertiesDao().saveAsEmpty(dbSession, key); + dbSession.commit(); + return this; + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/CommitPendingEditionOnStartup.java b/server/sonar-server/src/main/java/org/sonar/server/edition/CommitPendingEditionOnStartup.java new file mode 100644 index 00000000000..42909c09508 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/CommitPendingEditionOnStartup.java @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.edition; + +import org.sonar.api.Startable; + +public class CommitPendingEditionOnStartup implements Startable { + private final MutableEditionManagementState editionManagementState; + + public CommitPendingEditionOnStartup(MutableEditionManagementState editionManagementState) { + this.editionManagementState = editionManagementState; + } + + @Override + public void start() { + EditionManagementState.PendingStatus status = editionManagementState.getPendingInstallationStatus(); + switch (status) { + case NONE: + return; + case MANUAL_IN_PROGRESS: + case AUTOMATIC_READY: + // TODO save new license with plugin manager + editionManagementState.finalizeInstallation(); + break; + case AUTOMATIC_IN_PROGRESS: + // FIXME temporary hack until download of edition is implemented + editionManagementState.automaticInstallReady(); + editionManagementState.finalizeInstallation(); + break; + default: + throw new IllegalStateException("Unsupported status " + status); + } + } + + @Override + public void stop() { + // nothing to do + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementCommitModule.java b/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementCommitModule.java new file mode 100644 index 00000000000..6e417a40f38 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementCommitModule.java @@ -0,0 +1,33 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.edition; + +import org.sonar.core.platform.Module; + +public class EditionManagementCommitModule extends Module { + @Override + protected void configureModule() { + add( + // TODO add cluster ready implementation when not running Standalone + // Edition management WebServices also depend on this class + StandaloneEditionManagementStateImpl.class, + CommitPendingEditionOnStartup.class); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java index 0a1ca5d30f7..1f22a1c3182 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java @@ -28,7 +28,6 @@ public class EditionsWsModule extends Module { @Override protected void configureModule() { add( - StandaloneEditionManagementStateImpl.class, StatusAction.class, ApplyLicenseAction.class, EditionsWs.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java b/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java index 1ca7eb3e62f..5a714a4c7da 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java @@ -20,6 +20,7 @@ package org.sonar.server.edition; import com.google.common.collect.ImmutableSet; +import java.util.Arrays; import java.util.Map; import java.util.Optional; import org.picocontainer.Startable; @@ -37,14 +38,14 @@ import static org.sonar.server.edition.EditionManagementState.PendingStatus.MANU import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; public class StandaloneEditionManagementStateImpl implements MutableEditionManagementState, Startable { - private static final String CURRENT_EDITION_KEY = "sonar.editionManagement.currentEditionKey"; - private static final String PENDING_INSTALLATION_STATUS = "sonar.editionManagement.pendingInstallationStatus"; - private static final String PENDING_EDITION_KEY = "sonar.editionManagement.pendingEditionKey"; - private static final String PENDING_LICENSE = "sonar.editionManagement.pendingLicense"; + private static final String CURRENT_EDITION_KEY = "currentEditionKey"; + private static final String PENDING_INSTALLATION_STATUS = "pendingInstallStatus"; + private static final String PENDING_EDITION_KEY = "pendingEditionKey"; + private static final String PENDING_LICENSE = "pendingLicense"; private final DbClient dbClient; private String currentEditionKey; - private PendingStatus pendingInstallationStatus = NONE; + private PendingStatus pendingInstallationStatus; private String pendingEditionKey; private String pendingLicense; @@ -62,12 +63,15 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag .map(StandaloneEditionManagementStateImpl::emptyToNull) .orElse(null); this.pendingInstallationStatus = internalPropertyValues.getOrDefault(PENDING_INSTALLATION_STATUS, empty()) + .map(StandaloneEditionManagementStateImpl::emptyToNull) .map(PendingStatus::valueOf) .orElse(NONE); this.pendingEditionKey = internalPropertyValues.getOrDefault(PENDING_EDITION_KEY, empty()) .map(StandaloneEditionManagementStateImpl::emptyToNull) .orElse(null); - this.pendingLicense = internalPropertyValues.getOrDefault(PENDING_LICENSE, empty()).orElse(null); + this.pendingLicense = internalPropertyValues.getOrDefault(PENDING_LICENSE, empty()) + .map(StandaloneEditionManagementStateImpl::emptyToNull) + .orElse(null); } } @@ -78,28 +82,33 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag @Override public Optional getCurrentEditionKey() { + ensureStarted(); return Optional.ofNullable(currentEditionKey); } @Override public PendingStatus getPendingInstallationStatus() { + ensureStarted(); return pendingInstallationStatus; } @Override public Optional getPendingEditionKey() { + ensureStarted(); return Optional.ofNullable(pendingEditionKey); } @Override public Optional getPendingLicense() { + ensureStarted(); return Optional.ofNullable(pendingLicense); } @Override public synchronized PendingStatus startAutomaticInstall(License license) { + ensureStarted(); checkLicense(license); - changeStatusFromTo(NONE, AUTOMATIC_IN_PROGRESS); + changeStatusToFrom(AUTOMATIC_IN_PROGRESS, NONE); this.pendingLicense = license.getContent(); this.pendingEditionKey = license.getEditionKey(); persistProperties(); @@ -108,8 +117,9 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag @Override public synchronized PendingStatus startManualInstall(License license) { + ensureStarted(); checkLicense(license); - changeStatusFromTo(NONE, MANUAL_IN_PROGRESS); + changeStatusToFrom(MANUAL_IN_PROGRESS, NONE); this.pendingLicense = license.getContent(); this.pendingEditionKey = license.getEditionKey(); this.pendingInstallationStatus = MANUAL_IN_PROGRESS; @@ -119,9 +129,10 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag @Override public synchronized PendingStatus newEditionWithoutInstall(String newEditionKey) { + ensureStarted(); requireNonNull(newEditionKey, "newEditionKey can't be null"); checkArgument(!newEditionKey.isEmpty(), "newEditionKey can't be empty"); - changeStatusFromTo(NONE, NONE); + changeStatusToFrom(NONE, NONE); this.currentEditionKey = newEditionKey; persistProperties(); return this.pendingInstallationStatus; @@ -129,15 +140,16 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag @Override public synchronized PendingStatus automaticInstallReady() { - changeStatusFromTo(AUTOMATIC_IN_PROGRESS, AUTOMATIC_READY); + ensureStarted(); + changeStatusToFrom(AUTOMATIC_READY, AUTOMATIC_IN_PROGRESS); persistProperties(); return this.pendingInstallationStatus; } @Override public synchronized PendingStatus finalizeInstallation() { - checkState(this.pendingInstallationStatus == AUTOMATIC_READY || this.pendingInstallationStatus == MANUAL_IN_PROGRESS, - "Can't finalize installation when state is %s", this.pendingInstallationStatus); + ensureStarted(); + changeStatusToFrom(NONE, AUTOMATIC_READY, MANUAL_IN_PROGRESS); this.pendingInstallationStatus = NONE; this.currentEditionKey = this.pendingEditionKey; @@ -147,10 +159,14 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag return this.pendingInstallationStatus; } - private void changeStatusFromTo(PendingStatus expectedStatus, PendingStatus newStatus) { - checkState(pendingInstallationStatus == expectedStatus, - "Can't move to {} when status is {} (should be {})", - newStatus, pendingInstallationStatus, expectedStatus); + private void ensureStarted() { + checkState(pendingInstallationStatus != null, "%s is not started", getClass().getSimpleName()); + } + + private void changeStatusToFrom(PendingStatus newStatus, PendingStatus... validPendingStatuses) { + checkState(Arrays.stream(validPendingStatuses).anyMatch(s -> s == pendingInstallationStatus), + "Can't move to %s when status is %s (should be any of %s)", + newStatus, pendingInstallationStatus, Arrays.toString(validPendingStatuses)); this.pendingInstallationStatus = newStatus; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java index d7c3a3753b6..8df49bfdf3a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java @@ -21,6 +21,7 @@ package org.sonar.server.platform.platformlevel; import org.sonar.api.utils.UriReader; import org.sonar.core.util.DefaultHttpDownloader; +import org.sonar.server.edition.EditionManagementCommitModule; import org.sonar.server.organization.DefaultOrganizationProviderImpl; import org.sonar.server.organization.OrganizationFlagsImpl; import org.sonar.server.platform.ServerIdManager; @@ -47,6 +48,7 @@ public class PlatformLevel3 extends PlatformLevel { UriReader.class, DefaultHttpDownloader.class, DefaultOrganizationProviderImpl.class, - OrganizationFlagsImpl.class); + OrganizationFlagsImpl.class, + EditionManagementCommitModule.class); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/EditionManagementCommitModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/EditionManagementCommitModuleTest.java new file mode 100644 index 00000000000..859f87789a1 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/edition/EditionManagementCommitModuleTest.java @@ -0,0 +1,40 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.edition; + +import org.junit.Test; +import org.sonar.core.platform.ComponentContainer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; + +public class EditionManagementCommitModuleTest { + private EditionManagementCommitModule underTest = new EditionManagementCommitModule(); + + @Test + public void verify_component_count() { + ComponentContainer container = new ComponentContainer(); + underTest.configure(container); + + assertThat(container.getPicoContainer().getComponentAdapters()) + .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 2); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java index 116a4f4f2cd..c4fae543a77 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java @@ -34,6 +34,6 @@ public class EditionsWsModuleTest { underTest.configure(container); assertThat(container.getPicoContainer().getComponentAdapters()) - .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 4); + .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 3); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java new file mode 100644 index 00000000000..e657f951f0d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java @@ -0,0 +1,611 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.edition; + +import java.util.Collections; +import java.util.Random; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbTester; +import org.sonar.server.edition.EditionManagementState.PendingStatus; + +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_IN_PROGRESS; +import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_READY; +import static org.sonar.server.edition.EditionManagementState.PendingStatus.MANUAL_IN_PROGRESS; +import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; + +public class StandaloneEditionManagementStateImplTest { + private static final License LICENSE_WITHOUT_PLUGINS = new License(randomAlphanumeric(3), Collections.emptyList(), randomAlphanumeric(10)); + + @Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private DbClient dbClient = dbTester.getDbClient(); + private final StandaloneEditionManagementStateImpl underTest = new StandaloneEditionManagementStateImpl(dbClient); + + @Test + public void getCurrentEditionKey_fails_with_ISE_if_start_has_not_been_called() { + expectISENotStarted(); + + underTest.getCurrentEditionKey(); + } + + @Test + public void getCurrentEditionKey_returns_empty_when_internal_properties_table_is_empty() { + underTest.start(); + + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + + @Test + public void getCurrentEditionKey_returns_value_in_db_for_key_currentEditionKey() { + String value = randomAlphanumeric(10); + dbTester.properties().insertInternal("currentEditionKey", value); + underTest.start(); + + assertThat(underTest.getCurrentEditionKey()).contains(value); + } + + @Test + public void getCurrentEditionKey_returns_empty_when_value_in_db_is_empty_for_key_currentEditionKey() { + dbTester.properties().insertEmptyInternal("currentEditionKey"); + underTest.start(); + + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + + @Test + public void getPendingInstallationStatus_fails_with_ISE_if_start_has_not_been_called() { + expectISENotStarted(); + + underTest.getPendingInstallationStatus(); + } + + @Test + public void getPendingInstallationStatus_returns_NONE_when_internal_properties_table_is_empty() { + underTest.start(); + + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + } + + @Test + public void getPendingInstallationStatus_returns_value_in_db_for_key_pendingInstallStatus() { + PendingStatus value = PendingStatus.values()[new Random().nextInt(PendingStatus.values().length)]; + dbTester.properties().insertInternal("pendingInstallStatus", value.name()); + underTest.start(); + + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(value); + } + + @Test + public void getPendingInstallationStatus_returns_NONE_when_value_in_db_is_empty_for_key_pendingInstallStatus() { + dbTester.properties().insertEmptyInternal("pendingInstallStatus"); + underTest.start(); + + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + } + + @Test + public void start_fails_when_value_in_db_for_key_pendingInstallStatus_cannot_be_parsed_to_enum() { + String value = randomAlphanumeric(30); + dbTester.properties().insertInternal("pendingInstallStatus", value); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("No enum constant org.sonar.server.edition.EditionManagementState.PendingStatus." + value); + + underTest.start(); + } + + @Test + public void getPendingEditionKey_fails_with_ISE_if_start_has_not_been_called() { + expectISENotStarted(); + + underTest.getPendingEditionKey(); + } + + @Test + public void getPendingEditionKey_returns_empty_when_internal_properties_table_is_empty() { + underTest.start(); + + assertThat(underTest.getPendingEditionKey()).isEmpty(); + } + + @Test + public void getPendingEditionKey_returns_value_in_db_for_key_pendingEditionKey() { + String value = randomAlphanumeric(10); + dbTester.properties().insertInternal("pendingEditionKey", value); + underTest.start(); + + assertThat(underTest.getPendingEditionKey()).contains(value); + } + + @Test + public void getPendingEditionKey_returns_empty_when_value_in_db_is_empty_for_key_pendingEditionKey() { + dbTester.properties().insertEmptyInternal("pendingEditionKey"); + underTest.start(); + + assertThat(underTest.getPendingEditionKey()).isEmpty(); + } + + @Test + public void getPendingLicense_fails_with_ISE_if_start_has_not_been_called() { + expectISENotStarted(); + + underTest.getPendingLicense(); + } + + @Test + public void getPendingLicense_returns_empty_when_internal_properties_table_is_empty() { + underTest.start(); + + assertThat(underTest.getPendingLicense()).isEmpty(); + } + + @Test + public void getPendingLicense_returns_empty_value_in_db_for_key_pendingLicense() { + String value = randomAlphanumeric(10); + dbTester.properties().insertInternal("pendingLicense", value); + underTest.start(); + + assertThat(underTest.getPendingLicense()).contains(value); + } + + @Test + public void getPendingLicense_returns_empty_when_value_in_db_is_empty_for_key_pendingLicense() { + dbTester.properties().insertEmptyInternal("pendingLicense"); + underTest.start(); + + assertThat(underTest.getPendingLicense()).isEmpty(); + } + + @Test + public void startAutomaticInstall_fails_with_ISE_if_not_started() { + expectISENotStarted(); + + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void startAutomaticInstall_fails_with_NPE_if_license_is_null() { + underTest.start(); + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("license can't be null"); + + underTest.startAutomaticInstall(null); + } + + @Test + public void startAutomaticInstall_sets_pending_fields_after_start() { + underTest.start(); + + PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + + @Test + public void startAutomaticInstall_sets_pending_fields_after_start_with_existing_currentEditionKey() { + String value = randomAlphanumeric(10); + dbTester.properties().insertInternal("currentEditionKey", value); + underTest.start(); + + PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); + assertThat(underTest.getCurrentEditionKey()).contains(value); + } + + @Test + public void startAutomaticInstall_sets_pending_fields_after_newEditionWithoutInstall() { + String value = randomAlphanumeric(10); + underTest.start(); + underTest.newEditionWithoutInstall(value); + + PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); + assertThat(underTest.getCurrentEditionKey()).contains(value); + } + + @Test + public void startAutomaticInstall_fails_with_ISE_if_called_after_startAutomaticInstall() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to AUTOMATIC_IN_PROGRESS when status is AUTOMATIC_IN_PROGRESS (should be any of [NONE])"); + + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void startAutomaticInstall_fails_with_ISE_if_called_after_automaticInstallReady() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + underTest.automaticInstallReady(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to AUTOMATIC_IN_PROGRESS when status is AUTOMATIC_READY (should be any of [NONE])"); + + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void startAutomaticInstall_fails_with_ISE_if_called_after_manualInstall() { + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to AUTOMATIC_IN_PROGRESS when status is MANUAL_IN_PROGRESS (should be any of [NONE])"); + + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void startManualInstall_fails_with_ISE_if_not_started() { + expectISENotStarted(); + + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void startManualInstall_fails_with_NPE_if_license_is_null() { + underTest.start(); + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("license can't be null"); + + underTest.startManualInstall(null); + } + + @Test + public void startManualInstall_sets_pending_fields_after_start() { + underTest.start(); + + PendingStatus newStatus = underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + assertThat(newStatus).isEqualTo(MANUAL_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(MANUAL_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + + @Test + public void startManualInstall_sets_pending_fields_after_start_with_existing_currentEditionKey() { + String value = randomAlphanumeric(10); + dbTester.properties().insertInternal("currentEditionKey", value); + underTest.start(); + + PendingStatus newStatus = underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + assertThat(newStatus).isEqualTo(MANUAL_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(MANUAL_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); + assertThat(underTest.getCurrentEditionKey()).contains(value); + } + + @Test + public void startManualInstall_sets_pending_fields_after_newEditionWithoutInstall() { + String value = randomAlphanumeric(10); + underTest.start(); + underTest.newEditionWithoutInstall(value); + + PendingStatus newStatus = underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + assertThat(newStatus).isEqualTo(MANUAL_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(MANUAL_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); + assertThat(underTest.getCurrentEditionKey()).contains(value); + } + + @Test + public void startManualInstall_fails_with_ISE_if_called_after_startAutomaticInstall() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to MANUAL_IN_PROGRESS when status is AUTOMATIC_IN_PROGRESS (should be any of [NONE])"); + + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void startManualInstall_fails_with_ISE_if_called_after_automaticInstallReady() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + underTest.automaticInstallReady(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to MANUAL_IN_PROGRESS when status is AUTOMATIC_READY (should be any of [NONE])"); + + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void startManualInstall_fails_with_ISE_if_called_after_manualInstall() { + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to MANUAL_IN_PROGRESS when status is MANUAL_IN_PROGRESS (should be any of [NONE])"); + + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + } + + @Test + public void automaticInstallReady_fails_with_ISE_if_not_started() { + expectISENotStarted(); + + underTest.automaticInstallReady(); + } + + @Test + public void automaticInstallReady_fails_with_ISE_if_called() { + underTest.start(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is NONE (should be any of [AUTOMATIC_IN_PROGRESS])"); + + underTest.automaticInstallReady(); + } + + @Test + public void automaticInstallReady_fails_with_ISE_if_called_after_manualInstall() { + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is MANUAL_IN_PROGRESS (should be any of [AUTOMATIC_IN_PROGRESS])"); + + underTest.automaticInstallReady(); + } + + @Test + public void automaticInstallReady_after_startAutomaticInstall_changes_status_to_AUTOMATIC_READY_but_does_not_change_editions() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + PendingStatus newStatus = underTest.automaticInstallReady(); + + assertThat(newStatus).isEqualTo(AUTOMATIC_READY); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_READY); + assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + + @Test + public void newEditionWithoutInstall_fails_with_ISE_if_not_started() { + expectISENotStarted(); + + underTest.newEditionWithoutInstall(randomAlphanumeric(3)); + } + + @Test + public void newEditionWithoutInstall_fails_with_NPE_if_newEditionKey_is_null() { + underTest.start(); + + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("newEditionKey can't be null"); + + underTest.newEditionWithoutInstall(null); + } + + @Test + public void newEditionWithoutInstall_fails_with_IAE_if_newEditionKey_is_empty() { + underTest.start(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("newEditionKey can't be empty"); + + underTest.newEditionWithoutInstall(""); + } + + @Test + public void newEditionWithoutInstall_changes_current_edition() { + String newEditionKey = randomAlphanumeric(3); + underTest.start(); + + PendingStatus newStatus = underTest.newEditionWithoutInstall(newEditionKey); + + assertThat(newStatus).isEqualTo(NONE); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).contains(newEditionKey); + } + + @Test + public void newEditionWithoutInstall_overwrite_current_edition() { + String newEditionKey = randomAlphanumeric(3); + underTest.start(); + + PendingStatus newStatus = underTest.newEditionWithoutInstall(newEditionKey); + + assertThat(newStatus).isEqualTo(NONE); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).contains(newEditionKey); + } + + @Test + public void newEditionWithoutInstall_overwrites_from_previous_newEditionWithoutInstall() { + String newEditionKey1 = randomAlphanumeric(3); + String newEditionKey2 = randomAlphanumeric(3); + underTest.start(); + underTest.newEditionWithoutInstall(newEditionKey1); + + PendingStatus newStatus = underTest.newEditionWithoutInstall(newEditionKey2); + + assertThat(newStatus).isEqualTo(NONE); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).contains(newEditionKey2); + } + + @Test + public void newEditionWithoutInstall_fails_with_ISE_if_called_after_startAutomaticInstall() { + String newEditionKey = randomAlphanumeric(3); + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to NONE when status is AUTOMATIC_IN_PROGRESS (should be any of [NONE])"); + + underTest.newEditionWithoutInstall(newEditionKey); + } + + @Test + public void newEditionWithoutInstall_fails_with_ISE_if_called_after_startManualInstall() { + String newEditionKey = randomAlphanumeric(3); + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to NONE when status is MANUAL_IN_PROGRESS (should be any of [NONE])"); + + underTest.newEditionWithoutInstall(newEditionKey); + } + + @Test + public void finalizeInstallation_fails_with_ISE_if_not_started() { + expectISENotStarted(); + + underTest.finalizeInstallation(); + } + + @Test + public void finalizeInstallation_fails_with_ISE_after_start() { + underTest.start(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + + underTest.finalizeInstallation(); + } + + @Test + public void finalizeInstallation_fails_with_ISE_after_newEditionWithoutInstall() { + underTest.start(); + underTest.newEditionWithoutInstall(randomAlphanumeric(3)); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + + underTest.finalizeInstallation(); + } + + @Test + public void finalizeInstallation_fails_with_ISE_after_startAutomaticInstall() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to NONE when status is AUTOMATIC_IN_PROGRESS (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + + underTest.finalizeInstallation(); + } + + @Test + public void finalizeInstallation_set_new_edition_and_clear_pending_fields_after_manualInstallationReady() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + underTest.automaticInstallReady(); + + PendingStatus newStatus = underTest.finalizeInstallation(); + + assertThat(newStatus).isEqualTo(NONE); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + } + + @Test + public void finalizeInstallation_set_new_edition_and_clear_pending_fields_after_startManualInstall() { + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + PendingStatus newStatus = underTest.finalizeInstallation(); + + assertThat(newStatus).isEqualTo(NONE); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + } + + @Test + public void finalizeInstallation_overwrites_current_edition_and_clear_pending_fields_after_startManualInstall() { + String value = randomAlphanumeric(10); + dbTester.properties().insertInternal("currentEditionKey", value); + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + PendingStatus newStatus = underTest.finalizeInstallation(); + + assertThat(newStatus).isEqualTo(NONE); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); + } + + @Test + public void finalizeInstallation_fails_with_ISE_after_finalizeInstallation() { + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + underTest.finalizeInstallation(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + + underTest.finalizeInstallation(); + } + + private void expectISENotStarted() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("StandaloneEditionManagementStateImpl is not started"); + } + +} -- 2.39.5