package com.aluer.service; import com.aluer.ai.DeepSeekClient; import com.aluer.alert.EmailAlertService; import com.aluer.config.ServerGuardConfig; import com.aluer.monitor.*; import com.aluer.model.AlertEvent; import com.aluer.model.AlertType; import com.aluer.model.MetricsData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; @Service public class TestService { private static final Logger logger = LoggerFactory.getLogger(TestService.class); private final ServerGuardConfig config; private final RconClient rconClient; private final EmailAlertService emailAlertService; private final DeepSeekClient deepSeekClient; private final ProcessMonitor processMonitor; private final ResourceMonitor resourceMonitor; private final ConnectionMonitor connectionMonitor; private final LogMonitor logMonitor; public TestService( ServerGuardConfig config, RconClient rconClient, EmailAlertService emailAlertService, DeepSeekClient deepSeekClient, ProcessMonitor processMonitor, ResourceMonitor resourceMonitor, ConnectionMonitor connectionMonitor, LogMonitor logMonitor) { this.config = config; this.rconClient = rconClient; this.emailAlertService = emailAlertService; this.deepSeekClient = deepSeekClient; this.processMonitor = processMonitor; this.resourceMonitor = resourceMonitor; this.connectionMonitor = connectionMonitor; this.logMonitor = logMonitor; } public Map runAllTests() { Map results = new HashMap<>(); logger.info("========================================"); logger.info(" Aluer System Test Suite "); logger.info("========================================"); results.put("config", testConfiguration()); results.put("rcon", testRconConnection()); results.put("process", testProcessMonitor()); results.put("resource", testResourceMonitor()); results.put("connection", testConnectionMonitor()); results.put("log", testLogMonitor()); results.put("email", testEmailService()); results.put("deepseek", testDeepSeekApi()); printTestSummary(results); return results; } public Map runQuickTests() { Map results = new HashMap<>(); results.put("config", testConfiguration()); results.put("rcon", testRconConnection()); results.put("email", testEmailService()); printTestSummary(results); return results; } public TestResult testConfiguration() { TestResult result = new TestResult("Configuration"); try { if (config.getMinecraft() == null) { result.fail("Minecraft config is null"); return result; } if (config.getAi() == null) { result.fail("AI config is null"); return result; } if (config.getAlert() == null) { result.fail("Alert config is null"); return result; } result.pass(); result.addDetail("Service: " + config.getMinecraft().getServiceName()); result.addDetail("AI Enabled: " + config.getAi().isEnabled()); result.addDetail("Email Enabled: " + config.getAlert().isEnabled()); } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testRconConnection() { TestResult result = new TestResult("RCON Connection"); try { if (!config.getMinecraft().getRcon().isEnabled()) { result.skip("RCON is disabled"); return result; } String password = config.getMinecraft().getRcon().getPassword(); if (password == null || password.isEmpty()) { result.fail("RCON password not configured"); return result; } boolean connected = rconClient.connect(); if (connected) { result.pass(); String tps = rconClient.getTps(); result.addDetail("TPS: " + tps); String players = rconClient.getOnlinePlayers(); result.addDetail("Players: " + players); rconClient.close(); } else { result.fail("Could not connect to RCON"); } } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testProcessMonitor() { TestResult result = new TestResult("Process Monitor"); try { boolean running = processMonitor.isProcessRunning(); if (running) { result.pass(); result.addDetail("Minecraft process is running"); } else { result.fail("Minecraft process is not running"); } } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testResourceMonitor() { TestResult result = new TestResult("Resource Monitor"); try { MetricsData data = resourceMonitor.collectMetrics(); result.addDetail(String.format("TPS: %.1f", data.getTps())); result.addDetail(String.format("CPU: %.1f%%", data.getCpuUsage())); result.addDetail(String.format("Memory: %.1f%%", data.getMemoryUsage())); result.addDetail("Players: " + data.getOnlinePlayers()); result.addDetail("Connections: " + data.getConnections()); if (data.getTps() > 0 || data.getCpuUsage() >= 0) { result.pass(); } else { result.fail("Could not collect metrics"); } } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testConnectionMonitor() { TestResult result = new TestResult("Connection Monitor"); try { var connections = connectionMonitor.getActiveConnections(); result.addDetail("Active connections: " + connections.size()); if (connections.isEmpty()) { result.addDetail("No active connections (server may be offline)"); } else { connections.forEach((ip, count) -> result.addDetail(" " + ip + ": " + count)); } result.pass(); } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testLogMonitor() { TestResult result = new TestResult("Log Monitor"); try { String logPath = config.getMonitor().getLogPath(); result.addDetail("Log path: " + logPath); var newLines = logMonitor.watchLogs(); result.addDetail("New log lines: " + newLines.size()); result.pass(); } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testEmailService() { TestResult result = new TestResult("Email Service"); try { if (!config.getAlert().isEnabled()) { result.skip("Email alerts are disabled"); return result; } var emailConfig = config.getAlert().getEmail(); if (emailConfig.getTo() == null || emailConfig.getTo().isEmpty()) { result.fail("No email recipients configured"); return result; } result.addDetail("SMTP: " + emailConfig.getSmtpHost() + ":" + emailConfig.getSmtpPort()); result.addDetail("To: " + String.join(", ", emailConfig.getTo())); result.pass(); } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testDeepSeekApi() { TestResult result = new TestResult("DeepSeek API"); try { if (!config.getAi().getDeepseek().isEnabled()) { result.skip("DeepSeek is disabled"); return result; } if (!deepSeekClient.isEnabled()) { result.fail("DeepSeek API key not configured"); return result; } result.addDetail("Model: " + config.getAi().getDeepseek().getModel()); result.addDetail("Base URL: " + config.getAi().getDeepseek().getBaseUrl()); AlertEvent testAlert = new AlertEvent(AlertType.TPS_LOW, "Test alert - TPS dropped below threshold"); testAlert.setConfidence(0.85); CompletableFuture future = deepSeekClient.analyzeAlertAsync(testAlert); DeepSeekClient.AiAnalysisResult analysis = future.get(30, java.util.concurrent.TimeUnit.SECONDS); if (analysis != null) { result.pass(); result.addDetail("Severity: " + analysis.getSeverity()); result.addDetail("Root Cause: " + analysis.getRootCause()); } else { result.fail("No response from API"); } } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testAutoExecute() { TestResult result = new TestResult("Auto Execute"); try { var autoConfig = config.getAi().getDeepseek().getAutoExecute(); result.addDetail("Enabled: " + autoConfig.isEnabled()); result.addDetail("Ban IP: " + autoConfig.isBanIp()); result.addDetail("Kick Player: " + autoConfig.isKickPlayer()); result.addDetail("Clear Lag: " + autoConfig.isClearLag()); result.addDetail("Min Confidence: " + autoConfig.getMinConfidence() + "%"); if (autoConfig.isEnabled()) { result.pass(); } else { result.skip("Auto execute is disabled"); } } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult sendTestEmail() { TestResult result = new TestResult("Send Test Email"); try { if (!config.getAlert().isEnabled()) { result.skip("Email alerts are disabled"); return result; } emailAlertService.sendTestEmail(); result.pass(); result.addDetail("Test email sent"); } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult testRconCommand(String command) { TestResult result = new TestResult("RCON Command: " + command); try { if (!config.getMinecraft().getRcon().isEnabled()) { result.skip("RCON is disabled"); return result; } String output = rconClient.executeCommand(command); result.addDetail("Output: " + output); result.pass(); } catch (Exception e) { result.fail(e.getMessage()); } return result; } public TestResult simulateAttack() { TestResult result = new TestResult("Simulate Attack"); try { String fakeIp = "192.168.1." + (int)(Math.random() * 255); for (int i = 0; i < 10; i++) { connectionMonitor.detectConnectionFlood(); } result.pass(); result.addDetail("Simulated attack from: " + fakeIp); result.addDetail("Connection flood detection tested"); } catch (Exception e) { result.fail(e.getMessage()); } return result; } private void printTestSummary(Map results) { logger.info("========================================"); logger.info(" Test Results "); logger.info("========================================"); int passed = 0; int failed = 0; int skipped = 0; for (var entry : results.entrySet()) { TestResult r = entry.getValue(); String status = r.isPassed() ? "✓ PASS" : (r.isSkipped() ? "⊘ SKIP" : "✗ FAIL"); logger.info("{} - {}", status, r.getName()); if (r.isPassed()) passed++; else if (r.isSkipped()) skipped++; else failed++; for (String detail : r.getDetails()) { logger.info(" {}", detail); } if (!r.isPassed() && !r.isSkipped() && r.getError() != null) { logger.error(" Error: {}", r.getError()); } } logger.info("========================================"); logger.info("Passed: {} Failed: {} Skipped: {}", passed, failed, skipped); logger.info("========================================"); } public static class TestResult { private final String name; private boolean passed = false; private boolean skipped = false; private String error; private java.util.List details = new java.util.ArrayList<>(); public TestResult(String name) { this.name = name; } public TestResult pass() { this.passed = true; return this; } public TestResult fail(String error) { this.error = error; this.passed = false; return this; } public TestResult skip(String reason) { this.skipped = true; this.error = reason; return this; } public TestResult addDetail(String detail) { this.details.add(detail); return this; } public String getName() { return name; } public boolean isPassed() { return passed; } public boolean isSkipped() { return skipped; } public String getError() { return error; } public java.util.List getDetails() { return details; } } }