From eb4d23ec4559f8add0a95d831f1a35d044991076 Mon Sep 17 00:00:00 2001 From: J3fftw <44972470+J3fftw1@users.noreply.github.com> Date: Mon, 15 Jan 2024 14:40:43 +0100 Subject: [PATCH] Update MockBukkit to 1.20.4 along with existing tests (#4086) Co-authored-by: J3fftw1 <44972470+J3fftw1@users.noreply.github.com> Co-authored-by: Daniel Walsh Co-authored-by: Alessio Colombo <37039432+Sfiguz7@users.noreply.github.com> --- .gitignore | 2 +- docs/sop/update.md | 71 +++++++++++++++++++ pom.xml | 42 ++++++----- .../slimefun4/implementation/Slimefun.java | 36 +++------- .../slimefun4/utils/FileUtils.java | 24 +++++++ .../events/TestSlimefunBlockPlaceEvent.java | 10 +-- .../api/events/TestTalismanActivateEvent.java | 4 +- .../slimefun4/api/gps/TestWaypoints.java | 2 +- .../listeners/TestCargoNodeListener.java | 2 +- .../listeners/TestSlimefunGuideListener.java | 2 +- .../storage/backend/TestLegacyBackend.java | 4 +- .../slimefun4/test/TestUtilities.java | 2 +- 12 files changed, 144 insertions(+), 57 deletions(-) create mode 100644 docs/sop/update.md create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/utils/FileUtils.java diff --git a/.gitignore b/.gitignore index f025c1e19..e6f9d7a43 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ /.settings/ /.idea/ /.vscode/ -/data-store/ +/data-storage/ dependency-reduced-pom.xml diff --git a/docs/sop/update.md b/docs/sop/update.md new file mode 100644 index 000000000..88470853b --- /dev/null +++ b/docs/sop/update.md @@ -0,0 +1,71 @@ +# Update Procedure + +Date: 2024-01-15 +Last updated: 2024-01-15 + +## Goal + +This SOP will go over updating Slimefun to the newest Minecraft version, most of this will only apply to major versions, but we have also seen minor versions break things. So please read through the whole SOP and make sure you do everything applicable. + +## Updating + +### Updating Bukkit/Spigot + +The first step is just updating Spigot in the pom.xml. This should only be done in 2 cases: +* There's a new major version (well, MC major - 1.19 -> 1.20 is a major) +* There was a change within MC or Bukkit/Spigot that broke the API + +To update the Spigot version, you will need to go to the `pom.xml` and find the `spigot.version` property, this will be within the `properties` property. Simply make this the MC version (e.g. `1.20` or in the case of minor `1.20.4`). + +Once updated, **make sure to run a build** to check for compilation failures with `mvn clean package -DskipTests=true`. We will go over the tests next. + +### Updating tests + +The next step is making sure our tests are still working correctly as is. This can be done by running `mvn test` and verifying that all tests pass correctly without any failures or errors. + +If there are any failures you will need to investigate these, it's best to run them one at a time, so you don't have the potential for cross-test contamination. If you find any issues with the tests, please fix them and make sure to add a comment to the PR explaining why the test was changed. + +If you need any help fixing tests feel free to join the [Discord](https://discord.gg/slimefun). + +Once all the tests are passed, check to see if there's a new version of [MockBukkit](https://github.com/MockBukkit/MockBukkit), this is the framework handling the Bukkit side of our tests. There very well may not be a new version, they usually lag updates a bit. If not, that's perfectly ok, just make sure to note it on the PR. + +### Testing in game + +The final and most important step is testing this in game. While I'd love for our tests to be perfect, they are not (especially if MockBukkit hasn't had an update yet). We need to ensure that everything is working in-game before we can ship a new version release. + +To do this, you will need to build the plugin with `mvn clean package` and then copy the jar from `target/` to your server's `plugins/` folder. Once you've done this, start the server. You will want to test various things but the things we always want covered are: +* Commands, verify running a few commands work + * `/sf versions` + * `/sf cheat` + * `/sf search` +* Items, verify you can use a few items (you can grab these from `/sf cheat`) + * Wind staff + * One of the talismans + * One of the backpacks +* Blocks, verify you can place, break and ensure they all work + * Ancient altar + * Ore washer + * Coal generator + +It is important to verify heads are still working (part of the energy network and the coal generator). If head skins are not loading, consider it as a bug: try figuring out what the issue is, and ask in the [Discord](https://discord.gg/slimefun) if you are not sure what the cause may be. + +Also make sure to verify that there are no errors in the console, any errors here should be investigated and fixed. + +If you find any issues, please fix them and make sure to add a comment to the PR explaining why the fix was needed. + +> **Note** +> An issue here usually means that we need to update Dough. If this is the case, please open a PR to Dough and then update the Dough version in the `pom.xml` to the new version. Once you've done this, make sure to run a build to verify everything is working correctly. + +### Final steps + +Once you've verified everything is working, you can go ahead and open the PR. We will get to this as soon as we can :) + +While the PR is open, make sure to verify the E2E tests are passing, and you should also verify the output of these. If the E2E tests look good then finally we will update these. + +#### Updating E2E tests + +**This is only needed in a major version** + +In the `e2e-testing.yml` file you will need to update the matrix strategy, please add the latest version of the old major (e.g. if 1.21 came out, add 1.20.x where x is the latest released version). If MC is requiring a new Java version make sure that is updated too in the `latest` version. + +Once updated, push and re-verify that the E2E tests are still passing. diff --git a/pom.xml b/pom.xml index 65fd79d94..46b047825 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ 16 - 1.20 + 1.20.4 https://hub.spigotmc.org/javadocs/spigot/ @@ -334,13 +334,7 @@ - - - org.spigotmc - spigot-api - ${spigot.version}-R0.1-SNAPSHOT - provided - + @@ -355,7 +349,7 @@ com.github.baked-libs.dough dough-api - c4231a4d1a + a2364de77c compile @@ -398,10 +392,11 @@ 2.0.9 test + com.github.seeseemelk - MockBukkit-v1.18 - 2.0.0 + MockBukkit-v1.20 + 3.65.0 test @@ -513,12 +508,6 @@ - - com.mojang - authlib - 1.5.25 - provided - commons-lang @@ -526,5 +515,24 @@ 2.6 compile + + org.spigotmc + spigot-api + ${spigot.version}-R0.1-SNAPSHOT + provided + + + com.mojang + authlib + 6.0.52 + provided + + + + * + * + + + diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java index 8667eed68..28233ea74 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java @@ -13,7 +13,6 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; import io.github.thebusybiscuit.slimefun4.storage.Storage; import io.github.thebusybiscuit.slimefun4.storage.backend.legacy.LegacyStorage; @@ -29,7 +28,6 @@ import org.bukkit.inventory.Recipe; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.scheduler.BukkitTask; import io.github.bakedlibs.dough.config.Config; @@ -120,17 +118,16 @@ import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesS import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RadiationTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RainbowArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SlimefunArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SolarHelmetTask; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.integrations.IntegrationsManager; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; import io.papermc.lib.PaperLib; - import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.MenuListener; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; @@ -141,7 +138,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; * * @author TheBusyBiscuit */ -public final class Slimefun extends JavaPlugin implements SlimefunAddon { +public class Slimefun extends JavaPlugin implements SlimefunAddon { /** * This is the Java version we recommend server owners to use. @@ -209,30 +206,17 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon { private final SlimefunBowListener bowListener = new SlimefunBowListener(); /** - * Our default constructor for {@link Slimefun}. + * This constructor is invoked by Bukkit and within unit tests. + * Therefore we need to figure out if we're within unit tests or not. */ public Slimefun() { super(); - } - /** - * This constructor is invoked in Unit Test environments only. - * - * @param loader - * Our {@link JavaPluginLoader} - * @param description - * A {@link PluginDescriptionFile} - * @param dataFolder - * The data folder - * @param file - * A {@link File} for this {@link Plugin} - */ - @ParametersAreNonnullByDefault - public Slimefun(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { - super(loader, description, dataFolder, file); - - // This is only invoked during a Unit Test - minecraftVersion = MinecraftVersion.UNIT_TEST; + // Check that we got loaded by MockBukkit rather than Bukkit's loader + // TODO: This is very much a hack and we can hopefully move to a more native way in the future + if (getClassLoader().getClass().getPackageName().startsWith("be.seeseemelk.mockbukkit")) { + minecraftVersion = MinecraftVersion.UNIT_TEST; + } } /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/FileUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/FileUtils.java new file mode 100644 index 000000000..f8441dc75 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/FileUtils.java @@ -0,0 +1,24 @@ +package io.github.thebusybiscuit.slimefun4.utils; + +import java.io.File; + +public class FileUtils { + + public static boolean deleteDirectory(File folder) { + if (folder.isDirectory()) { + File[] files = folder.listFiles(); + + if (files != null) { + for (File file : files) { + // Recursive call to delete files and subfolders + if (!deleteDirectory(file)) { + return false; + } + } + } + } + + // Delete the folder itself + return folder.delete(); + } +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java index f6d8d2868..c33db5718 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java @@ -65,7 +65,7 @@ public class TestSlimefunBlockPlaceEvent { int x = TestUtilities.randomInt(); int z = TestUtilities.randomInt(); Block block = new BlockMock(Material.GREEN_TERRACOTTA, new Location(world, x, 0, z)); - Block blockAgainst = new BlockMock(Material.GRASS, new Location(world, x, 1, z)); + Block blockAgainst = new BlockMock(Material.GRASS_BLOCK, new Location(world, x, 1, z)); Slimefun.getRegistry().getWorlds().put("my_world", new BlockStorage(world)); @@ -88,7 +88,7 @@ public class TestSlimefunBlockPlaceEvent { int x = TestUtilities.randomInt(); int z = TestUtilities.randomInt(); Block block = new BlockMock(Material.GREEN_TERRACOTTA, new Location(world, x, 0, z)); - Block blockAgainst = new BlockMock(Material.GRASS, new Location(world, x, 1, z)); + Block blockAgainst = new BlockMock(Material.GRASS_BLOCK, new Location(world, x, 1, z)); Slimefun.getRegistry().getWorlds().put("my_world", new BlockStorage(world)); @@ -125,7 +125,7 @@ public class TestSlimefunBlockPlaceEvent { int x = TestUtilities.randomInt(); int z = TestUtilities.randomInt(); Block block = new BlockMock(Material.GREEN_TERRACOTTA, new Location(world, x, 0, z)); - Block blockAgainst = new BlockMock(Material.GRASS, new Location(world, x, 1, z)); + Block blockAgainst = new BlockMock(Material.GRASS_BLOCK, new Location(world, x, 1, z)); Slimefun.getRegistry().getWorlds().put("my_world", new BlockStorage(world)); @@ -153,7 +153,7 @@ public class TestSlimefunBlockPlaceEvent { int x = TestUtilities.randomInt(); int z = TestUtilities.randomInt(); Block firstBlock = new BlockMock(Material.GREEN_TERRACOTTA, new Location(world, x, 0, z)); - Block firstBlockAgainst = new BlockMock(Material.GRASS, new Location(world, x, 1, z)); + Block firstBlockAgainst = new BlockMock(Material.GRASS_BLOCK, new Location(world, x, 1, z)); Slimefun.getRegistry().getWorlds().put("my_world", new BlockStorage(world)); @@ -176,7 +176,7 @@ public class TestSlimefunBlockPlaceEvent { // Place second block in the same location Block secondBlock = new BlockMock(Material.GREEN_TERRACOTTA, new Location(world, x, 0, z)); - Block secondBlockAgainst = new BlockMock(Material.GRASS, new Location(world, x, 1, z)); + Block secondBlockAgainst = new BlockMock(Material.GRASS_BLOCK, new Location(world, x, 1, z)); BlockPlaceEvent secondBlockPlaceEvent = new BlockPlaceEvent( secondBlock, secondBlock.getState(), secondBlockAgainst, itemStack, player, true, EquipmentSlot.HAND diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java index 83b49fa23..94b1947cf 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java @@ -55,9 +55,9 @@ class TestTalismanActivateEvent { ItemStack breakableItem = new ItemStack(Material.IRON_PICKAXE); if (inEnderChest) { - player.getEnderChest().addItem(talismanItem); + player.getEnderChest().setItem(9, talismanItem); } else { - player.getInventory().addItem(talismanItem); + player.getInventory().setItem(9, talismanItem); } player.getInventory().setItemInMainHand(breakableItem); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java index a0de64b14..3b769c44a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java @@ -3,7 +3,6 @@ package io.github.thebusybiscuit.slimefun4.api.gps; import java.io.File; import java.io.IOException; -import org.apache.commons.io.FileUtils; import org.bukkit.entity.Player; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; @@ -15,6 +14,7 @@ import io.github.thebusybiscuit.slimefun4.api.events.WaypointCreateEvent; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; +import io.github.thebusybiscuit.slimefun4.utils.FileUtils; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java index 1288b34d7..0951dce2c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java @@ -84,7 +84,7 @@ class TestCargoNodeListener { Location l = new Location(player.getWorld(), 300, 25, 1200); Block b = l.getBlock(); - b.setType(Material.GRASS); + b.setType(Material.GRASS_BLOCK); ItemGroup itemGroup = TestUtilities.getItemGroup(plugin, "cargo_test"); SlimefunItemStack item = new SlimefunItemStack("MOCK_CARGO_NODE_2", new CustomItemStack(Material.PLAYER_HEAD, "&4Cargo node!")); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java index 5c62c4090..6b58f849b 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java @@ -45,7 +45,7 @@ class TestSlimefunGuideListener { PlayerMock player = new PlayerMock(server, "CanIHazGuide"); if (hasPlayedBefore) { - player.setLastPlayed(System.currentTimeMillis()); + server.getPlayerList().setLastSeen(player.getUniqueId(), System.currentTimeMillis()); } PlayerJoinEvent event = new PlayerJoinEvent(player, "CanIHazGuide has joined and wants sum guide"); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java index 185965999..c8e1916f5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java @@ -5,8 +5,8 @@ import java.io.IOException; import java.nio.file.Files; import java.util.UUID; -import org.apache.commons.io.FileUtils; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; @@ -30,7 +30,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.storage.backend.legacy.LegacyStorage; import io.github.thebusybiscuit.slimefun4.storage.data.PlayerData; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import net.md_5.bungee.api.ChatColor; +import io.github.thebusybiscuit.slimefun4.utils.FileUtils; class TestLegacyBackend { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java b/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java index d5f5b134c..edd6a458a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java @@ -110,7 +110,7 @@ public final class TestUtilities { int x = TestUtilities.randomInt(); int z = TestUtilities.randomInt(); Block block = new BlockMock(item.getType(), new Location(world, x, 0, z)); - Block blockAgainst = new BlockMock(Material.GRASS, new Location(world, x, 1, z)); + Block blockAgainst = new BlockMock(Material.GRASS_BLOCK, new Location(world, x, 1, z)); BlockPlaceEvent blockPlaceEvent = new BlockPlaceEvent( block, block.getState(), blockAgainst, item, player, true, EquipmentSlot.HAND