From d45ce8cf57d1e2911954f93ac6e1fb0340be2f06 Mon Sep 17 00:00:00 2001 From: gjoranv Date: Mon, 5 Sep 2022 23:25:46 +0200 Subject: Redesign application bundle loading with a 'complete' phase. - To be able to uninstall bundles from a config generation that has failed, without affecting the bundles from the last successful generation. (Component reconfig with unchanged bundles was not handled correctly.) --- .../core/config/ApplicationBundleLoaderTest.java | 37 ++++++++++++++++++---- .../com/yahoo/container/core/config/TestOsgi.java | 4 +-- .../java/com/yahoo/container/di/ContainerTest.java | 4 +-- 3 files changed, 35 insertions(+), 10 deletions(-) (limited to 'container-core/src/test') diff --git a/container-core/src/test/java/com/yahoo/container/core/config/ApplicationBundleLoaderTest.java b/container-core/src/test/java/com/yahoo/container/core/config/ApplicationBundleLoaderTest.java index 7f223b0f5a0..fdd44fe358d 100644 --- a/container-core/src/test/java/com/yahoo/container/core/config/ApplicationBundleLoaderTest.java +++ b/container-core/src/test/java/com/yahoo/container/core/config/ApplicationBundleLoaderTest.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.core.config; +import com.yahoo.container.di.Osgi.GenerationStatus; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.osgi.framework.Bundle; @@ -15,6 +16,7 @@ import static com.yahoo.container.core.config.BundleTestUtil.BUNDLE_2; import static com.yahoo.container.core.config.BundleTestUtil.BUNDLE_2_REF; import static com.yahoo.container.core.config.BundleTestUtil.testBundles; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -46,9 +48,29 @@ public class ApplicationBundleLoaderTest { assertEquals(BUNDLE_1_REF, bundleLoader.getActiveFileReferences().get(0)); } + @Test + void generation_must_be_marked_complete_before_using_new_bundles() { + bundleLoader.useBundles(List.of(BUNDLE_1_REF)); + assertThrows(IllegalStateException.class, + () -> bundleLoader.useBundles(List.of(BUNDLE_1_REF))); + } + + @Test + void no_bundles_are_marked_obsolete_upon_reconfig_with_unchanged_bundles() { + bundleLoader.useBundles(List.of(BUNDLE_1_REF)); + bundleLoader.completeGeneration(GenerationStatus.SUCCESS); + + Set obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_1_REF, BUNDLE_2_REF)); + + // No bundles are obsolete + assertTrue(obsoleteBundles.isEmpty()); + } + @Test void new_bundle_can_be_installed_in_reconfig() { bundleLoader.useBundles(List.of(BUNDLE_1_REF)); + bundleLoader.completeGeneration(GenerationStatus.SUCCESS); + Set obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_1_REF, BUNDLE_2_REF)); // No bundles are obsolete @@ -73,6 +95,8 @@ public class ApplicationBundleLoaderTest { @Test void unused_bundle_is_marked_obsolete_after_reconfig() { bundleLoader.useBundles(List.of(BUNDLE_1_REF)); + bundleLoader.completeGeneration(GenerationStatus.SUCCESS); + Set obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_2_REF)); // The returned set of obsolete bundles contains bundle-1 @@ -97,11 +121,13 @@ public class ApplicationBundleLoaderTest { @Test void previous_generation_can_be_restored_after_a_failed_reconfig() { bundleLoader.useBundles(List.of(BUNDLE_1_REF)); + bundleLoader.completeGeneration(GenerationStatus.SUCCESS); + Set obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_2_REF)); assertEquals(BUNDLE_1.getSymbolicName(), obsoleteBundles.iterator().next().getSymbolicName()); // Revert to the previous generation, as will be done upon a failed reconfig. - Collection bundlesToUninstall = bundleLoader.revertToPreviousGeneration(); + Collection bundlesToUninstall = bundleLoader.completeGeneration(GenerationStatus.FAILURE); assertEquals(1, bundlesToUninstall.size()); assertEquals(BUNDLE_2.getSymbolicName(), bundlesToUninstall.iterator().next().getSymbolicName()); @@ -117,18 +143,17 @@ public class ApplicationBundleLoaderTest { } @Test - void bundles_are_unaffected_by_failed_reconfig_with_unchanged_bundles() { + void bundles_from_committed_config_generation_are_not_uninstalled_upon_future_failed_reconfig() { bundleLoader.useBundles(List.of(BUNDLE_1_REF)); - Set obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_1_REF)); - assertTrue(obsoleteBundles.isEmpty()); + bundleLoader.completeGeneration(GenerationStatus.SUCCESS); // Revert to the previous generation, as will be done upon a failed reconfig. - Collection bundlesToUninstall = bundleLoader.revertToPreviousGeneration(); + Collection bundlesToUninstall = bundleLoader.completeGeneration(GenerationStatus.FAILURE); assertEquals(0, bundlesToUninstall.size()); assertEquals(1, osgi.getCurrentBundles().size()); - obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_1_REF)); + Set obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_1_REF)); assertTrue(obsoleteBundles.isEmpty()); assertEquals(1, osgi.getCurrentBundles().size()); } diff --git a/container-core/src/test/java/com/yahoo/container/core/config/TestOsgi.java b/container-core/src/test/java/com/yahoo/container/core/config/TestOsgi.java index b48aae2e300..d634d7b7ce2 100644 --- a/container-core/src/test/java/com/yahoo/container/core/config/TestOsgi.java +++ b/container-core/src/test/java/com/yahoo/container/core/config/TestOsgi.java @@ -70,8 +70,8 @@ public class TestOsgi extends MockOsgi implements com.yahoo.container.di.Osgi { } @Override - public Collection revertApplicationBundles() { - return bundleLoader.revertToPreviousGeneration(); + public Collection completeBundleGeneration(GenerationStatus status) { + return bundleLoader.completeGeneration(status); } public void removeBundle(Bundle bundle) { diff --git a/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java b/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java index 23649f8de72..5fbb035136f 100644 --- a/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java +++ b/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java @@ -10,13 +10,13 @@ import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.SimpleCompo import com.yahoo.container.di.componentgraph.core.ComponentNode.ComponentConstructorException; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.osgi.framework.Bundle; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -252,7 +252,7 @@ public class ContainerTest extends ContainerTestBase { try { newGraph.get(1, TimeUnit.SECONDS); fail("Expected waiting for new config."); - } catch (Exception ignored) { + } catch (TimeoutException ignored) { // expect to time out } -- cgit v1.2.3