Skip to content

Commit

Permalink
Added Unit Test logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Shweit committed Aug 29, 2024
1 parent 3ff2747 commit b4dfdb1
Show file tree
Hide file tree
Showing 14 changed files with 446 additions and 56 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,23 @@ jobs:
with:
name: checkstyle-reports
path: target/checkstyle-result.xml

unit-tests:
name: Unit Tests
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 21
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '21'

- name: Build with Maven
run: mvn clean install

- name: Run Unit Tests
run: mvn test
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ This project allows server administrators to automate tasks, gather
information, and manage the server more efficiently.

## Prerequisites
- **Java:** JDK 20
- **Java:** JDK 20 or higher is required to build and run the project.
- **Maven:** Make sure Maven is installed on your system.
You can download it from [here](https://maven.apache.org/download.cgi).
You can download it [here](https://maven.apache.org/download.cgi).
- **Minecraft Server:** Make sure you have a Paper or Spigot Minecraft server running on your machine.
- **Docker:** The Test Environment is set up using Docker.
Make sure you have Docker installed on your system.
You can download it [here](https://www.docker.com/products/docker-desktop).

## Installation
### Cloning the Repository
Expand Down
18 changes: 17 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>citizens-repo</id>
<url>https://maven.citizensnpcs.co/repo</url>
</repository>
</repositories>

<dependencies>
Expand Down Expand Up @@ -61,7 +65,6 @@
<groupId>eu.kennytv.maintenance</groupId>
<artifactId>maintenance-api</artifactId>
<version>4.2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
Expand Down Expand Up @@ -103,6 +106,19 @@
<artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
</dependency>
<dependency>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-main</artifactId>
<version>2.0.35-SNAPSHOT</version>
<scope>test</scope>
<type>jar</type>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void registerEndpoints() {
server.addRoute(NanoHTTPD.Method.POST, "/v1/server/exec", serverAPI::execCommand);
Logger.info("Registered POST /v1/server/exec");

server.addRoute(NanoHTTPD.Method.POST, "/v1/server/reboot", serverAPI::reload);
server.addRoute(NanoHTTPD.Method.POST, "/v1/server/reload", serverAPI::reload);
Logger.info("Registered POST /v1/server/reload");

server.addRoute(NanoHTTPD.Method.POST, "/v1/server/reboot", serverAPI::reboot);
Expand Down
106 changes: 66 additions & 40 deletions src/test/java/ApiTestHelper.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import org.json.JSONObject;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.junit.jupiter.Container;
import org.junit.jupiter.api.TestInstance;
import org.testcontainers.containers.DockerComposeContainer;

import java.io.File;
Expand All @@ -11,41 +12,45 @@
import java.util.logging.Logger;

import org.apache.commons.io.FileUtils;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
public class ApiTestHelper {
public static final String BASE_URL = "http://localhost:7001";
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class ApiTestHelper {

@Container
public static DockerComposeContainer<?> compose =
new DockerComposeContainer<>(new File("src/test/resources/docker-compose.yml"))
.withExposedService("mc_1", 25565);
protected static final DockerComposeContainer<?> compose = SharedDockerComposeContainer.getInstance();
public static final String BASE_URL = "http://localhost:7001";

public static String getBaseUrl() {
return BASE_URL;
}

public static String readResponse(HttpURLConnection conn) throws IOException {
try (Scanner scanner = new Scanner(conn.getInputStream())) {
scanner.useDelimiter("\\A");
return scanner.hasNext() ? scanner.next() : "";
}
}

@BeforeAll
public static void setUp() {
public void setUp() {
buildPluginWithMaven();
compose.start();

// TODO: Add Check if the this is the first time the server is being started
copyPluginToDockerContainer();
reloadMinecraftServer();
}

@AfterAll
public static void tearDown() {
compose.stop();
public void tearDown() {
// Reset the Minecraft server to its original state
try {
File pluginFile = new File("src/test/resources/server-data/server.properties");
File destDir_1 = new File("src/test/resources/minecraft-test-server/");
FileUtils.copyFileToDirectory(pluginFile, destDir_1);

File whitelistFile = new File("src/test/resources/server-data/whitelist.json");
File destDir_2 = new File("src/test/resources/minecraft-test-server/");
FileUtils.copyFileToDirectory(whitelistFile, destDir_2);

} catch (IOException e) {
throw new RuntimeException("Failed to copy server properties to Docker container directory", e);
}

try {
org.testcontainers.containers.Container.ExecResult result = compose.getContainerByServiceName("mc_1").get().execInContainer("whitelist", "on");
} catch (Exception e) {
throw new RuntimeException("Failed to execute Docker command to enable Whitelist", e);
}
}

private static void buildPluginWithMaven() {
Expand All @@ -65,27 +70,48 @@ private static void buildPluginWithMaven() {

private static void copyPluginToDockerContainer() {
try {
// Plugin file
File pluginFile = new File("target/MinecraftServerAPI-1.0.jar");

File destDir_1 = new File("src/test/resources/minecraft-test-server/plugins");

FileUtils.copyFileToDirectory(pluginFile, destDir_1);


File configFile = new File("src/test/resources/config.yml");

// Config file
File configFile = new File("src/test/resources/server-data/config.yml");
File destDir_2 = new File("src/test/resources/minecraft-test-server/plugins/MinecraftServerAPI");

FileUtils.copyFileToDirectory(configFile, destDir_2);

// Citizens plugin
File citizensFile = new File("src/test/resources/server-data/plugins/Citizens-2.0.35-b3535.jar");
File destDir_3 = new File("src/test/resources/minecraft-test-server/plugins");
FileUtils.copyFileToDirectory(citizensFile, destDir_3);

// Maintenance plugin
File maintenanceFile = new File("src/test/resources/server-data/plugins/Maintenance-4.2.1.jar");
File destDir_4 = new File("src/test/resources/minecraft-test-server/plugins");
FileUtils.copyFileToDirectory(maintenanceFile, destDir_4);

// server.properties file
File serverPropertiesFile = new File("src/test/resources/server-data/server.properties");
File destDir_5 = new File("src/test/resources/minecraft-test-server/");
FileUtils.copyFileToDirectory(serverPropertiesFile, destDir_5);

//whitelist.json file
File whitelistFile = new File("src/test/resources/server-data/whitelist.json");
File destDir_6 = new File("src/test/resources/minecraft-test-server/");
FileUtils.copyFileToDirectory(whitelistFile, destDir_6);
} catch (IOException e) {
throw new RuntimeException("Failed to copy plugin to Docker container directory", e);
}

try {
org.testcontainers.containers.Container.ExecResult result = compose.getContainerByServiceName("mc_1").get().execInContainer("whitelist", "on");
} catch (Exception e) {
throw new RuntimeException("Failed to execute Docker command to enable Whitelist", e);
}
}

private static void reloadMinecraftServer() {
try {
// Logger.getLogger("org.testcontainers").log(Level.INFO, "Reloading Minecraft server");
org.testcontainers.containers.Container.ExecResult result = compose.getContainerByServiceName("mc_1").get().execInContainer("rcon-cli", "reload confirm");
int exitCode = result.getExitCode();
if (exitCode != 0) {
Expand Down Expand Up @@ -113,8 +139,6 @@ private static void reloadMinecraftServer() {
conn.connect();

int responseCode = conn.getResponseCode();
logger.info("Response code: " + responseCode);

if (responseCode == 200) {
isReady = true;
}
Expand All @@ -138,16 +162,18 @@ private static void reloadMinecraftServer() {
}
}

private static void copyConfigToDockerContainer() {
try {
File configFile = new File("src/test/resources/config.yml");

File destDir = new File("src/test/resources/minecraft-test-server/plugins/MinecraftServerAPI");

FileUtils.copyFileToDirectory(configFile, destDir);
public static HttpURLConnection sendRequest(String endpoint, String method) throws IOException {
URL url = new URL(getBaseUrl() + endpoint);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setRequestProperty("Authorization", "TestKey");
return conn;
}

} catch (IOException e) {
throw new RuntimeException("Failed to copy config to Docker container directory", e);
public static String readResponse(HttpURLConnection conn) throws IOException {
try (Scanner scanner = new Scanner(conn.getInputStream())) {
scanner.useDelimiter("\\A");
return scanner.hasNext() ? scanner.next() : "";
}
}
}
32 changes: 20 additions & 12 deletions src/test/java/PlayerAPITest.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import org.json.JSONObject;
import org.junit.Ignore;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import static org.junit.jupiter.api.Assertions.*;

public class PlayerAPITest extends ApiTestHelper {

@Test
public void testPingEndpoint() throws IOException {
String urlString = ApiTestHelper.getBaseUrl() + "/v1/ping";
URL url = new URL(urlString);
public void testPlayersEndpoint() throws IOException {
HttpURLConnection conn = sendRequest("/v1/players", "GET");
String response = ApiTestHelper.readResponse(conn);

assertEquals(200, conn.getResponseCode());
assertNotNull(response);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
JSONObject jsonResponse = new JSONObject(response);

int responseCode = conn.getResponseCode();
assertEquals(200, responseCode, "Expected response code to be 200");
assertTrue(jsonResponse.has("onlinePlayers"));
assertEquals(0, jsonResponse.getJSONArray("onlinePlayers").length());
}

String response = readResponse(conn);
assertNotNull(response, "Response should not be null");
assertEquals("pong", response.trim(), "Expected response to be 'pong'");
@Test
@Disabled
public void testPlayerEndpoint() throws IOException {
HttpURLConnection conn = sendRequest("/v1/player/Shweit", "GET");
assertEquals(404, conn.getResponseCode());
}
}
Loading

0 comments on commit b4dfdb1

Please sign in to comment.