From 9c1b63eb1667e330d0c1f652c6ac071d56154011 Mon Sep 17 00:00:00 2001 From: Peter Palaga Date: Mon, 28 Sep 2020 18:23:19 +0200 Subject: [PATCH 1/2] Test BOM edits #9 --- build/publish-on-sdkman.sh | 16 ++++ .../jboss/fuse/mvnd/client/ClientLayout.java | 9 +++ .../org/jboss/fuse/mvnd/common/Layout.java | 8 +- .../fuse/mvnd/it/ModuleAndPluginNativeIT.java | 5 +- .../fuse/mvnd/it/UpgradesInBomNativeIT.java | 80 +++++++++++++++++++ .../jboss/fuse/mvnd/it/UpgradesInBomTest.java | 80 +++++++++++++++++++ .../jboss/fuse/mvnd/junit/ClientFactory.java | 23 ++++++ .../fuse/mvnd/junit/MvndTestExtension.java | 67 ++++++---------- .../jboss/fuse/mvnd/junit/TestRegistry.java | 53 ++++++++++++ .../org/jboss/fuse/mvnd/junit/TestUtils.java | 37 +++++++++ .../test/projects/module-and-plugin/pom.xml | 2 +- .../src/test/projects/multi-module/pom.xml | 2 +- .../src/test/projects/single-module/pom.xml | 2 +- .../upgrades-in-bom/hello-0.0.1/pom.xml | 71 ++++++++++++++++ .../mvnd/test/upgrades/bom/hello/Hello.java | 24 ++++++ .../hello-0.0.2-SNAPSHOT/pom.xml | 71 ++++++++++++++++ .../mvnd/test/upgrades/bom/hello/Hello.java | 24 ++++++ .../upgrades-in-bom/parent/.mvn/.gitkeep | 0 .../upgrades-in-bom/parent/bom/pom.xml | 41 ++++++++++ .../upgrades-in-bom/parent/module/pom.xml | 49 ++++++++++++ .../test/upgrades/bom/module/UseHello.java | 26 ++++++ .../projects/upgrades-in-bom/parent/pom.xml | 77 ++++++++++++++++++ 22 files changed, 716 insertions(+), 51 deletions(-) create mode 100644 integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomNativeIT.java create mode 100644 integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomTest.java create mode 100644 integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/ClientFactory.java create mode 100644 integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestRegistry.java create mode 100644 integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestUtils.java create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/pom.xml create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/pom.xml create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/parent/.mvn/.gitkeep create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/parent/bom/pom.xml create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/parent/module/pom.xml create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/parent/module/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/module/UseHello.java create mode 100644 integration-tests/src/test/projects/upgrades-in-bom/parent/pom.xml diff --git a/build/publish-on-sdkman.sh b/build/publish-on-sdkman.sh index a6a547d0..25649028 100755 --- a/build/publish-on-sdkman.sh +++ b/build/publish-on-sdkman.sh @@ -1,4 +1,20 @@ #!/usr/bin/env bash +# +# Copyright 2019 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + set -e #set -x diff --git a/client/src/main/java/org/jboss/fuse/mvnd/client/ClientLayout.java b/client/src/main/java/org/jboss/fuse/mvnd/client/ClientLayout.java index f3562d6c..07a0d968 100644 --- a/client/src/main/java/org/jboss/fuse/mvnd/client/ClientLayout.java +++ b/client/src/main/java/org/jboss/fuse/mvnd/client/ClientLayout.java @@ -88,6 +88,15 @@ public class ClientLayout extends Layout { this.logbackConfigurationPath = logbackConfigurationPath; } + /** + * @param newUserDir where to change the current directory to + * @return a new {@link ClientLayout} with {@code userDir} set to the given {@code newUserDir} + */ + public ClientLayout cd(Path newUserDir) { + return new ClientLayout(mvndPropertiesPath, mavenHome, newUserDir, multiModuleProjectDirectory, javaHome, + localMavenRepository, settings, logbackConfigurationPath); + } + /** * @return absolute normalized path to local Maven repository or {@code null} if the server is supposed to use the * default diff --git a/common/src/main/java/org/jboss/fuse/mvnd/common/Layout.java b/common/src/main/java/org/jboss/fuse/mvnd/common/Layout.java index daf1d36c..05afa274 100644 --- a/common/src/main/java/org/jboss/fuse/mvnd/common/Layout.java +++ b/common/src/main/java/org/jboss/fuse/mvnd/common/Layout.java @@ -27,10 +27,10 @@ public class Layout { private static Layout ENV_INSTANCE; - private final Path mavenHome; - private final Path userDir; - private final Path multiModuleProjectDirectory; - private final Path mvndPropertiesPath; + protected final Path mavenHome; + protected final Path userDir; + protected final Path multiModuleProjectDirectory; + protected final Path mvndPropertiesPath; public Layout(Path mvndPropertiesPath, Path mavenHome, Path userDir, Path multiModuleProjectDirectory) { super(); diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/ModuleAndPluginNativeIT.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/ModuleAndPluginNativeIT.java index 7bc01fa3..ad307f5b 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/ModuleAndPluginNativeIT.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/ModuleAndPluginNativeIT.java @@ -26,6 +26,7 @@ import org.jboss.fuse.mvnd.client.Client; import org.jboss.fuse.mvnd.client.ClientLayout; import org.jboss.fuse.mvnd.client.ClientOutput; import org.jboss.fuse.mvnd.junit.MvndNativeTest; +import org.jboss.fuse.mvnd.junit.TestUtils; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -68,9 +69,7 @@ public class ModuleAndPluginNativeIT { { final Path mojoPath = layout.multiModuleProjectDirectory() .resolve("plugin/src/main/java/org/jboss/fuse/mvnd/test/module/plugin/mojo/HelloMojo.java"); - String mojoSource = new String(Files.readAllBytes(mojoPath), StandardCharsets.UTF_8); - mojoSource = mojoSource.replace("\"Hello\".getBytes", "\"Hi\".getBytes"); - Files.write(mojoPath, mojoSource.getBytes(StandardCharsets.UTF_8)); + TestUtils.replace(mojoPath, "\"Hello\".getBytes", "\"Hi\".getBytes"); final ClientOutput output = Mockito.mock(ClientOutput.class); client.execute(output, diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomNativeIT.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomNativeIT.java new file mode 100644 index 00000000..18a174b0 --- /dev/null +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomNativeIT.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.it; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import javax.inject.Inject; +import org.assertj.core.api.Assertions; +import org.jboss.fuse.mvnd.client.Client; +import org.jboss.fuse.mvnd.client.ClientOutput; +import org.jboss.fuse.mvnd.junit.ClientFactory; +import org.jboss.fuse.mvnd.junit.MvndNativeTest; +import org.jboss.fuse.mvnd.junit.TestLayout; +import org.jboss.fuse.mvnd.junit.TestRegistry; +import org.jboss.fuse.mvnd.junit.TestUtils; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +@MvndNativeTest(projectDir = "src/test/projects/upgrades-in-bom") +public class UpgradesInBomNativeIT { + + @Inject + TestLayout layout; + + @Inject + TestRegistry registry; + + @Inject + ClientFactory clientFactory; + + @Test + void upgrade() throws IOException, InterruptedException { + /* Install the dependencies */ + for (String artifactDir : Arrays.asList("project/hello-0.0.1", "project/hello-0.0.2-SNAPSHOT")) { + final Client cl = clientFactory.newClient(layout.cd(layout.getTestDir().resolve(artifactDir))); + final ClientOutput output = Mockito.mock(ClientOutput.class); + cl.execute(output, "clean", "install", "-e").assertSuccess(); + registry.killAll(); + } + Assertions.assertThat(registry.getAll().size()).isEqualTo(0); + + /* Build the initial state of the test project */ + final Path parentDir = layout.getTestDir().resolve("project/parent"); + final Client cl = clientFactory.newClient(layout.cd(parentDir)); + { + final ClientOutput output = Mockito.mock(ClientOutput.class); + cl.execute(output, "clean", "install", "-e").assertSuccess(); + } + Assertions.assertThat(registry.getAll().size()).isEqualTo(1); + + /* Upgrade the dependency */ + final Path parentPomPath = parentDir.resolve("pom.xml"); + TestUtils.replace(parentPomPath, "0.0.1", + "0.0.2-SNAPSHOT"); + /* Adapt the caller */ + final Path useHelloPath = parentDir + .resolve("module/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/module/UseHello.java"); + TestUtils.replace(useHelloPath, "new Hello().sayHello()", "new Hello().sayWisdom()"); + { + final ClientOutput output = Mockito.mock(ClientOutput.class); + cl.execute(output, "clean", "install", "-e").assertSuccess(); + } + Assertions.assertThat(registry.getAll().size()).isEqualTo(1); + + } +} diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomTest.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomTest.java new file mode 100644 index 00000000..7bd3ba7d --- /dev/null +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/UpgradesInBomTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.it; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import javax.inject.Inject; +import org.assertj.core.api.Assertions; +import org.jboss.fuse.mvnd.client.Client; +import org.jboss.fuse.mvnd.client.ClientOutput; +import org.jboss.fuse.mvnd.junit.ClientFactory; +import org.jboss.fuse.mvnd.junit.MvndTest; +import org.jboss.fuse.mvnd.junit.TestLayout; +import org.jboss.fuse.mvnd.junit.TestRegistry; +import org.jboss.fuse.mvnd.junit.TestUtils; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +@MvndTest(projectDir = "src/test/projects/upgrades-in-bom") +public class UpgradesInBomTest { + + @Inject + TestLayout layout; + + @Inject + TestRegistry registry; + + @Inject + ClientFactory clientFactory; + + @Test + void upgrade() throws IOException, InterruptedException { + /* Install the dependencies */ + for (String artifactDir : Arrays.asList("project/hello-0.0.1", "project/hello-0.0.2-SNAPSHOT")) { + final Client cl = clientFactory.newClient(layout.cd(layout.getTestDir().resolve(artifactDir))); + final ClientOutput output = Mockito.mock(ClientOutput.class); + cl.execute(output, "clean", "install", "-e").assertSuccess(); + registry.killAll(); + } + Assertions.assertThat(registry.getAll().size()).isEqualTo(0); + + /* Build the initial state of the test project */ + final Path parentDir = layout.getTestDir().resolve("project/parent"); + final Client cl = clientFactory.newClient(layout.cd(parentDir)); + { + final ClientOutput output = Mockito.mock(ClientOutput.class); + cl.execute(output, "clean", "install", "-e").assertSuccess(); + } + Assertions.assertThat(registry.getAll().size()).isEqualTo(1); + + /* Upgrade the dependency */ + final Path parentPomPath = parentDir.resolve("pom.xml"); + TestUtils.replace(parentPomPath, "0.0.1", + "0.0.2-SNAPSHOT"); + /* Adapt the caller */ + final Path useHelloPath = parentDir + .resolve("module/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/module/UseHello.java"); + TestUtils.replace(useHelloPath, "new Hello().sayHello()", "new Hello().sayWisdom()"); + { + final ClientOutput output = Mockito.mock(ClientOutput.class); + cl.execute(output, "clean", "install", "-e").assertSuccess(); + } + Assertions.assertThat(registry.getAll().size()).isEqualTo(1); + + } +} diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/ClientFactory.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/ClientFactory.java new file mode 100644 index 00000000..0fe9f70c --- /dev/null +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/ClientFactory.java @@ -0,0 +1,23 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.junit; + +import org.jboss.fuse.mvnd.client.Client; +import org.jboss.fuse.mvnd.client.ClientLayout; + +public interface ClientFactory { + Client newClient(ClientLayout layout); +} diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java index f8419cf5..7324a130 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java @@ -22,18 +22,16 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Comparator; -import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.stream.Stream; import org.jboss.fuse.mvnd.client.Client; +import org.jboss.fuse.mvnd.client.ClientLayout; import org.jboss.fuse.mvnd.client.DefaultClient; import org.jboss.fuse.mvnd.common.BuildProperties; -import org.jboss.fuse.mvnd.common.DaemonInfo; import org.jboss.fuse.mvnd.common.DaemonRegistry; import org.jboss.fuse.mvnd.common.Environment; import org.jboss.fuse.mvnd.common.Layout; -import org.jboss.fuse.mvnd.jpm.ProcessImpl; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; @@ -92,26 +90,15 @@ public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, javax.inject.Inject inject = f.getAnnotation(javax.inject.Inject.class); if (inject != null) { f.setAccessible(true); - if (f.getType() == DaemonRegistry.class) { + if (DaemonRegistry.class.isAssignableFrom(f.getType())) { f.set(testInstance, resource.registry); } else if (Layout.class.isAssignableFrom(f.getType())) { f.set(testInstance, resource.layout); } else if (f.getType() == Client.class) { - if (resource.isNative) { - final Path mvndNativeExecutablePath = resource.layout.mavenHome().resolve( - System.getProperty("os.name").toLowerCase(Locale.ROOT).startsWith("windows") - ? "bin/mvnd.exe" - : "bin/mvnd") - .toAbsolutePath().normalize(); - if (!Files.isRegularFile(mvndNativeExecutablePath)) { - throw new IllegalStateException("mvnd executable does not exist: " + mvndNativeExecutablePath); - } - f.set(testInstance, - new NativeTestClient(resource.layout, mvndNativeExecutablePath, resource.timeoutMs)); - } else { - f.set(testInstance, new DefaultClient(() -> resource.layout, BuildProperties.getInstance())); - } - } else if (f.getType() == NativeTestClient.class) { + f.set(testInstance, newClient(resource.isNative, resource.layout, resource.timeoutMs)); + } else if (f.getType() == ClientFactory.class) { + final ClientFactory cf = customLayout -> newClient(resource.isNative, customLayout, resource.timeoutMs); + f.set(testInstance, cf); } } } @@ -119,6 +106,22 @@ public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, } } + Client newClient(boolean isNative, ClientLayout layout, long timeoutMs) { + if (isNative) { + final Path mvndNativeExecutablePath = layout.mavenHome().resolve( + System.getProperty("os.name").toLowerCase(Locale.ROOT).startsWith("windows") + ? "bin/mvnd.exe" + : "bin/mvnd") + .toAbsolutePath().normalize(); + if (!Files.isRegularFile(mvndNativeExecutablePath)) { + throw new IllegalStateException("mvnd executable does not exist: " + mvndNativeExecutablePath); + } + return new NativeTestClient(layout, mvndNativeExecutablePath, timeoutMs); + } else { + return new DefaultClient(() -> layout, BuildProperties.getInstance()); + } + } + @Override public void afterAll(ExtensionContext context) throws Exception { final Store store = context.getRoot().getStore(ExtensionContext.Namespace.GLOBAL); @@ -131,7 +134,7 @@ public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, static class MvndResource implements ExtensionContext.Store.CloseableResource { private final TestLayout layout; - private final DaemonRegistry registry; + private final TestRegistry registry; private final boolean isNative; private final long timeoutMs; @@ -195,7 +198,7 @@ public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, Paths.get(System.getProperty("java.home")).toAbsolutePath().normalize(), localMavenRepository, settingsPath, mvndHome.resolve("conf/logging/logback.xml")); - final DaemonRegistry registry = new DaemonRegistry(layout.registry()); + final TestRegistry registry = new TestRegistry(layout.registry()); return new MvndResource(layout, registry, isNative, timeoutMs); } @@ -234,7 +237,7 @@ public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, return settingsPath; } - public MvndResource(TestLayout layout, DaemonRegistry registry, boolean isNative, long timeoutMs) { + public MvndResource(TestLayout layout, TestRegistry registry, boolean isNative, long timeoutMs) { super(); this.layout = layout; this.registry = registry; @@ -244,25 +247,7 @@ public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, @Override public void close() throws Exception { - List daemons; - final int timeout = 5000; - final long deadline = System.currentTimeMillis() + timeout; - while (!(daemons = registry.getAll()).isEmpty()) { - for (DaemonInfo di : daemons) { - try { - new ProcessImpl(di.getPid()).destroy(); - } catch (IOException t) { - System.out.println("Daemon " + di.getUid() + ": " + t.getMessage()); - } catch (Exception t) { - System.out.println("Daemon " + di.getUid() + ": " + t); - } finally { - registry.remove(di.getUid()); - } - } - if (deadline < System.currentTimeMillis() && !registry.getAll().isEmpty()) { - throw new RuntimeException("Could not stop all mvnd daemons within " + timeout + " ms"); - } - } + registry.killAll(); } } diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestRegistry.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestRegistry.java new file mode 100644 index 00000000..3f7ef297 --- /dev/null +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestRegistry.java @@ -0,0 +1,53 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.junit; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import org.jboss.fuse.mvnd.common.DaemonInfo; +import org.jboss.fuse.mvnd.common.DaemonRegistry; +import org.jboss.fuse.mvnd.jpm.ProcessImpl; + +public class TestRegistry extends DaemonRegistry { + + public TestRegistry(Path registryFile) { + super(registryFile); + } + + public void killAll() { + List daemons; + final int timeout = 5000; + final long deadline = System.currentTimeMillis() + timeout; + while (!(daemons = getAll()).isEmpty()) { + for (DaemonInfo di : daemons) { + try { + new ProcessImpl(di.getPid()).destroy(); + } catch (IOException t) { + System.out.println("Daemon " + di.getUid() + ": " + t.getMessage()); + } catch (Exception t) { + System.out.println("Daemon " + di.getUid() + ": " + t); + } finally { + remove(di.getUid()); + } + } + if (deadline < System.currentTimeMillis() && !getAll().isEmpty()) { + throw new RuntimeException("Could not stop all mvnd daemons within " + timeout + " ms"); + } + } + } + +} diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestUtils.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestUtils.java new file mode 100644 index 00000000..3dd40f49 --- /dev/null +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/TestUtils.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.junit; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +public class TestUtils { + + public static void replace(Path path, String find, String replacement) { + try { + final String originalSrc = new String(Files.readAllBytes(path), StandardCharsets.UTF_8); + final String newSrc = originalSrc.replace(find, replacement); + if (originalSrc.equals(newSrc)) { + throw new IllegalStateException("[" + find + "] not found in " + path); + } + Files.write(path, newSrc.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new RuntimeException("Could not read or write " + path, e); + } + } +} diff --git a/integration-tests/src/test/projects/module-and-plugin/pom.xml b/integration-tests/src/test/projects/module-and-plugin/pom.xml index 78d9ea3f..9ee25d20 100644 --- a/integration-tests/src/test/projects/module-and-plugin/pom.xml +++ b/integration-tests/src/test/projects/module-and-plugin/pom.xml @@ -30,7 +30,7 @@ 1.8 2.5 - 3.1 + 3.8.0 2.4 2.6 3.0.0-M4 diff --git a/integration-tests/src/test/projects/multi-module/pom.xml b/integration-tests/src/test/projects/multi-module/pom.xml index 1c1368c9..95dc9839 100644 --- a/integration-tests/src/test/projects/multi-module/pom.xml +++ b/integration-tests/src/test/projects/multi-module/pom.xml @@ -30,7 +30,7 @@ 1.8 2.5 - 3.1 + 3.8.0 2.4 2.6 3.0.0-M4 diff --git a/integration-tests/src/test/projects/single-module/pom.xml b/integration-tests/src/test/projects/single-module/pom.xml index 7d8f94b5..05fff788 100644 --- a/integration-tests/src/test/projects/single-module/pom.xml +++ b/integration-tests/src/test/projects/single-module/pom.xml @@ -30,7 +30,7 @@ 1.8 2.5 - 3.1 + 3.8.0 2.4 2.6 3.0.0-M4 diff --git a/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/pom.xml b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/pom.xml new file mode 100644 index 00000000..236771a7 --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-hello + 0.0.1 + jar + + + UTF-8 + 1.8 + 1.8 + + 2.5 + 3.8.0 + 2.4 + 2.6 + 3.0.0-M4 + + + + + + + org.apache.maven.plugins + maven-clean-plugin + ${maven-clean-plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-install-plugin + ${maven-install-plugin.version} + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + + + \ No newline at end of file diff --git a/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java new file mode 100644 index 00000000..507febe0 --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.1/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java @@ -0,0 +1,24 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.test.upgrades.bom.hello; + +public class Hello { + + public String sayHello() { + return "Hello"; + } + +} diff --git a/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/pom.xml b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/pom.xml new file mode 100644 index 00000000..53fe6991 --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-hello + 0.0.2-SNAPSHOT + jar + + + UTF-8 + 1.8 + 1.8 + + 2.5 + 3.8.0 + 2.4 + 2.6 + 3.0.0-M4 + + + + + + + org.apache.maven.plugins + maven-clean-plugin + ${maven-clean-plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-install-plugin + ${maven-install-plugin.version} + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + + + \ No newline at end of file diff --git a/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java new file mode 100644 index 00000000..09fa789d --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/hello-0.0.2-SNAPSHOT/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/hello/Hello.java @@ -0,0 +1,24 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.test.upgrades.bom.hello; + +public class Hello { + + public int sayWisdom() { + return 42; + } + +} diff --git a/integration-tests/src/test/projects/upgrades-in-bom/parent/.mvn/.gitkeep b/integration-tests/src/test/projects/upgrades-in-bom/parent/.mvn/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/integration-tests/src/test/projects/upgrades-in-bom/parent/bom/pom.xml b/integration-tests/src/test/projects/upgrades-in-bom/parent/bom/pom.xml new file mode 100644 index 00000000..ac69e0b3 --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/parent/bom/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-parent + 0.0.1-SNAPSHOT + ../pom.xml + + + upgrades-in-bom-bom + pom + + + + + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-hello + ${hello.version} + + + + + \ No newline at end of file diff --git a/integration-tests/src/test/projects/upgrades-in-bom/parent/module/pom.xml b/integration-tests/src/test/projects/upgrades-in-bom/parent/module/pom.xml new file mode 100644 index 00000000..2980b514 --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/parent/module/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-parent + 0.0.1-SNAPSHOT + ../pom.xml + + + upgrades-in-bom-module + + + + + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-bom + 0.0.1-SNAPSHOT + pom + import + + + + + + + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-hello + + + + \ No newline at end of file diff --git a/integration-tests/src/test/projects/upgrades-in-bom/parent/module/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/module/UseHello.java b/integration-tests/src/test/projects/upgrades-in-bom/parent/module/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/module/UseHello.java new file mode 100644 index 00000000..0488cb1b --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/parent/module/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/module/UseHello.java @@ -0,0 +1,26 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.test.upgrades.bom.module; + +import org.jboss.fuse.mvnd.test.upgrades.bom.hello.Hello; + +public class UseHello { + + public void use() { + System.out.println(new Hello().sayHello()); + } + +} diff --git a/integration-tests/src/test/projects/upgrades-in-bom/parent/pom.xml b/integration-tests/src/test/projects/upgrades-in-bom/parent/pom.xml new file mode 100644 index 00000000..53260012 --- /dev/null +++ b/integration-tests/src/test/projects/upgrades-in-bom/parent/pom.xml @@ -0,0 +1,77 @@ + + + + 4.0.0 + org.jboss.fuse.mvnd.test.upgrades-in-bom + upgrades-in-bom-parent + 0.0.1-SNAPSHOT + pom + + + 0.0.1 + UTF-8 + 1.8 + 1.8 + + 2.5 + 3.8.0 + 2.4 + 2.6 + 3.0.0-M4 + + + + bom + module + + + + + + + org.apache.maven.plugins + maven-clean-plugin + ${maven-clean-plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-install-plugin + ${maven-install-plugin.version} + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + + + \ No newline at end of file From 16a93e4a3a9053f00afd2c904755ed7df405b854 Mon Sep 17 00:00:00 2001 From: Peter Palaga Date: Tue, 29 Sep 2020 09:47:07 +0200 Subject: [PATCH 2/2] CachingProjectBuilder ignored #72 --- .../jboss/fuse/mvnd/common/ServerMain.java | 15 +- daemon/pom.xml | 17 +++ .../org/jboss/fuse/mvnd/daemon/Server.java | 18 +-- daemon/src/main/provisio/maven-distro.xml | 41 ++++- .../org/jboss/fuse/mvnd/dist/DistroIT.java | 141 ++++++++++++++++++ 5 files changed, 217 insertions(+), 15 deletions(-) create mode 100644 daemon/src/test/java/org/jboss/fuse/mvnd/dist/DistroIT.java diff --git a/common/src/main/java/org/jboss/fuse/mvnd/common/ServerMain.java b/common/src/main/java/org/jboss/fuse/mvnd/common/ServerMain.java index c4a0d88b..734260a4 100644 --- a/common/src/main/java/org/jboss/fuse/mvnd/common/ServerMain.java +++ b/common/src/main/java/org/jboss/fuse/mvnd/common/ServerMain.java @@ -28,11 +28,21 @@ public class ServerMain { final String uidStr = Environment.DAEMON_UID.systemProperty().orFail().asString(); final Path mavenHome = Environment.MVND_HOME.systemProperty().orFail().asPath(); URL[] classpath = Stream.concat( - Stream.concat(Files.list(mavenHome.resolve("lib/ext")), - Files.list(mavenHome.resolve("lib"))) + /* jars */ + Stream.of("lib/ext", "lib", "boot") + .map(mavenHome::resolve) + .flatMap((Path p) -> { + try { + return Files.list(p); + } catch (java.io.IOException e) { + throw new RuntimeException("Could not list " + p, e); + } + }) .filter(p -> p.getFileName().toString().endsWith(".jar")) .filter(Files::isRegularFile), + /* resources */ Stream.of(mavenHome.resolve("conf"), mavenHome.resolve("conf/logging"))) + .map(Path::normalize) .map(Path::toUri) .map(uri -> { @@ -56,6 +66,7 @@ public class ServerMain { Thread.currentThread().setContextClassLoader(loader); Class clazz = loader.loadClass("org.jboss.fuse.mvnd.daemon.Server"); try (AutoCloseable server = (AutoCloseable) clazz.getConstructor(String.class).newInstance(uidStr)) { + System.out.println("server = " + server); ((Runnable) server).run(); } } diff --git a/daemon/pom.xml b/daemon/pom.xml index cb6048dc..6e4a5ed1 100644 --- a/daemon/pom.xml +++ b/daemon/pom.xml @@ -92,6 +92,23 @@ + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + ${project.basedir}/target/maven-distro/mvnd-${project.version}-${os.detected.name}-${os.detected.arch} + + + + + io.takari.maven.plugins takari-lifecycle-plugin diff --git a/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java b/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java index 27510185..824f545a 100644 --- a/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java +++ b/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java @@ -69,15 +69,15 @@ public class Server implements AutoCloseable, Runnable { public static final int CANCEL_TIMEOUT = 10 * 1000; public static final int DEFAULT_IDLE_TIMEOUT = (int) TimeUnit.HOURS.toMillis(3); - private String uid; - private ServerSocketChannel socket; - private DaemonMavenCli cli; - private DaemonInfo info; - private DaemonRegistry registry; + private final String uid; + private final ServerSocketChannel socket; + private final DaemonMavenCli cli; + private volatile DaemonInfo info; + private final DaemonRegistry registry; private final Layout layout; - private ScheduledExecutorService executor; - private DaemonExpirationStrategy strategy; + private final ScheduledExecutorService executor; + private final DaemonExpirationStrategy strategy; private final Lock expirationLock = new ReentrantLock(); private final Lock stateLock = new ReentrantLock(); private final Condition condition = stateLock.newCondition(); @@ -106,8 +106,8 @@ public class Server implements AutoCloseable, Runnable { idleTimeout, Locale.getDefault().toLanguageTag(), opts, Busy, cur, cur); registry.store(info); - } catch (Throwable t) { - LOGGER.error("Error initializing daemon: " + t, t); + } catch (Exception e) { + throw new RuntimeException("Could not initialize " + Server.class.getName(), e); } } diff --git a/daemon/src/main/provisio/maven-distro.xml b/daemon/src/main/provisio/maven-distro.xml index fb383ded..ace3e064 100644 --- a/daemon/src/main/provisio/maven-distro.xml +++ b/daemon/src/main/provisio/maven-distro.xml @@ -20,13 +20,46 @@ + excludes="lib/slf4j*,conf/logging/*,lib/maven-slf4j-provider*,bin/mvn*,lib/jansi-*.jar,lib/jansi-native/*"/> - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/daemon/src/test/java/org/jboss/fuse/mvnd/dist/DistroIT.java b/daemon/src/test/java/org/jboss/fuse/mvnd/dist/DistroIT.java new file mode 100644 index 00000000..f63bc6cd --- /dev/null +++ b/daemon/src/test/java/org/jboss/fuse/mvnd/dist/DistroIT.java @@ -0,0 +1,141 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.fuse.mvnd.dist; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class DistroIT { + + /** + * Asserts that we do not have the same libs in lib/ext and in lib or boot directories. + */ + @Test + void noDuplicateJars() { + final Path mavenHome = Paths.get(System.getProperty("mvnd.home")); + Set mavenLibs = streamJars(mavenHome, "lib", "boot").collect(Collectors.toCollection(TreeSet::new)); + Assertions.assertFalse(mavenLibs.isEmpty()); + final List mvndJars = streamJars(mavenHome, "lib/ext").collect(Collectors.toList()); + Assertions.assertFalse(mvndJars.isEmpty()); + + final List dups = mvndJars.stream() + .filter(avc -> mavenLibs.stream().anyMatch(mvnAvc -> mvnAvc.sameArtifactId(avc))) + .collect(Collectors.toList()); + + final String msg = mavenHome.resolve("lib/ext") + " contains duplicates available in " + mavenHome.resolve("lib") + + " or " + mavenHome.resolve("lib"); + Assertions.assertEquals(new ArrayList(), dups, msg); + } + + @Test + void avcOf() { + assertAvcOf("foo-bar-1.2.3.jar", "foo-bar", "1.2.3", null); + assertAvcOf("foo_bar-1.2.3-classifier.jar", "foo_bar", "1.2.3", "classifier"); + } + + void assertAvcOf(String jarName, String artifactId, String version, String classifier) { + Avc avc = Avc.of(jarName); + Assertions.assertEquals(artifactId, avc.artifactId, "artifactId in " + jarName); + Assertions.assertEquals(version, avc.version, "version in " + jarName); + Assertions.assertEquals(classifier, avc.classifier, "classifier in " + jarName); + } + + private static Stream streamJars(Path mavenHome, String... dirs) { + return Stream.of(dirs) + .map(mavenHome::resolve) + .flatMap((Path p) -> { + try { + return Files.list(p); + } catch (java.io.IOException e) { + throw new RuntimeException("Could not list " + p, e); + } + }) + .filter(p -> p.getFileName().toString().endsWith(".jar")) + .filter(Files::isRegularFile) + .map(Path::getFileName) + .map(Path::toString) + .map(Avc::of); + } + + static class Avc implements Comparable { + + private static final Pattern JAR_NAME_PATTERN = Pattern.compile("^(.*)(?:-([0-9]+(?:\\.[0-9]+)*))(?:-(.*))?.jar$"); + + public static Avc of(String jarName) { + final Matcher m = JAR_NAME_PATTERN.matcher(jarName); + if (m.find()) { + return new Avc(m.group(1), m.group(2), m.group(3), jarName); + } else { + throw new IllegalStateException("Jar name " + jarName + " does not match " + JAR_NAME_PATTERN.pattern()); + } + } + + private final String artifactId; + private final String version; + private final String classifier; + private final String jarName; + + public Avc(String artifactId, String version, String classifier, String jarName) { + this.artifactId = artifactId; + this.version = version; + this.classifier = classifier; + this.jarName = jarName; + } + + @Override + public String toString() { + return jarName; + } + + @Override + public int hashCode() { + return jarName.hashCode(); + } + + public boolean sameArtifactId(Avc other) { + return this.artifactId.equals(other.artifactId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Avc other = (Avc) obj; + return this.jarName.equals(other.jarName); + } + + @Override + public int compareTo(Avc other) { + return this.jarName.compareTo(other.jarName); + } + + } +}