From 182f308f7194132b3f9126d60e2a92a8c634f84e Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Sun, 5 Jun 2022 04:50:23 -0700 Subject: [PATCH] test: add NetworkMode setting to MTE (#5037) --- .../integrationenvironment/Engines.java | 11 +++--- .../TestingStateHeadlessSetup.java | 4 ++- .../jupiter/IntegrationEnvironment.java | 17 +++++++++ .../jupiter/MTEExtension.java | 35 +++++++++++++++++-- .../NetworkModeLocalServerTest.java | 32 +++++++++++++++++ .../NetworkModeNoneTest.java | 32 +++++++++++++++++ .../NetworkModeServerTest.java | 30 ++++++++++++++++ .../headless/mode/StateHeadlessSetup.java | 9 ++++- 8 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/IntegrationEnvironment.java create mode 100644 engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeLocalServerTest.java create mode 100644 engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeNoneTest.java create mode 100644 engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeServerTest.java diff --git a/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/Engines.java b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/Engines.java index 59b2641d7ef..c65627c2b52 100644 --- a/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/Engines.java +++ b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/Engines.java @@ -35,6 +35,7 @@ import org.terasology.engine.core.subsystem.openvr.OpenVRInput; import org.terasology.engine.integrationenvironment.jupiter.MTEExtension; import org.terasology.engine.network.JoinStatus; +import org.terasology.engine.network.NetworkMode; import org.terasology.engine.network.NetworkSystem; import org.terasology.engine.registry.CoreRegistry; import org.terasology.engine.rendering.opengl.ScreenGrabber; @@ -80,8 +81,10 @@ public class Engines { PathManager pathManager; PathManagerProvider.Cleaner pathManagerCleaner; TerasologyEngine host; + private final NetworkMode networkMode; - public Engines(Set dependencies, String worldGeneratorUri) { + public Engines(Set dependencies, String worldGeneratorUri, NetworkMode networkMode) { + this.networkMode = networkMode; this.dependencies.addAll(dependencies); if (worldGeneratorUri != null) { @@ -97,7 +100,7 @@ public Engines(Set dependencies, String worldGeneratorUri) { public void setup() { mockPathManager(); try { - host = createHost(); + host = createHost(networkMode); } catch (IOException e) { throw new UncheckedIOException(e); } @@ -256,11 +259,11 @@ protected void mockPathManager() { PathManagerProvider.setPathManager(pathManager); } - TerasologyEngine createHost() throws IOException { + TerasologyEngine createHost(NetworkMode networkMode) throws IOException { TerasologyEngine host = createHeadlessEngine(); host.getFromEngineContext(SystemConfig.class).writeSaveGamesEnabled.set(false); host.subscribeToStateChange(new HeadlessStateChangeListener(host)); - host.changeState(new TestingStateHeadlessSetup(dependencies, worldGeneratorUri)); + host.changeState(new TestingStateHeadlessSetup(dependencies, worldGeneratorUri, networkMode)); doneLoading = false; host.subscribeToStateChange(() -> { diff --git a/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/TestingStateHeadlessSetup.java b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/TestingStateHeadlessSetup.java index 0bd16b057ec..889a5fc53eb 100644 --- a/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/TestingStateHeadlessSetup.java +++ b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/TestingStateHeadlessSetup.java @@ -11,6 +11,7 @@ import org.terasology.engine.core.TerasologyEngine; import org.terasology.engine.core.subsystem.headless.mode.StateHeadlessSetup; import org.terasology.engine.game.GameManifest; +import org.terasology.engine.network.NetworkMode; import org.terasology.engine.world.time.WorldTime; import org.terasology.gestalt.naming.Name; @@ -33,7 +34,8 @@ public class TestingStateHeadlessSetup extends StateHeadlessSetup { strictModuleRequirements = true; } - public TestingStateHeadlessSetup(Collection dependencies, String worldGeneratorUri) { + public TestingStateHeadlessSetup(Collection dependencies, String worldGeneratorUri, NetworkMode networkMode) { + super(networkMode); this.dependencies = dependencies; this.worldGeneratorUri = new SimpleUri(worldGeneratorUri); checkArgument(this.worldGeneratorUri.isValid(), "Not a valid URI `%s`", worldGeneratorUri); diff --git a/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/IntegrationEnvironment.java b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/IntegrationEnvironment.java new file mode 100644 index 00000000000..cc1611a31f8 --- /dev/null +++ b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/IntegrationEnvironment.java @@ -0,0 +1,17 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +package org.terasology.engine.integrationenvironment.jupiter; + +import org.terasology.engine.network.NetworkMode; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface IntegrationEnvironment { + NetworkMode networkMode() default NetworkMode.LISTEN_SERVER; +} diff --git a/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/MTEExtension.java b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/MTEExtension.java index d9b1a6c2d5e..17b1f3e4a78 100644 --- a/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/MTEExtension.java +++ b/engine-tests/src/main/java/org/terasology/engine/integrationenvironment/jupiter/MTEExtension.java @@ -11,10 +11,13 @@ import org.junit.jupiter.api.extension.ParameterResolver; import org.junit.jupiter.api.extension.TestInstancePostProcessor; import org.opentest4j.MultipleFailuresError; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.terasology.engine.integrationenvironment.Engines; import org.terasology.engine.integrationenvironment.MainLoop; import org.terasology.engine.integrationenvironment.ModuleTestingHelper; import org.terasology.engine.integrationenvironment.Scopes; +import org.terasology.engine.network.NetworkMode; import org.terasology.engine.registry.In; import org.terasology.unittest.worlds.DummyWorldGenerator; @@ -25,6 +28,8 @@ import java.util.Set; import java.util.function.Function; +import static org.junit.platform.commons.support.AnnotationSupport.findAnnotation; + /** * Sets up a Terasology environment for use with your {@index JUnit} 5 test. *

@@ -80,6 +85,8 @@ */ public class MTEExtension implements ParameterResolver, TestInstancePostProcessor { + private static final Logger logger = LoggerFactory.getLogger(MTEExtension.class); + protected Function helperLifecycle = Scopes.PER_CLASS; protected Function> getTestClass = Scopes::getTopTestClass; @@ -149,6 +156,17 @@ public Set getDependencyNames(ExtensionContext context) { return dependencies != null ? Sets.newHashSet(dependencies.value()) : Collections.emptySet(); } + public NetworkMode getNetworkMode(ExtensionContext context) { + return getAnnotationWithDefault(context, IntegrationEnvironment::networkMode); + } + + private T getAnnotationWithDefault(ExtensionContext context, Function method) { + var ann = + findAnnotation(context.getRequiredTestClass(), IntegrationEnvironment.class) + .orElseGet(ToReadDefaultValuesFrom::getDefaults); + return method.apply(ann); + } + /** * Get the Engines for this test. *

@@ -165,7 +183,11 @@ public Set getDependencyNames(ExtensionContext context) { protected Engines getEngines(ExtensionContext context) { ExtensionContext.Store store = context.getStore(helperLifecycle.apply(context)); EnginesCleaner autoCleaner = store.getOrComputeIfAbsent( - EnginesCleaner.class, k -> new EnginesCleaner(getDependencyNames(context), getWorldGeneratorUri(context)), + EnginesCleaner.class, k -> new EnginesCleaner( + getDependencyNames(context), + getWorldGeneratorUri(context), + getNetworkMode(context) + ), EnginesCleaner.class); return autoCleaner.engines; } @@ -179,8 +201,8 @@ protected Engines getEngines(ExtensionContext context) { static class EnginesCleaner implements ExtensionContext.Store.CloseableResource { protected Engines engines; - EnginesCleaner(Set dependencyNames, String worldGeneratorUri) { - engines = new Engines(dependencyNames, worldGeneratorUri); + EnginesCleaner(Set dependencyNames, String worldGeneratorUri, NetworkMode networkMode) { + engines = new Engines(dependencyNames, worldGeneratorUri, networkMode); engines.setup(); } @@ -190,4 +212,11 @@ public void close() { engines = null; } } + + @IntegrationEnvironment + private static final class ToReadDefaultValuesFrom { + static IntegrationEnvironment getDefaults() { + return ToReadDefaultValuesFrom.class.getDeclaredAnnotation(IntegrationEnvironment.class); + } + } } diff --git a/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeLocalServerTest.java b/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeLocalServerTest.java new file mode 100644 index 00000000000..83119bb7dc0 --- /dev/null +++ b/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeLocalServerTest.java @@ -0,0 +1,32 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 +package org.terasology.engine.integrationenvironment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment; +import org.terasology.engine.integrationenvironment.jupiter.MTEExtension; +import org.terasology.engine.logic.players.LocalPlayer; +import org.terasology.engine.network.NetworkMode; +import org.terasology.engine.network.NetworkSystem; + +import static com.google.common.truth.Truth.assertThat; + +@Tag("MteTest") +@ExtendWith(MTEExtension.class) +@IntegrationEnvironment(networkMode = NetworkMode.DEDICATED_SERVER) +public class NetworkModeLocalServerTest { + @Test + void testNetworkMode(NetworkSystem network) { + assertThat(network.getMode()).isEqualTo(NetworkMode.DEDICATED_SERVER); + } + + @Test + void testForLocalPlayer(NetworkSystem network, LocalPlayer player) { + assertThat(network.getPlayers()).hasSize(1); + var client = network.getPlayers().iterator().next(); + assertThat(client.isLocal()).isTrue(); + assertThat(player.isValid()).isTrue(); + } +} diff --git a/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeNoneTest.java b/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeNoneTest.java new file mode 100644 index 00000000000..784935e07bc --- /dev/null +++ b/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeNoneTest.java @@ -0,0 +1,32 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 +package org.terasology.engine.integrationenvironment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment; +import org.terasology.engine.integrationenvironment.jupiter.MTEExtension; +import org.terasology.engine.logic.players.LocalPlayer; +import org.terasology.engine.network.NetworkMode; +import org.terasology.engine.network.NetworkSystem; + +import static com.google.common.truth.Truth.assertThat; + +@Tag("MteTest") +@ExtendWith(MTEExtension.class) +@IntegrationEnvironment(networkMode = NetworkMode.NONE) +public class NetworkModeNoneTest { + @Test + void testNetworkMode(NetworkSystem network) { + assertThat(network.getMode()).isEqualTo(NetworkMode.NONE); + } + + @Test + void testForLocalPlayer(NetworkSystem network, LocalPlayer player) { + assertThat(network.getPlayers()).hasSize(1); + var client = network.getPlayers().iterator().next(); + assertThat(client.isLocal()).isTrue(); + assertThat(player.isValid()).isTrue(); + } +} diff --git a/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeServerTest.java b/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeServerTest.java new file mode 100644 index 00000000000..0e54205b172 --- /dev/null +++ b/engine-tests/src/test/java/org/terasology/engine/integrationenvironment/NetworkModeServerTest.java @@ -0,0 +1,30 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 +package org.terasology.engine.integrationenvironment; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment; +import org.terasology.engine.integrationenvironment.jupiter.MTEExtension; +import org.terasology.engine.logic.players.LocalPlayer; +import org.terasology.engine.network.NetworkMode; +import org.terasology.engine.network.NetworkSystem; + +import static com.google.common.truth.Truth.assertThat; + +@Tag("MteTest") +@ExtendWith(MTEExtension.class) +@IntegrationEnvironment(networkMode = NetworkMode.LISTEN_SERVER) +public class NetworkModeServerTest { + @Test + void testNetworkMode(NetworkSystem network) { + assertThat(network.getMode()).isEqualTo(NetworkMode.LISTEN_SERVER); + } + + @Test + void testServerHasNoPlayers(NetworkSystem network, LocalPlayer player) { + assertThat(network.getPlayers()).isEmpty(); + assertThat(player.isValid()).isFalse(); + } +} diff --git a/engine/src/main/java/org/terasology/engine/core/subsystem/headless/mode/StateHeadlessSetup.java b/engine/src/main/java/org/terasology/engine/core/subsystem/headless/mode/StateHeadlessSetup.java index 87bfc5ee37f..050278b74c4 100644 --- a/engine/src/main/java/org/terasology/engine/core/subsystem/headless/mode/StateHeadlessSetup.java +++ b/engine/src/main/java/org/terasology/engine/core/subsystem/headless/mode/StateHeadlessSetup.java @@ -35,7 +35,14 @@ public class StateHeadlessSetup extends AbstractState { protected boolean strictModuleRequirements; + private final NetworkMode networkMode; + public StateHeadlessSetup() { + this(NetworkMode.LISTEN_SERVER); + } + + public StateHeadlessSetup(NetworkMode networkMode) { + this.networkMode = networkMode; } @Override @@ -58,7 +65,7 @@ public void init(GameEngine gameEngine) { config.getUniverseConfig().setSpawnWorldTitle(worldInfo.getTitle()); config.getUniverseConfig().setUniverseSeed(gameManifest.getSeed()); - gameEngine.changeState(new StateLoading(gameManifest, NetworkMode.LISTEN_SERVER)); + gameEngine.changeState(new StateLoading(gameManifest, networkMode)); } public GameManifest createGameManifest() {