-
-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
112e715
commit 308c136
Showing
6 changed files
with
304 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package de.sldk.mc.metrics; | ||
|
||
import de.sldk.mc.utils.PathFileSize; | ||
import io.prometheus.client.Gauge; | ||
import java.util.logging.Logger; | ||
import org.bukkit.World; | ||
import org.bukkit.plugin.Plugin; | ||
|
||
public class WorldSize extends WorldMetric { | ||
|
||
private final Logger log; | ||
private static final Gauge WORLD_SIZE = Gauge.build() | ||
.name(prefix("world_size")) | ||
.help("World size in bytes") | ||
.labelNames("world") | ||
.create(); | ||
|
||
public WorldSize(Plugin plugin) { | ||
super(plugin, WORLD_SIZE); | ||
this.log = plugin.getLogger(); | ||
} | ||
|
||
@Override | ||
protected void clear() { | ||
WORLD_SIZE.clear(); | ||
} | ||
|
||
@Override | ||
public void collect(World world) { | ||
try { | ||
PathFileSize pathUtils = new PathFileSize(world.getWorldFolder().toPath()); | ||
long size = pathUtils.getSize(); | ||
String worldName = world.getName(); | ||
WORLD_SIZE.labels(worldName).set(size); | ||
} catch (Throwable t) { | ||
log.throwing(this.getClass().getSimpleName(), "collect", t); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package de.sldk.mc.utils; | ||
|
||
import java.io.*; | ||
import java.nio.file.*; | ||
import java.nio.file.attribute.BasicFileAttributes; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
|
||
public class PathFileSize { | ||
final private Path path; | ||
|
||
public PathFileSize(Path path) { | ||
if (path == null) { | ||
throw new IllegalArgumentException("Path must not be null!"); | ||
} | ||
this.path = path; | ||
} | ||
|
||
public long getSize() throws IOException { | ||
final AtomicLong size = new AtomicLong(0); | ||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() { | ||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { | ||
size.addAndGet(attrs.size()); | ||
return FileVisitResult.CONTINUE; | ||
} | ||
|
||
public FileVisitResult visitFileFailed(Path file, IOException exc) { | ||
return FileVisitResult.CONTINUE; | ||
} | ||
}); | ||
return size.get(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package de.sldk.mc.metrics; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
import io.prometheus.client.CollectorRegistry; | ||
import java.io.*; | ||
import java.nio.file.*; | ||
import java.util.Random; | ||
import net.bytebuddy.utility.RandomString; | ||
import org.bukkit.World; | ||
import org.bukkit.plugin.Plugin; | ||
import org.junit.jupiter.api.*; | ||
import org.junit.jupiter.api.io.TempDir; | ||
|
||
public class WorldSizeTest { | ||
|
||
private static final String METRIC_NAME = "mc_world_size"; | ||
private static final String[] METRIC_LABELS = { "world" }; | ||
|
||
private WorldSize worldSizeMetric; | ||
|
||
@TempDir | ||
private Path path; | ||
private File file; | ||
private World world; | ||
|
||
@BeforeEach | ||
public void beforeEach() { | ||
worldSizeMetric = new WorldSize(mock(Plugin.class)); | ||
worldSizeMetric.enable(); | ||
} | ||
|
||
@AfterEach | ||
public void afterEach() { | ||
CollectorRegistry.defaultRegistry.clear(); | ||
} | ||
|
||
@Test | ||
public void doesNotThrowIfFileDoesNotExist() { | ||
givenWorldFileDoesNotExist(); | ||
assertDoesNotThrow(() -> worldSizeMetric.collect(world)); | ||
} | ||
|
||
@Test | ||
public void doesNotPopulateMetricIfFileDoesNotExist() { | ||
givenWorldFileDoesNotExist(); | ||
worldSizeMetric.collect(world); | ||
assertMetricIsEmpty(); | ||
} | ||
|
||
@Test | ||
public void setsMetricWithCorrectNameAndLabel() { | ||
String worldName = new RandomString(10).nextString(); | ||
givenWorldFileExists(worldName); | ||
worldSizeMetric.collect(world); | ||
assertNotNull(getMetricValue(worldName)); | ||
} | ||
|
||
@Test | ||
public void setsCorrectWorldSizeValue() throws IOException { | ||
String worldName = new RandomString(10).nextString(); | ||
int worldSize = new Random().ints(128, 1024).findFirst().getAsInt(); | ||
givenWorldFileExists(worldName, worldSize); | ||
worldSizeMetric.collect(world); | ||
Double value = getMetricValue(worldName); | ||
assertEquals(worldSize, value.longValue()); | ||
} | ||
|
||
private Double getMetricValue(String worldName) { | ||
return CollectorRegistry.defaultRegistry.getSampleValue( | ||
METRIC_NAME, | ||
METRIC_LABELS, | ||
new String[] { worldName } | ||
); | ||
} | ||
|
||
private void assertMetricIsEmpty() { | ||
assertNull(CollectorRegistry.defaultRegistry.getSampleValue(METRIC_NAME)); | ||
} | ||
|
||
private void givenWorldFileDoesNotExist() { | ||
String worldName = "some_file_that_surely_does_not_exist_" + new RandomString(10).nextString(); | ||
file = mock(File.class); | ||
world = mock(World.class); | ||
|
||
when(file.toPath()).thenReturn(path); | ||
when(world.getWorldFolder()).thenReturn(file); | ||
when(world.getName()).thenReturn(worldName); | ||
} | ||
|
||
private void givenWorldFileExists(String worldName, int worldSize) throws IOException { | ||
givenWorldFileExists(worldName); | ||
String filename = new RandomString(10).nextString(); | ||
File f = path.resolve(filename).toFile(); | ||
try (FileWriter writer = new FileWriter(f)) { | ||
writer.write(new RandomString(worldSize).nextString()); | ||
} | ||
} | ||
|
||
private void givenWorldFileExists(String worldName) { | ||
file = path.toFile(); | ||
world = mock(World.class); | ||
|
||
when(world.getWorldFolder()).thenReturn(file); | ||
when(world.getName()).thenReturn(worldName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package de.sldk.mc.utils; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
import java.io.*; | ||
import java.nio.file.*; | ||
import java.util.Random; | ||
import net.bytebuddy.utility.RandomString; | ||
import org.junit.jupiter.api.*; | ||
import org.junit.jupiter.api.io.TempDir; | ||
|
||
public class PathFileSizeTest { | ||
@TempDir | ||
private Path path; | ||
private PathFileSize pathFileSize; | ||
|
||
@Nested | ||
public class WhenPathIsNull { | ||
@Test | ||
public void shouldThrowException() { | ||
assertThrows(IllegalArgumentException.class, () -> new PathFileSize(null)); | ||
} | ||
} | ||
|
||
@Nested | ||
public class WhenPathDoesNotExist { | ||
@BeforeEach | ||
public void beforeEach() { | ||
path = new File("./some/random/path/that/surely/does/not/exist.bf").toPath(); | ||
pathFileSize = new PathFileSize(path); | ||
} | ||
|
||
@Test | ||
public void returnsSizeZero() throws IOException { | ||
assertEquals(0, pathFileSize.getSize()); | ||
} | ||
} | ||
|
||
@Nested | ||
public class WhenPathIsFile { | ||
@BeforeEach | ||
public void beforeEach() throws IOException { | ||
path = File.createTempFile("test", "txt").toPath(); | ||
pathFileSize = new PathFileSize(path); | ||
} | ||
|
||
@Test | ||
public void returnsZeroIfFileIsEmpty() throws IOException { | ||
assertEquals(0, pathFileSize.getSize()); | ||
} | ||
|
||
@RepeatedTest(5) | ||
public void returnsFileSize() throws IOException { | ||
int length = new Random().nextInt(10000); | ||
try (FileWriter fileWriter = new FileWriter(path.toFile())) { | ||
fileWriter.write(new RandomString(length).nextString()); | ||
} | ||
assertEquals(length, pathFileSize.getSize()); | ||
} | ||
} | ||
|
||
@Nested | ||
public class WhenPathIsDirectory { | ||
@BeforeEach | ||
public void beforeEach() throws IOException { | ||
path = Files.createTempDirectory("test-"); | ||
pathFileSize = new PathFileSize(path); | ||
} | ||
|
||
@Test | ||
public void returnsZeroIfDirectoryIsEmpty() throws IOException { | ||
assertEquals(0, pathFileSize.getSize()); | ||
} | ||
|
||
@Test | ||
public void returnsSizeOfSingleFile() throws IOException { | ||
long length = createMultipleFilesInTmpDirectory(path, 1); | ||
assertEquals(length, pathFileSize.getSize()); | ||
} | ||
|
||
@Test | ||
public void returnsSizeOfMultipleFiles() throws IOException { | ||
int files = new Random().ints(2, 10).findFirst().getAsInt(); | ||
long length = createMultipleFilesInTmpDirectory(path, files); | ||
assertEquals(length, pathFileSize.getSize()); | ||
} | ||
|
||
@Test | ||
public void returnSizeOfNestedDirectories() throws IOException { | ||
int directories = new Random().ints(2, 10).findFirst().getAsInt(); | ||
long length = createMultiplePopulatedDirectories(path, directories); | ||
assertEquals(length, pathFileSize.getSize()); | ||
} | ||
} | ||
|
||
private static long createMultiplePopulatedDirectories(Path path, int directories) throws IOException { | ||
long length = 0; | ||
for (int i = 0; i < directories; i++) { | ||
int files = new Random().ints(2, 10).findFirst().getAsInt(); | ||
Path directory = Files.createTempDirectory(path, "dir" + i + "-"); | ||
length += createMultipleFilesInTmpDirectory(directory, files); | ||
} | ||
return length; | ||
} | ||
|
||
private static long createMultipleFilesInTmpDirectory(Path path, int files) throws IOException { | ||
int totalLength = 0; | ||
for (int i = 0; i < files; i++) { | ||
int length = new Random().nextInt(10000); | ||
createFileInTmpDirectory(path, "test" + i + "txt", length); | ||
totalLength += length; | ||
} | ||
return totalLength; | ||
} | ||
|
||
private static File createFileInTmpDirectory(Path path, String name, int length) throws IOException { | ||
File file = path.resolve(name).toFile(); | ||
try (FileWriter fileWriter = new FileWriter(file)) { | ||
fileWriter.write(new RandomString(length).nextString()); | ||
} | ||
return file; | ||
} | ||
} |