package com.htopweb.system; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; class SystemMetricsServiceTest { @TempDir Path tempDir; private Path hostProc; private Path hostRoot; @BeforeEach void setUp() throws IOException { hostRoot = tempDir.resolve("host-root"); hostProc = hostRoot.resolve("proc"); Files.createDirectories(hostProc); } @Test void readHostCpuTicks_parsesAggregateLine() throws IOException { // "cpu user nice system idle iowait irq softirq steal guest guest_nice" String stat = "cpu 1000 200 300 5000 100 10 20 30 0 0\n"; stat += "cpu0 500 100 150 2500 50 5 10 15 0 0\n"; Files.writeString(hostProc.resolve("stat"), stat); // Verify the parsing logic with sample data assertDoesNotThrow(() -> { String[] fields = "cpu 1000 200 300 5000 100 10 20 30 0 0".trim().split("\\s+"); long total = 0; for (int i = 1; i < fields.length; i++) { total += Long.parseLong(fields[i]); } long idle = Long.parseLong(fields[4]); // 5000 if (fields.length > 5) { idle += Long.parseLong(fields[5]); // +100 iowait } // 1000+200+300+5000+100+10+20+30+0+0 = 6660 assertEquals(6660, total); // 5000 + 100 = 5100 assertEquals(5100, idle); }); } @Test void readHostMemory_parsesMeminfo() throws IOException { String meminfo = "MemTotal: 16384000 kB\n" + "MemFree: 4096000 kB\n" + "MemAvailable: 8192000 kB\n" + "Buffers: 512000 kB\n" + "Cached: 2048000 kB\n"; Files.writeString(hostProc.resolve("meminfo"), meminfo); assertDoesNotThrow(() -> { Map values = new java.util.HashMap<>(); for (String line : Files.readAllLines(hostProc.resolve("meminfo"))) { int separator = line.indexOf(':'); if (separator < 0) continue; String key = line.substring(0, separator).trim(); if (!key.equals("MemTotal") && !key.equals("MemAvailable")) continue; String[] parts = line.substring(separator + 1).trim().split("\\s+"); if (parts.length > 0) { values.put(key, Long.parseLong(parts[0]) * 1024L); } } assertEquals(16384000L * 1024, values.get("MemTotal")); assertEquals(8192000L * 1024, values.get("MemAvailable")); }); } @Test void readHostMemory_returnsEmptyOnMissingFile() { Map values = new java.util.HashMap<>(); Path missingFile = hostProc.resolve("nonexistent"); assertFalse(Files.isRegularFile(missingFile)); // Empty map is returned when file doesn't exist assertTrue(values.isEmpty()); } @Test void getLogicalProcessorCount_parsesCpuLines() throws IOException { String stat = "cpu 1000 200 300 5000 100 10 20 30 0 0\n" + "cpu0 500 100 150 2500 50 5 10 15 0 0\n" + "cpu1 500 100 150 2500 50 5 10 15 0 0\n" + "cpu2 500 100 150 2500 50 5 10 15 0 0\n" + "cpu3 500 100 150 2500 50 5 10 15 0 0\n"; Files.writeString(hostProc.resolve("stat"), stat); int count = 0; for (String line : Files.readAllLines(hostProc.resolve("stat"))) { if (line.matches("^cpu\\d+\\s+.*")) { count++; } } assertEquals(4, count); } @Test void readHostOsRelease_parsesKeyValuePairs() throws IOException { Path etcDir = hostRoot.resolve("etc"); Files.createDirectories(etcDir); String osRelease = "NAME=\"Ubuntu\"\n" + "VERSION=\"22.04.3 LTS (Jammy Jellyfish)\"\n" + "ID=ubuntu\n" + "VERSION_ID=\"22.04\"\n"; Files.writeString(etcDir.resolve("os-release"), osRelease); assertDoesNotThrow(() -> { Map values = new java.util.HashMap<>(); for (String line : Files.readAllLines(etcDir.resolve("os-release"))) { int separator = line.indexOf('='); if (separator <= 0 || line.startsWith("#")) continue; String key = line.substring(0, separator).trim(); String value = line.substring(separator + 1).trim(); if (value.length() >= 2 && ((value.startsWith("\"") && value.endsWith("\"")) || (value.startsWith("'") && value.endsWith("'")))) { value = value.substring(1, value.length() - 1); } values.put(key, value); } assertEquals("Ubuntu", values.get("NAME")); assertEquals("22.04.3 LTS (Jammy Jellyfish)", values.get("VERSION")); assertEquals("22.04", values.get("VERSION_ID")); }); } @Test void readHostHostname_returnsHostname() throws IOException { Path etcDir = hostRoot.resolve("etc"); Files.createDirectories(etcDir); Files.writeString(etcDir.resolve("hostname"), "myserver\n"); String hostname = Files.readString(etcDir.resolve("hostname")).trim(); assertEquals("myserver", hostname); } }