mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-10-04 17:37:29 +02:00
Fixed inconsistency issues related to activity index SQL
- Subquery was not returning rows for active playtime of 0, fix: COALESCE - Union was removing duplicate 0s, replaced with UNION ALL - Query did not use floating point for calculation Affects issues: - Fixed #1388
This commit is contained in:
parent
6ee06d1cf8
commit
b375661047
@ -17,15 +17,13 @@
|
||||
package com.djrapitops.plan.delivery.domain.mutators;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.container.DataContainer;
|
||||
import com.djrapitops.plan.delivery.domain.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatter;
|
||||
import com.djrapitops.plan.gathering.domain.Session;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.HtmlLang;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Represents Activity index of a player at a certain date.
|
||||
@ -112,10 +110,7 @@ public class ActivityIndex {
|
||||
}
|
||||
|
||||
private double calculate(DataContainer container) {
|
||||
Optional<List<Session>> sessionsValue = container.getValue(PlayerKeys.SESSIONS);
|
||||
return sessionsValue
|
||||
.map(sessions -> calculate(new SessionsMutator(sessions)))
|
||||
.orElse(0.0);
|
||||
return calculate(SessionsMutator.forContainer(container));
|
||||
}
|
||||
|
||||
private double calculate(SessionsMutator sessionsMutator) {
|
||||
@ -123,7 +118,7 @@ public class ActivityIndex {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
long week = TimeAmount.WEEK.toMillis(1L);
|
||||
long week = TimeUnit.DAYS.toMillis(7L);
|
||||
long weekAgo = date - week;
|
||||
long twoWeeksAgo = date - 2L * week;
|
||||
long threeWeeksAgo = date - 3L * week;
|
||||
@ -132,13 +127,13 @@ public class ActivityIndex {
|
||||
SessionsMutator weekTwo = sessionsMutator.filterSessionsBetween(twoWeeksAgo, weekAgo);
|
||||
SessionsMutator weekThree = sessionsMutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo);
|
||||
|
||||
long playtime1 = weekOne.toActivePlaytime();
|
||||
long playtime2 = weekTwo.toActivePlaytime();
|
||||
long playtime3 = weekThree.toActivePlaytime();
|
||||
double playtime1 = weekOne.toActivePlaytime();
|
||||
double playtime2 = weekTwo.toActivePlaytime();
|
||||
double playtime3 = weekThree.toActivePlaytime();
|
||||
|
||||
double indexW1 = 1.0 / (Math.PI / 2.0 * (playtime1 * 1.0 / playtimeMsThreshold) + 1.0);
|
||||
double indexW2 = 1.0 / (Math.PI / 2.0 * (playtime2 * 1.0 / playtimeMsThreshold) + 1.0);
|
||||
double indexW3 = 1.0 / (Math.PI / 2.0 * (playtime3 * 1.0 / playtimeMsThreshold) + 1.0);
|
||||
double indexW1 = 1.0 / (Math.PI / 2.0 * (playtime1 / playtimeMsThreshold) + 1.0);
|
||||
double indexW2 = 1.0 / (Math.PI / 2.0 * (playtime2 / playtimeMsThreshold) + 1.0);
|
||||
double indexW3 = 1.0 / (Math.PI / 2.0 * (playtime3 / playtimeMsThreshold) + 1.0);
|
||||
|
||||
double average = (indexW1 + indexW2 + indexW3) / 3.0;
|
||||
|
||||
|
@ -197,7 +197,7 @@ public class SessionsMutator {
|
||||
return session -> {
|
||||
Long start = session.getUnsafe(SessionKeys.START);
|
||||
long end = session.getValue(SessionKeys.END).orElse(System.currentTimeMillis());
|
||||
return (after <= start && start <= before) || (after <= end && end <= before);
|
||||
return (after <= end && start <= before);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public class Session extends DynamicDataContainer implements DateHolder {
|
||||
|
||||
private long sessionStart;
|
||||
private final long sessionStart;
|
||||
private WorldTimes worldTimes;
|
||||
private List<PlayerKill> playerKills;
|
||||
|
||||
@ -74,7 +74,7 @@ public class Session extends DynamicDataContainer implements DateHolder {
|
||||
putSupplier(SessionKeys.PLAYER_KILL_COUNT, getUnsafe(SessionKeys.PLAYER_KILLS)::size);
|
||||
putSupplier(SessionKeys.LENGTH, () ->
|
||||
getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START));
|
||||
putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME));
|
||||
putSupplier(SessionKeys.ACTIVE_TIME, () -> getLength() - this.afkTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,7 +119,7 @@ public class Session extends DynamicDataContainer implements DateHolder {
|
||||
putSupplier(SessionKeys.PLAYER_KILL_COUNT, () -> getUnsafe(SessionKeys.PLAYER_KILLS).size());
|
||||
putSupplier(SessionKeys.LENGTH, () ->
|
||||
getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START));
|
||||
putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME));
|
||||
putSupplier(SessionKeys.ACTIVE_TIME, () -> getLength() - this.afkTime);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,20 +74,21 @@ public class ActivityIndexQueries {
|
||||
|
||||
public static String selectActivityIndexSQL() {
|
||||
String selectActivePlaytimeSQL = SELECT +
|
||||
SessionsTable.USER_UUID +
|
||||
",SUM(" +
|
||||
SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME +
|
||||
") as active_playtime" +
|
||||
"ux." + UserInfoTable.USER_UUID + ",COALESCE(active_playtime,0) AS active_playtime" +
|
||||
FROM + UserInfoTable.TABLE_NAME + " ux" +
|
||||
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_UUID +
|
||||
",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
|
||||
FROM + SessionsTable.TABLE_NAME +
|
||||
WHERE + SessionsTable.SERVER_UUID + "=?" +
|
||||
AND + SessionsTable.SESSION_START + ">=?" +
|
||||
AND + SessionsTable.SESSION_END + "<=?" +
|
||||
GROUP_BY + SessionsTable.USER_UUID;
|
||||
AND + SessionsTable.SESSION_END + ">=?" +
|
||||
AND + SessionsTable.SESSION_START + "<=?" +
|
||||
GROUP_BY + SessionsTable.USER_UUID +
|
||||
") sx on sx.uuid=ux.uuid";
|
||||
|
||||
String selectThreeWeeks = selectActivePlaytimeSQL + UNION + selectActivePlaytimeSQL + UNION + selectActivePlaytimeSQL;
|
||||
String selectThreeWeeks = selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL;
|
||||
|
||||
return SELECT +
|
||||
"5.0 - 5.0 * AVG(1 / (?/2 * (q1.active_playtime/?) +1)) as activity_index," +
|
||||
"5.0 - 5.0 * AVG(1.0 / (?/2.0 * (q1.active_playtime/?) +1.0)) as activity_index," +
|
||||
"q1." + SessionsTable.USER_UUID +
|
||||
FROM + '(' + selectThreeWeeks + ") q1" +
|
||||
GROUP_BY + "q1." + SessionsTable.USER_UUID;
|
||||
|
@ -77,19 +77,20 @@ public class NetworkActivityIndexQueries {
|
||||
|
||||
public static String selectActivityIndexSQL() {
|
||||
String selectActivePlaytimeSQL = SELECT +
|
||||
SessionsTable.USER_UUID +
|
||||
",SUM(" +
|
||||
SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME +
|
||||
") as active_playtime" +
|
||||
"ux." + UsersTable.USER_UUID + ",COALESCE(active_playtime,0) AS active_playtime" +
|
||||
FROM + UsersTable.TABLE_NAME + " ux" +
|
||||
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_UUID +
|
||||
",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
|
||||
FROM + SessionsTable.TABLE_NAME +
|
||||
WHERE + SessionsTable.SESSION_START + ">=?" +
|
||||
AND + SessionsTable.SESSION_END + "<=?" +
|
||||
GROUP_BY + SessionsTable.USER_UUID;
|
||||
WHERE + SessionsTable.SESSION_END + ">=?" +
|
||||
AND + SessionsTable.SESSION_START + "<=?" +
|
||||
GROUP_BY + SessionsTable.USER_UUID +
|
||||
") sx on sx.uuid=ux.uuid";
|
||||
|
||||
String selectThreeWeeks = selectActivePlaytimeSQL + UNION + selectActivePlaytimeSQL + UNION + selectActivePlaytimeSQL;
|
||||
String selectThreeWeeks = selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL;
|
||||
|
||||
return SELECT +
|
||||
"5.0 - 5.0 * AVG(1 / (?/2 * (q1.active_playtime/?) +1)) as activity_index," +
|
||||
"5.0 - 5.0 * AVG(1.0 / (?/2.0 * (q1.active_playtime/?) +1.0)) as activity_index," +
|
||||
"q1." + SessionsTable.USER_UUID +
|
||||
FROM + '(' + selectThreeWeeks + ") q1" +
|
||||
GROUP_BY + "q1." + SessionsTable.USER_UUID;
|
||||
|
@ -43,6 +43,7 @@ public abstract class Sql {
|
||||
public static final String INNER_JOIN = " JOIN ";
|
||||
public static final String LEFT_JOIN = " LEFT JOIN ";
|
||||
public static final String UNION = " UNION ";
|
||||
public static final String UNION_ALL = " UNION ALL ";
|
||||
public static final String AND = " AND ";
|
||||
public static final String OR = " OR ";
|
||||
public static final String IS_NULL = " IS NULL";
|
||||
|
@ -17,30 +17,40 @@
|
||||
package com.djrapitops.plan.storage.database.queries;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.TablePlayer;
|
||||
import com.djrapitops.plan.delivery.domain.keys.SessionKeys;
|
||||
import com.djrapitops.plan.delivery.domain.mutators.ActivityIndex;
|
||||
import com.djrapitops.plan.delivery.domain.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.gathering.domain.Session;
|
||||
import com.djrapitops.plan.storage.database.DatabaseTestPreparer;
|
||||
import com.djrapitops.plan.storage.database.queries.analysis.ActivityIndexQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.NetworkTablePlayersQuery;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.ServerTablePlayersQuery;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
|
||||
import com.djrapitops.plan.storage.database.transactions.events.PlayerServerRegisterTransaction;
|
||||
import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import utilities.RandomData;
|
||||
import utilities.TestConstants;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public interface ActivityIndexQueriesTest extends DatabaseTestPreparer {
|
||||
|
||||
default void storeSessions() {
|
||||
default void storeSessions(Predicate<Session> save) {
|
||||
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, RandomData::randomTime, TestConstants.PLAYER_ONE_NAME, serverUUID()));
|
||||
db().executeTransaction(new PlayerServerRegisterTransaction(player2UUID, RandomData::randomTime, TestConstants.PLAYER_TWO_NAME, serverUUID()));
|
||||
for (String world : worlds) {
|
||||
@ -48,7 +58,7 @@ public interface ActivityIndexQueriesTest extends DatabaseTestPreparer {
|
||||
}
|
||||
|
||||
for (Session session : RandomData.randomSessions(serverUUID(), worlds, playerUUID, player2UUID)) {
|
||||
execute(DataStoreQueries.storeSession(session));
|
||||
if (save.test(session)) execute(DataStoreQueries.storeSession(session));
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,9 +72,9 @@ public interface ActivityIndexQueriesTest extends DatabaseTestPreparer {
|
||||
// assertEquals(expected, groupings);
|
||||
// }
|
||||
|
||||
@Test
|
||||
@RepeatedTest(3)
|
||||
default void activityIndexCalculationsMatch() {
|
||||
storeSessions();
|
||||
storeSessions(session -> true);
|
||||
|
||||
long date = System.currentTimeMillis();
|
||||
long playtimeThreshold = TimeUnit.HOURS.toMillis(5L);
|
||||
@ -79,12 +89,85 @@ public interface ActivityIndexQueriesTest extends DatabaseTestPreparer {
|
||||
Optional<ActivityIndex> currentActivityIndex = found.get().getCurrentActivityIndex();
|
||||
assertTrue(currentActivityIndex.isPresent());
|
||||
|
||||
assertEquals(javaCalculation.getValue(), currentActivityIndex.get().getValue(), 0.001);
|
||||
assertEquals(javaCalculation.getValue(), currentActivityIndex.get().getValue(), 0.001, () -> {
|
||||
StringBuilder errorMsg = new StringBuilder("Activity indexes did not match\n");
|
||||
|
||||
long week = TimeUnit.DAYS.toMillis(7L);
|
||||
long weekAgo = date - week;
|
||||
long twoWeeksAgo = date - 2L * week;
|
||||
long threeWeeksAgo = date - 3L * week;
|
||||
|
||||
SessionsMutator mutator = new SessionsMutator(sessions);
|
||||
SessionsMutator w1 = mutator.filterSessionsBetween(weekAgo, date);
|
||||
SessionsMutator w2 = mutator.filterSessionsBetween(twoWeeksAgo, weekAgo);
|
||||
SessionsMutator w3 = mutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo);
|
||||
|
||||
Long dbW1 = db().query(SessionQueries.activePlaytime(weekAgo, date, serverUUID()));
|
||||
Long dbW2 = db().query(SessionQueries.activePlaytime(twoWeeksAgo, weekAgo, serverUUID()));
|
||||
Long dbW3 = db().query(SessionQueries.activePlaytime(threeWeeksAgo, twoWeeksAgo, serverUUID()));
|
||||
|
||||
errorMsg.append("Java calculation playtimes: ")
|
||||
.append(w1.toActivePlaytime()).append("ms,")
|
||||
.append(w2.toActivePlaytime()).append("ms,")
|
||||
.append(w3.toActivePlaytime()).append("ms\n")
|
||||
.append("DB calculation playtimes: ")
|
||||
.append(dbW1).append("ms,")
|
||||
.append(dbW2).append("ms,")
|
||||
.append(dbW3).append("ms");
|
||||
return errorMsg.toString();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@RepeatedTest(3)
|
||||
default void activityIndexCalculationsMatchWithMissingData() {
|
||||
long keepAfter = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7L);
|
||||
storeSessions(session -> session.getDate() >= keepAfter && session.getUnsafe(SessionKeys.END) >= keepAfter);
|
||||
|
||||
long date = System.currentTimeMillis();
|
||||
long playtimeThreshold = TimeUnit.HOURS.toMillis(5L);
|
||||
List<Session> sessions = db().query(SessionQueries.fetchSessionsOfPlayer(playerUUID))
|
||||
.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||
|
||||
ActivityIndex javaCalculation = new ActivityIndex(sessions, date, playtimeThreshold);
|
||||
|
||||
List<TablePlayer> players = db().query(new ServerTablePlayersQuery(serverUUID(), date, playtimeThreshold, 5));
|
||||
Optional<TablePlayer> found = players.stream().filter(tp -> playerUUID.equals(tp.getPlayerUUID())).findFirst();
|
||||
assertTrue(found.isPresent());
|
||||
Optional<ActivityIndex> currentActivityIndex = found.get().getCurrentActivityIndex();
|
||||
assertTrue(currentActivityIndex.isPresent());
|
||||
|
||||
assertEquals(javaCalculation.getValue(), currentActivityIndex.get().getValue(), 0.001, () -> {
|
||||
StringBuilder errorMsg = new StringBuilder("Activity indexes did not match\n");
|
||||
|
||||
long week = TimeUnit.DAYS.toMillis(7L);
|
||||
long weekAgo = date - week;
|
||||
long twoWeeksAgo = date - 2L * week;
|
||||
long threeWeeksAgo = date - 3L * week;
|
||||
|
||||
SessionsMutator mutator = new SessionsMutator(sessions);
|
||||
SessionsMutator w1 = mutator.filterSessionsBetween(weekAgo, date);
|
||||
SessionsMutator w2 = mutator.filterSessionsBetween(twoWeeksAgo, weekAgo);
|
||||
SessionsMutator w3 = mutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo);
|
||||
|
||||
Long dbW1 = db().query(SessionQueries.activePlaytime(weekAgo, date, serverUUID()));
|
||||
Long dbW2 = db().query(SessionQueries.activePlaytime(twoWeeksAgo, weekAgo, serverUUID()));
|
||||
Long dbW3 = db().query(SessionQueries.activePlaytime(threeWeeksAgo, twoWeeksAgo, serverUUID()));
|
||||
|
||||
errorMsg.append("Java calculation playtimes: ")
|
||||
.append(w1.toActivePlaytime()).append("ms,")
|
||||
.append(w2.toActivePlaytime()).append("ms,")
|
||||
.append(w3.toActivePlaytime()).append("ms\n")
|
||||
.append("DB calculation playtimes: ")
|
||||
.append(dbW1).append("ms,")
|
||||
.append(dbW2).append("ms,")
|
||||
.append(dbW3).append("ms");
|
||||
return errorMsg.toString();
|
||||
});
|
||||
}
|
||||
|
||||
@RepeatedTest(3)
|
||||
default void networkActivityIndexCalculationsMatch() {
|
||||
storeSessions();
|
||||
storeSessions(session -> true);
|
||||
|
||||
long date = System.currentTimeMillis();
|
||||
long playtimeThreshold = TimeUnit.HOURS.toMillis(5L);
|
||||
@ -99,7 +182,58 @@ public interface ActivityIndexQueriesTest extends DatabaseTestPreparer {
|
||||
Optional<ActivityIndex> currentActivityIndex = found.get().getCurrentActivityIndex();
|
||||
assertTrue(currentActivityIndex.isPresent());
|
||||
|
||||
assertEquals(javaCalculation.getValue(), currentActivityIndex.get().getValue(), 0.001);
|
||||
assertEquals(javaCalculation.getValue(), currentActivityIndex.get().getValue(), 0.001, () -> {
|
||||
StringBuilder errorMsg = new StringBuilder("Activity indexes did not match\n");
|
||||
|
||||
long week = TimeUnit.DAYS.toMillis(7L);
|
||||
long weekAgo = date - week;
|
||||
long twoWeeksAgo = date - 2L * week;
|
||||
long threeWeeksAgo = date - 3L * week;
|
||||
|
||||
SessionsMutator mutator = new SessionsMutator(sessions);
|
||||
SessionsMutator w1 = mutator.filterSessionsBetween(weekAgo, date);
|
||||
SessionsMutator w2 = mutator.filterSessionsBetween(twoWeeksAgo, weekAgo);
|
||||
SessionsMutator w3 = mutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo);
|
||||
|
||||
Long dbW1 = db().query(activePlaytime(weekAgo, date));
|
||||
Long dbW2 = db().query(activePlaytime(twoWeeksAgo, weekAgo));
|
||||
Long dbW3 = db().query(activePlaytime(threeWeeksAgo, twoWeeksAgo));
|
||||
|
||||
errorMsg.append("Java calculation playtimes: ")
|
||||
.append(w1.toActivePlaytime()).append("ms,")
|
||||
.append(w2.toActivePlaytime()).append("ms,")
|
||||
.append(w3.toActivePlaytime()).append("ms\n")
|
||||
.append("DB calculation playtimes: ")
|
||||
.append(dbW1).append("ms,")
|
||||
.append(dbW2).append("ms,")
|
||||
.append(dbW3).append("ms");
|
||||
return errorMsg.toString();
|
||||
});
|
||||
}
|
||||
|
||||
default Query<Long> activePlaytime(long after, long before) {
|
||||
String sql = SELECT +
|
||||
"ux." + UsersTable.USER_UUID + ",COALESCE(active_playtime,0) AS active_playtime" +
|
||||
FROM + UsersTable.TABLE_NAME + " ux" +
|
||||
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_UUID +
|
||||
",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
|
||||
FROM + SessionsTable.TABLE_NAME +
|
||||
WHERE + SessionsTable.SESSION_END + ">=?" +
|
||||
AND + SessionsTable.SESSION_START + "<=?" +
|
||||
GROUP_BY + SessionsTable.USER_UUID +
|
||||
") sx on sx.uuid=ux.uuid";
|
||||
return new QueryStatement<Long>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, after);
|
||||
statement.setLong(2, before);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long processResults(ResultSet set) throws SQLException {
|
||||
return set.next() ? set.getLong("active_playtime") : 0L;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -16,24 +16,31 @@
|
||||
*/
|
||||
package com.djrapitops.plan.storage.database.queries;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.TablePlayer;
|
||||
import com.djrapitops.plan.delivery.domain.container.PlayerContainer;
|
||||
import com.djrapitops.plan.delivery.domain.keys.SessionKeys;
|
||||
import com.djrapitops.plan.delivery.domain.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.gathering.domain.PlayerKill;
|
||||
import com.djrapitops.plan.gathering.domain.Session;
|
||||
import com.djrapitops.plan.gathering.domain.WorldTimes;
|
||||
import com.djrapitops.plan.storage.database.DatabaseTestPreparer;
|
||||
import com.djrapitops.plan.storage.database.queries.containers.PlayerContainerQuery;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.KillQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.ServerTablePlayersQuery;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.WorldTimesQueries;
|
||||
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
||||
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
|
||||
import com.djrapitops.plan.storage.database.transactions.events.PlayerServerRegisterTransaction;
|
||||
import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import utilities.RandomData;
|
||||
import utilities.TestConstants;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ -258,61 +265,60 @@ public interface SessionQueriesTest extends DatabaseTestPreparer {
|
||||
assertEquals(new HashSet<>(Arrays.asList(expected)), result);
|
||||
}
|
||||
|
||||
// Tests to reproduce an issue, flaky.
|
||||
// @Test
|
||||
// default void playersTableAndPlayerPagePlaytimeMatches() {
|
||||
// prepareForSessionSave();
|
||||
// List<Session> player1Sessions = RandomData.randomSessions(serverUUID(), worlds, playerUUID, player2UUID);
|
||||
// List<Session> player2Sessions = RandomData.randomSessions(serverUUID(), worlds, player2UUID, playerUUID);
|
||||
// player1Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
// player2Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
//
|
||||
// long playtimeThreshold = RandomData.randomLong(TimeUnit.HOURS.toMillis(1L), TimeUnit.DAYS.toMillis(2L));
|
||||
//
|
||||
// PlayerContainer playerContainer = db().query(new PlayerContainerQuery(playerUUID));
|
||||
// TablePlayer tablePlayer = db().query(new ServerTablePlayersQuery(serverUUID(), System.currentTimeMillis(), playtimeThreshold, 5))
|
||||
// .stream().filter(player -> playerUUID.equals(player.getPlayerUUID())).findAny()
|
||||
// .orElseThrow(AssertionError::new);
|
||||
//
|
||||
// long expected = SessionsMutator.forContainer(playerContainer).toPlaytime();
|
||||
// long got = tablePlayer.getPlaytime().orElseThrow(AssertionError::new);
|
||||
// assertEquals(expected, got);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// default void playersTableAndPlayerPageActivityIndexMatches() {
|
||||
// prepareForSessionSave();
|
||||
// List<Session> player1Sessions = RandomData.randomSessions(serverUUID(), worlds, playerUUID, player2UUID);
|
||||
// List<Session> player2Sessions = RandomData.randomSessions(serverUUID(), worlds, player2UUID, playerUUID);
|
||||
// player1Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
// player2Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
//
|
||||
// long time = System.currentTimeMillis();
|
||||
// long playtimeThreshold = RandomData.randomLong(TimeUnit.HOURS.toMillis(1L), TimeUnit.DAYS.toMillis(2L));
|
||||
//
|
||||
// PlayerContainer playerContainer = db().query(new PlayerContainerQuery(playerUUID));
|
||||
// TablePlayer tablePlayer = db().query(new ServerTablePlayersQuery(serverUUID(), time, playtimeThreshold, 5))
|
||||
// .stream().filter(player -> playerUUID.equals(player.getPlayerUUID())).findAny()
|
||||
// .orElseThrow(AssertionError::new);
|
||||
//
|
||||
// SessionsMutator sessionsMutator = SessionsMutator.forContainer(playerContainer);
|
||||
// long week = TimeAmount.WEEK.toMillis(1L);
|
||||
// long weekAgo = time - week;
|
||||
// long twoWeeksAgo = time - 2L * week;
|
||||
// long threeWeeksAgo = time - 3L * week;
|
||||
// SessionsMutator weekOne = sessionsMutator.filterSessionsBetween(weekAgo, time);
|
||||
// SessionsMutator weekTwo = sessionsMutator.filterSessionsBetween(twoWeeksAgo, weekAgo);
|
||||
// SessionsMutator weekThree = sessionsMutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo);
|
||||
//
|
||||
// long playtime1 = weekOne.toActivePlaytime();
|
||||
// long playtime2 = weekTwo.toActivePlaytime();
|
||||
// long playtime3 = weekThree.toActivePlaytime();
|
||||
//
|
||||
// double expected = playerContainer.getActivityIndex(time, playtimeThreshold).getValue();
|
||||
// double got = tablePlayer.getCurrentActivityIndex().orElseThrow(AssertionError::new).getValue();
|
||||
// assertEquals(expected, got, 0.00001,
|
||||
// () -> "Activity Indexes between queries differed, expected: <" + expected + "> but was: <" + got + ">" +
|
||||
// ". Playtime for reference container: <w1:" + playtime1 + ", w2:" + playtime2 + ", w3:" + playtime3 + ">"
|
||||
// );
|
||||
// }
|
||||
@RepeatedTest(3)
|
||||
default void playersTableAndPlayerPagePlaytimeMatches() {
|
||||
prepareForSessionSave();
|
||||
List<Session> player1Sessions = RandomData.randomSessions(serverUUID(), worlds, playerUUID, player2UUID);
|
||||
List<Session> player2Sessions = RandomData.randomSessions(serverUUID(), worlds, player2UUID, playerUUID);
|
||||
player1Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
player2Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
|
||||
long playtimeThreshold = RandomData.randomLong(TimeUnit.HOURS.toMillis(1L), TimeUnit.DAYS.toMillis(2L));
|
||||
|
||||
PlayerContainer playerContainer = db().query(new PlayerContainerQuery(playerUUID));
|
||||
TablePlayer tablePlayer = db().query(new ServerTablePlayersQuery(serverUUID(), System.currentTimeMillis(), playtimeThreshold, 5))
|
||||
.stream().filter(player -> playerUUID.equals(player.getPlayerUUID())).findAny()
|
||||
.orElseThrow(AssertionError::new);
|
||||
|
||||
long expected = SessionsMutator.forContainer(playerContainer).toPlaytime();
|
||||
long got = tablePlayer.getPlaytime().orElseThrow(AssertionError::new);
|
||||
assertEquals(expected, got);
|
||||
}
|
||||
|
||||
@RepeatedTest(3)
|
||||
default void playersTableAndPlayerPageActivityIndexMatches() {
|
||||
prepareForSessionSave();
|
||||
List<Session> player1Sessions = RandomData.randomSessions(serverUUID(), worlds, playerUUID, player2UUID);
|
||||
List<Session> player2Sessions = RandomData.randomSessions(serverUUID(), worlds, player2UUID, playerUUID);
|
||||
player1Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
player2Sessions.forEach(session -> execute(DataStoreQueries.storeSession(session)));
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
long playtimeThreshold = RandomData.randomLong(TimeUnit.HOURS.toMillis(1L), TimeUnit.DAYS.toMillis(2L));
|
||||
|
||||
PlayerContainer playerContainer = db().query(new PlayerContainerQuery(playerUUID));
|
||||
TablePlayer tablePlayer = db().query(new ServerTablePlayersQuery(serverUUID(), time, playtimeThreshold, 5))
|
||||
.stream().filter(player -> playerUUID.equals(player.getPlayerUUID())).findAny()
|
||||
.orElseThrow(AssertionError::new);
|
||||
|
||||
SessionsMutator sessionsMutator = SessionsMutator.forContainer(playerContainer);
|
||||
long week = TimeAmount.WEEK.toMillis(1L);
|
||||
long weekAgo = time - week;
|
||||
long twoWeeksAgo = time - 2L * week;
|
||||
long threeWeeksAgo = time - 3L * week;
|
||||
SessionsMutator weekOne = sessionsMutator.filterSessionsBetween(weekAgo, time);
|
||||
SessionsMutator weekTwo = sessionsMutator.filterSessionsBetween(twoWeeksAgo, weekAgo);
|
||||
SessionsMutator weekThree = sessionsMutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo);
|
||||
|
||||
long playtime1 = weekOne.toActivePlaytime();
|
||||
long playtime2 = weekTwo.toActivePlaytime();
|
||||
long playtime3 = weekThree.toActivePlaytime();
|
||||
|
||||
double expected = playerContainer.getActivityIndex(time, playtimeThreshold).getValue();
|
||||
double got = tablePlayer.getCurrentActivityIndex().orElseThrow(AssertionError::new).getValue();
|
||||
assertEquals(expected, got, 0.001,
|
||||
() -> "Activity Indexes between queries differed, expected: <" + expected + "> but was: <" + got + ">" +
|
||||
". Playtime for reference container: <w1:" + playtime1 + ", w2:" + playtime2 + ", w3:" + playtime3 + ">"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user