From f96d9b615f76872e0853a083a8bf710c3214450e Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Mon, 24 Jun 2024 16:16:58 +0200 Subject: [PATCH] #213 add integration-test module to test reloading of configurations --- .../cms/api/configuration/Configuration.java | 2 +- .../managment/ConfigurationManagement.java | 10 +- .../thmarx/cms/filesystem/FileSystemTest.java | 8 +- integration-tests/pom.xml | 23 +++ .../reload/config/taxonomy.tags.yaml | 9 ++ integration-tests/reload/config/taxonomy.yaml | 10 ++ .../reload/taxonomies/taxonomy.tags.yaml | 9 ++ .../reload/taxonomies/taxonomy.yaml | 10 ++ .../ConfigurationManagementReloadTest.java | 141 ++++++++++++++++++ .../tests/ConfigurationReloadTest.java | 94 ++++++++++++ pom.xml | 1 + 11 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 integration-tests/pom.xml create mode 100644 integration-tests/reload/config/taxonomy.tags.yaml create mode 100644 integration-tests/reload/config/taxonomy.yaml create mode 100644 integration-tests/reload/taxonomies/taxonomy.tags.yaml create mode 100644 integration-tests/reload/taxonomies/taxonomy.yaml create mode 100644 integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationManagementReloadTest.java create mode 100644 integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationReloadTest.java diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/Configuration.java b/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/Configuration.java index 3149a3ef..7e492197 100644 --- a/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/Configuration.java +++ b/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/Configuration.java @@ -59,9 +59,9 @@ public T get(Class configClass) { public void reload(Class configClass) { try { - var env = get(ServerConfiguration.class).serverProperties().env(); log.debug("reload config + " + configClass.getSimpleName()); if (configClass.equals(SiteConfiguration.class)) { + var env = get(ServerConfiguration.class).serverProperties().env(); new SiteConfigurationLoader(hostBase, env).reload((SiteConfiguration)configs.get(configClass)); } else if (configClass.equals(TaxonomyConfiguration.class)) { new TaxonomyConfigurationLoader(hostBase).reload((TaxonomyConfiguration)configs.get(configClass)); diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/managment/ConfigurationManagement.java b/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/managment/ConfigurationManagement.java index 42ac4d92..fef2c6a8 100644 --- a/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/managment/ConfigurationManagement.java +++ b/cms-api/src/main/java/com/github/thmarx/cms/api/configuration/managment/ConfigurationManagement.java @@ -91,18 +91,22 @@ private void init_files () throws IOException { } public void init() throws IOException { + init(1, 1, TimeUnit.MINUTES); + } + + public void init(int initialDelay, int delay, TimeUnit timeUnit) throws IOException { init_files(); // setup scheduler - scheduler.scheduleWithFixedDelay(this, 1, 1, TimeUnit.MINUTES); + scheduler.scheduleWithFixedDelay(this, initialDelay, delay, timeUnit); } - + private void addPathToWatch(final Path configFile, final Class configClass) throws IOException { if (!Files.exists(configFile)) { return; } watched_configurations.add( - new ConfigurationResource(configFile, configClass, Files.getLastModifiedTime(configFile).toMillis()) + new ConfigurationResource(configFile, configClass, 0) ); } diff --git a/cms-filesystem/src/test/java/com/github/thmarx/cms/filesystem/FileSystemTest.java b/cms-filesystem/src/test/java/com/github/thmarx/cms/filesystem/FileSystemTest.java index e2c9f242..b545332c 100644 --- a/cms-filesystem/src/test/java/com/github/thmarx/cms/filesystem/FileSystemTest.java +++ b/cms-filesystem/src/test/java/com/github/thmarx/cms/filesystem/FileSystemTest.java @@ -26,6 +26,7 @@ import java.nio.file.Files; import java.nio.file.Path; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -39,8 +40,6 @@ public class FileSystemTest { static FileSystem fileSystem; - - @BeforeAll static void setup() throws IOException { @@ -55,6 +54,11 @@ static void setup() throws IOException { }); fileSystem.init(); } + + @AfterAll + static void shutdown () { + fileSystem.shutdown(); + } @Test public void test_seconday_index() throws IOException { diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml new file mode 100644 index 00000000..4779512b --- /dev/null +++ b/integration-tests/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + com.github.thmarx.cms + cms-parent + 5.1.0 + + integration-tests + jar + + + + com.github.thmarx.cms + cms-api + + + com.github.thmarx.cms + cms-filesystem + + + + \ No newline at end of file diff --git a/integration-tests/reload/config/taxonomy.tags.yaml b/integration-tests/reload/config/taxonomy.tags.yaml new file mode 100644 index 00000000..1b7740c3 --- /dev/null +++ b/integration-tests/reload/config/taxonomy.tags.yaml @@ -0,0 +1,9 @@ +## YAML Template. +--- +values: + - id: blue + title: Blau + - id: red + title: Rot + - id: orange + title: Orange \ No newline at end of file diff --git a/integration-tests/reload/config/taxonomy.yaml b/integration-tests/reload/config/taxonomy.yaml new file mode 100644 index 00000000..0005133f --- /dev/null +++ b/integration-tests/reload/config/taxonomy.yaml @@ -0,0 +1,10 @@ +## YAML Template. +--- +taxonomies: + - title: Kategorie + slug: kategorien + field: taxonomy.category + - title: Tags + slug: tags + field: taxonomy.tags + array: true \ No newline at end of file diff --git a/integration-tests/reload/taxonomies/taxonomy.tags.yaml b/integration-tests/reload/taxonomies/taxonomy.tags.yaml new file mode 100644 index 00000000..1b7740c3 --- /dev/null +++ b/integration-tests/reload/taxonomies/taxonomy.tags.yaml @@ -0,0 +1,9 @@ +## YAML Template. +--- +values: + - id: blue + title: Blau + - id: red + title: Rot + - id: orange + title: Orange \ No newline at end of file diff --git a/integration-tests/reload/taxonomies/taxonomy.yaml b/integration-tests/reload/taxonomies/taxonomy.yaml new file mode 100644 index 00000000..0005133f --- /dev/null +++ b/integration-tests/reload/taxonomies/taxonomy.yaml @@ -0,0 +1,10 @@ +## YAML Template. +--- +taxonomies: + - title: Kategorie + slug: kategorien + field: taxonomy.category + - title: Tags + slug: tags + field: taxonomy.tags + array: true \ No newline at end of file diff --git a/integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationManagementReloadTest.java b/integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationManagementReloadTest.java new file mode 100644 index 00000000..1d5ed1c2 --- /dev/null +++ b/integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationManagementReloadTest.java @@ -0,0 +1,141 @@ +package com.github.thmarx.cms.integration.tests; + +/*- + * #%L + * integration-tests + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +import com.github.thmarx.cms.api.ServerProperties; +import com.github.thmarx.cms.api.configuration.Configuration; +import com.github.thmarx.cms.api.configuration.ConfigurationManagement; +import com.github.thmarx.cms.api.configuration.configs.ServerConfiguration; +import com.github.thmarx.cms.api.eventbus.Event; +import com.github.thmarx.cms.api.eventbus.EventBus; +import com.github.thmarx.cms.api.eventbus.EventListener; +import com.github.thmarx.cms.filesystem.FileDB; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +/** + * + * @author t.marx + */ +public class ConfigurationManagementReloadTest { + + static FileDB db; + + static Configuration configuration; + + static ConfigurationManagement configurationManagement; + + static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + static MockEventBus eventBus = new MockEventBus(); + + @BeforeAll + static void setup() throws IOException { + + var serverProps = Mockito.mock(ServerProperties.class); + + Mockito.when(serverProps.env()).thenReturn("dev"); + + configuration = new Configuration(Path.of("reload/")); + configuration.add(ServerConfiguration.class, new ServerConfiguration(serverProps)); + + db = new FileDB(Path.of("reload/"), eventBus, (path) -> Map.of(), configuration); + db.init(); + + configurationManagement = new ConfigurationManagement(db, configuration, scheduler, eventBus); + configurationManagement.init(0, 5, TimeUnit.SECONDS); + } + + @BeforeEach + void prepare_clean_run () throws IOException { + Files.deleteIfExists(Path.of("reload/config/taxonomy.yaml")); + Files.deleteIfExists(Path.of("reload/config/taxonomy.tags.yaml")); + } + + @AfterAll + static void shutdown() throws Exception { + db.close(); + scheduler.shutdown(); + } + + @Test + void test_taxonomy() throws Exception { + + eventBus.reset(); + Files.copy( + Path.of("reload/taxonomies/taxonomy.yaml"), + Path.of("reload/config/taxonomy.yaml") + ); + Files.copy( + Path.of("reload/taxonomies/taxonomy.tags.yaml"), + Path.of("reload/config/taxonomy.tags.yaml") + ); + + configurationManagement.reload(); + + Thread.sleep(Duration.ofSeconds(6)); + + Assertions.assertThat(eventBus.pubCounter).isEqualTo(2); + } + + static class MockEventBus implements EventBus { + + private int pubCounter = 0; + + public void reset() { + pubCounter = 0; + } + + @Override + public void syncPublish(T event) { + } + + @Override + public void publish(T event) { + pubCounter++; + } + + @Override + public void register(Class eventClass, EventListener listener) { + } + + @Override + public void unregister(Class eventClass, EventListener listener) { + } + + @Override + public void unregister(EventListener listener) { + } + } +} diff --git a/integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationReloadTest.java b/integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationReloadTest.java new file mode 100644 index 00000000..c4a28b1c --- /dev/null +++ b/integration-tests/src/test/java/com/github/thmarx/cms/integration/tests/ConfigurationReloadTest.java @@ -0,0 +1,94 @@ +package com.github.thmarx.cms.integration.tests; + +/*- + * #%L + * integration-tests + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.github.thmarx.cms.api.configuration.Configuration; +import com.github.thmarx.cms.api.configuration.configs.TaxonomyConfiguration; +import com.github.thmarx.cms.api.eventbus.EventBus; +import com.github.thmarx.cms.filesystem.FileSystem; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.yaml.snakeyaml.Yaml; + +/** + * + * @author t.marx + */ +public class ConfigurationReloadTest { + + static FileSystem fileSystem; + + static Configuration configuration; + + @BeforeAll + static void setup() throws IOException { + + Files.deleteIfExists(Path.of("reload/config/taxonomy.yaml")); + Files.deleteIfExists(Path.of("reload/config/taxonomy.tags.yaml")); + + var eventBus = Mockito.mock(EventBus.class); + + fileSystem = new FileSystem(Path.of("reload/"), eventBus, (file) -> { + try { + return new Yaml().load(Files.readString(file)); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + fileSystem.init(); + + configuration = new Configuration(fileSystem.base()); + } + + @AfterAll + static void shutdown () { + fileSystem.shutdown(); + } + + @Test + void test_taxonomy () throws IOException { + + TaxonomyConfiguration config = configuration.get(TaxonomyConfiguration.class); + + Assertions.assertThat(config.getTaxonomies()).isEmpty(); + + Files.copy( + Path.of("reload/taxonomies/taxonomy.yaml"), + Path.of("reload/config/taxonomy.yaml") + ); + Files.copy( + Path.of("reload/taxonomies/taxonomy.tags.yaml"), + Path.of("reload/config/taxonomy.tags.yaml") + ); + + configuration.reload(TaxonomyConfiguration.class); + + Assertions.assertThat(config.getTaxonomies()).isNotEmpty(); + } +} diff --git a/pom.xml b/pom.xml index 3e4c7b4c..1c60464d 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ cms-content cms-extensions cms-auth + integration-tests 2023