Test for default config value validity

This commit is contained in:
Rsl1122 2018-12-15 13:14:51 +02:00
parent 016fd542f6
commit 7030e86496
6 changed files with 566 additions and 0 deletions

View File

@ -0,0 +1,143 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.*;
import com.djrapitops.plan.system.settings.paths.key.Setting;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import utilities.FieldFetcher;
import utilities.TestResources;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test to check that configs contain all values required to run the plugin.
*
* @author Rsl1122
*/
public class ConfigSettingKeyTest {
@ClassRule
public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void serverConfigHasValidDefaultValues() throws IOException, IllegalAccessException {
PlanConfig planConfig = createConfig("config.yml");
Collection<Setting> settings = getServerSettings();
hasValidDefaultValuesForAllSettings(planConfig, settings);
}
@Test
public void networkConfigHasValidDefaultValues() throws IOException, IllegalAccessException {
PlanConfig planConfig = createConfig("bungeeconfig.yml");
Collection<Setting> settings = getNetworkSettings();
hasValidDefaultValuesForAllSettings(planConfig, settings);
}
private void hasValidDefaultValuesForAllSettings(PlanConfig config, Iterable<Setting> settings) {
List<String> fails = new ArrayList<>();
for (Setting setting : settings) {
checkSettingForFailures(config, setting).ifPresent(fails::add);
}
assertTrue(fails.isEmpty(), fails::toString);
}
private Optional<String> checkSettingForFailures(PlanConfig config, Setting setting) {
try {
if (!config.contains(setting.getPath())) {
return Optional.of("Did not contain " + setting.getPath());
} else {
config.get(setting);
return Optional.empty();
}
} catch (IllegalStateException validationFailed) {
return Optional.of(validationFailed.getMessage());
}
}
private Collection<Setting> getServerSettings() throws IllegalAccessException {
List<Setting> settings = new ArrayList<>();
for (Class settingKeyClass : new Class[]{
DatabaseSettings.class,
DataGatheringSettings.class,
DisplaySettings.class,
ExportSettings.class,
FormatSettings.class,
PluginDataSettings.class,
PluginSettings.class,
TimeSettings.class,
WebserverSettings.class
}) {
settings.addAll(FieldFetcher.getPublicStaticFields(settingKeyClass, Setting.class));
}
return settings;
}
private Collection<Setting> getNetworkSettings() throws IllegalAccessException {
List<Setting> settings = new ArrayList<>();
for (Class settingKeyClass : new Class[]{
DatabaseSettings.class,
DisplaySettings.class,
ExportSettings.class,
FormatSettings.class,
PluginSettings.class,
ProxySettings.class,
TimeSettings.class,
WebserverSettings.class
}) {
settings.addAll(FieldFetcher.getPublicStaticFields(settingKeyClass, Setting.class));
}
settings.add(PluginDataSettings.PLUGIN_BUYCRAFT_SECRET);
// Server settings contained in the key classes, remove
settings.remove(PluginSettings.SERVER_NAME);
settings.remove(PluginSettings.BUNGEE_COPY_CONFIG);
settings.remove(DatabaseSettings.TYPE);
settings.remove(DisplaySettings.PLAYERS_PER_SERVER_PAGE);
settings.remove(DisplaySettings.GRAPH_TPS_THRESHOLD_MED);
settings.remove(DisplaySettings.GRAPH_TPS_THRESHOLD_HIGH);
settings.remove(DisplaySettings.GRAPH_DISK_THRESHOLD_MED);
settings.remove(DisplaySettings.GRAPH_DISK_THRESHOLD_HIGH);
settings.remove(DisplaySettings.GRAPH_DISK_THRESHOLD_HIGH);
settings.remove(DisplaySettings.WORLD_ALIASES);
settings.remove(TimeSettings.ANALYSIS_REFRESH_PERIOD);
return settings;
}
private PlanConfig createConfig(String copyDefaultSettingsFrom) throws IOException {
File configFile = temporaryFolder.newFile();
TestResources.copyResourceIntoFile(configFile, "/" + copyDefaultSettingsFrom);
return createConfig(configFile);
}
private PlanConfig createConfig(File configFile) throws IOException {
PlanConfig config = new PlanConfig(configFile, null, null);
config.save();
return config;
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package utilities;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
public class FieldFetcher {
private FieldFetcher() {
/* static method class*/
}
public static <T> List<T> getPublicStaticFields(Class fromClass, Class<T> ofType) throws IllegalAccessException {
List<T> list = new ArrayList<>();
for (Field field : fromClass.getDeclaredFields()) {
if (!Modifier.isPublic(field.getModifiers())) {
continue;
}
T key = (T) field.get(null);
list.add(key);
}
return list;
}
}

View File

@ -0,0 +1,86 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package utilities;
import com.djrapitops.plan.PlanPlugin;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.file.Paths;
public class TestResources {
private TestResources() {
/* static method class */
}
public static File getTestResourceFile(String called, Class testClass) throws URISyntaxException {
return Paths.get(testClass.getResource("/" + called).toURI()).toFile();
}
public static void copyResourceIntoFile(File toFile, String resourcePath) {
createEmptyFile(toFile);
writeResourceToFile(toFile, resourcePath);
}
public static void copyTestResourceIntoFile(File toFile, InputStream testResource) {
createEmptyFile(toFile);
copyResourceToFile(toFile, testResource);
}
private static void copyResourceToFile(File toFile, InputStream testResource) {
try (InputStream in = testResource;
OutputStream out = new FileOutputStream(toFile)) {
copy(in, out);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private static void writeResourceToFile(File toFile, String resourcePath) {
try (InputStream in = PlanPlugin.class.getResourceAsStream(resourcePath);
OutputStream out = new FileOutputStream(toFile)) {
if (in == null) {
throw new FileNotFoundException("Resource with name '" + resourcePath + "' not found");
}
copy(in, out);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private static void copy(InputStream in, OutputStream out) throws IOException {
int read;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
}
private static void createEmptyFile(File toFile) {
String path = toFile.getAbsolutePath();
try {
toFile.getParentFile().mkdirs();
if (!toFile.exists() && !toFile.createNewFile()) {
throw new FileNotFoundException("Could not create file: " + path);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

View File

@ -0,0 +1,129 @@
# -----------------------------------------------------
# Plan Bungee Configuration file
# More information about each setting:
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Bungee-Configuration
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Bukkit-Configuration
# -----------------------------------------------------
Server:
IP: 0.0.0.0
Network:
Name: Plan
Plugin:
Debug: 'false'
Locale: default
Check-for-updates: true
Notify-About-DEV-Releases: false
KeepLogsForXDays: 7
# -----------------------------------------------------
# More information about SSL Certificate Settings:
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/SSL-Certificate-%28HTTPS%29-Set-Up
# -----------------------------------------------------
WebServer:
Port: 8804
InternalIP: 0.0.0.0
Security:
SSL-Certificate:
KeyStorePath: 'SSLCertificate.keystore'
KeyPass: 'default'
StorePass: 'default'
Alias: 'alias'
# -----------------------------------------------------
Database:
MySQL:
Host: localhost
Port: 3306
User: root
Password: minecraft
Database: Plan
# Launch options to append after driver address, for example
LaunchOptions: "?rewriteBatchedStatements=true&useSSL=false"
# -----------------------------------------------------
Commands:
AlternativeIP:
Enabled: false
Link: your.domain.here:%port%
Colors:
Main: '&2'
Secondary: '&7'
Highlight: '&f'
Analysis:
AutoRefreshPeriod: 60
Active:
# Minutes a player should play per week to be considered active
PlaytimeThreshold: 30
# How many days player should join per week to be considered active
LoginThreshold: 2
Export:
Enabled: false
DestinationFolder: 'Analysis Results'
Data:
# How many minutes player has to stay still to be considered AFK
AFKThresholdMinutes: 3
Commands:
LogUnknownCommands: false
CombineCommandAliases: true
Geolocations: true
Ping:
ServerEnableDelaySeconds: 300
PlayerLoginDelaySeconds: 30
KeepInactivePlayerDataForDays: 180
# -----------------------------------------------------
Customization:
UseServerTime: true
Display:
SessionsAsTable: false
LargestWorldPercInSessionTitle: false
# By Default WorldPie is ordered alphabetically, colors are still determined alphabetically.
OrderWorldPieByPercentage: false
MaxSessions: 50
MaxPlayers: 2500
MaxPlayersPlayersPage: 25000
PlayerTableFooter: true
PlayerIPs: true
GapsInGraphData: false
Formatting:
DecimalPoints: '#.##'
Dates:
# RecentDays replaces date with Today, Yesterday, Wednesday etc.
RecentDays: true
# Non-regex pattern to replace
DatePattern: 'MMM d YYYY'
Full: 'MMM d YYYY, HH:mm:ss'
NoSeconds: 'MMM d YYYY, HH:mm'
JustClock: 'HH:mm:ss'
TimeAmount:
Year: '1 year, '
Years: '%years% years, '
Month: '1 month, '
Months: '%months% months, '
Day: '1d '
Days: '%days%d '
Hours: '%hours%h '
Minutes: '%minutes%m '
Seconds: '%seconds%s'
Zero: '0s'
# -----------------------------------------------------
# More information about Themes:
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Themes
# -----------------------------------------------------
Theme:
Base: Default
Font:
FontStyleSheet: https://fonts.googleapis.com/css?family=Quicksand:300,400
FontFamily: "'Quicksand', sans-serif"
# -----------------------------------------------------
Servers:
Example:
WebServerPort: 8034
ServerName: Example
ThemeBase: Default
# -----------------------------------------------------
Plugins:
BuyCraft:
# http://help.buycraft.net/article/36-where-to-find-the-secret-key
Secret: "-"

View File

@ -0,0 +1,155 @@
# -----------------------------------------------------
# Plan Bukkit Configuration file
# More information about each setting:
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Bukkit-Configuration
# -----------------------------------------------------
Server:
ServerName: 'Plan'
# -----------------------------------------------------
# More information about Locale
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Localization
# -----------------------------------------------------
Plugin:
Debug: false
Locale: default
WriteNewLocaleFileOnEnable: false
Bungee-Override:
StandaloneMode: false
CopyBungeeConfig: true
Check-for-updates: true
Notify-About-DEV-Releases: false
KeepLogsForXDays: 7
# -----------------------------------------------------
# More information about SSL Certificate Settings:
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/SSL-Certificate-%28HTTPS%29-Set-Up
# -----------------------------------------------------
WebServer:
Port: 8804
# InternalIP usually does not need to be changed, only change it if you know what you're doing!
# 0.0.0.0 allocates Internal (local) IP automatically for the WebServer.
InternalIP: 0.0.0.0
Security:
SSL-Certificate:
KeyStorePath: 'SSLCertificate.keystore'
KeyPass: 'default'
StorePass: 'default'
Alias: 'alias'
# For those that want to serve Html from their own WebServer instead.
# Set up Html Export (https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/External-WebServer-Use)
# ATTENTION: On BungeeCord systems it is not possible to disable the WebServer on the plugin due to connection requirements.
# If the WebServer is disabled with this setting BungeeCord systems will cease to function.
DisableWebServer: false
ExternalWebServerAddress: "https://www.example.address"
# -----------------------------------------------------
Database:
Type: SQLite
MySQL:
Host: localhost
Port: 3306
User: root
Password: minecraft
Database: Plan
# Launch options to append after driver address, for example
LaunchOptions: "?rewriteBatchedStatements=true&useSSL=false"
# -----------------------------------------------------
Commands:
AlternativeIP:
Enabled: false
Link: your.domain.here:%port%
Colors:
Main: '&2'
Secondary: '&7'
Highlight: '&f'
Analysis:
AutoRefreshPeriod: 60
Active:
# Minutes a player should play per week to be considered active
PlaytimeThreshold: 30
# How many days player should join per week to be considered active
LoginThreshold: 2
LogProgress: true
Export:
Enabled: false
DestinationFolder: 'Analysis Results'
Data:
# How many minutes player has to stay still to be considered AFK
AFKThresholdMinutes: 3
Commands:
LogUnknownCommands: false
CombineCommandAliases: true
Geolocations: true
Ping:
ServerEnableDelaySeconds: 300
PlayerLoginDelaySeconds: 30
KeepInactivePlayerDataForDays: 180
# -----------------------------------------------------
Customization:
UseServerTime: true
Display:
SessionsAsTable: false
LargestWorldPercInSessionTitle: false
# By Default WorldPie is ordered alphabetically, colors are still determined alphabetically.
OrderWorldPieByPercentage: false
MaxSessions: 50
MaxPlayers: 2500
MaxPlayersPlayersPage: 25000
PlayerTableFooter: true
PlayerIPs: true
GapsInGraphData: false
Formatting:
DecimalPoints: '#.##'
# Dates settings use Java SimpleDateFormat.
# You can find the patterns & examples here:
# https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Dates:
# RecentDays replaces date with Today, Yesterday, Wednesday etc.
RecentDays: true
# Non-regex pattern to replace
DatePattern: 'MMM d YYYY'
Full: 'MMM d YYYY, HH:mm:ss'
NoSeconds: 'MMM d YYYY, HH:mm'
JustClock: 'HH:mm:ss'
TimeAmount:
Year: '1 year, '
Years: '%years% years, '
Month: '1 month, '
Months: '%months% months, '
Day: '1d '
Days: '%days%d '
Hours: '%hours%h '
Minutes: '%minutes%m '
Seconds: '%seconds%s'
Zero: '0s'
WorldAliases:
world: world
# -----------------------------------------------------
# More information about Themes:
# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Themes
#
# Since 4.1.0 colors are set in theme.yml
# -----------------------------------------------------
Theme:
Base: Default
Graphs:
TPS:
High-Threshold: 18
Medium-Threshold: 10
# Free Disk space thresholds, in megabytes.
Disk:
High-Threshold: 500
Medium-Threshold: 100
# -----------------------------------------------------
Plugins:
Factions:
HideFactions:
- ExampleFaction
Towny:
HideTowns:
- ExampleTown
BuyCraft:
# http://help.buycraft.net/article/36-where-to-find-the-secret-key
Secret: "-"

View File

@ -81,6 +81,17 @@
<version>5.3.2</version>
<scope>test</scope>
</dependency>
<dependency> <!-- JUnit 5, parameterized tests-->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
<dependency> <!-- TempDirectory, TODO DEPENDENCY TO BE REMOVED ON JUNIT 5.4 RELEASE -->
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>0.3.0</version>
</dependency>
<dependency> <!-- Mockito -->
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>