refactor: подтянуть Legal NER, переформатировать код и добавить тесты

Слияние с 685ec97 (третья ступень NER для юридических реквизитов),
код приведён к google-java-format, добавлены юнит-тесты
AdaptiveConcurrencyLimiter/SystemsConfig/PayloadCipher.
This commit is contained in:
Максименко Никита Владимирович
2026-09-23 22:02:45 +03:00
parent 685ec977de
commit 1328a7b234
79 changed files with 7385 additions and 6430 deletions
+59 -55
View File
@@ -1,73 +1,77 @@
package ru.pdguard;
import org.junit.jupiter.api.Test;
import ru.pdguard.core.PayloadStore;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import ru.pdguard.core.PayloadStore;
/** Ограничения хранилища соответствий: объём, срок жизни и разделение по системам. */
class PayloadStoreTest {
private static final String SYSTEM = "crm";
private static final String SYSTEM = "crm";
@Test
void returnsWhatWasStored() {
PayloadStore store = new PayloadStore(1_000_000L, 30);
store.put(SYSTEM, "id", "исходный текст", "маска");
@Test
void returnsWhatWasStored() {
PayloadStore store = new PayloadStore(1_000_000L, 30);
store.put(SYSTEM, "id", "исходный текст", "маска");
PayloadStore.Entry entry = store.byId(SYSTEM, "id");
assertNotNull(entry);
assertEquals("исходный текст", entry.original());
assertEquals("маска", entry.masked());
assertEquals("исходный текст", store.originalForMask(SYSTEM, "маска"));
PayloadStore.Entry entry = store.byId(SYSTEM, "id");
assertNotNull(entry);
assertEquals("исходный текст", entry.original());
assertEquals("маска", entry.masked());
assertEquals("исходный текст", store.originalForMask(SYSTEM, "маска"));
}
@Test
void forgetsEntriesAfterTheirLifetime() {
PayloadStore store = new PayloadStore(1_000_000L, 0);
store.put(SYSTEM, "id", "исходный текст", "маска");
assertNull(store.byId(SYSTEM, "id"), "запись с истёкшим сроком жизни не должна отдаваться");
assertNull(store.originalForMask(SYSTEM, "маска"));
}
@Test
void evictsOldestWhenOverSizeLimit() {
PayloadStore store = new PayloadStore(100L, 30);
for (int i = 0; i < 50; i++) {
store.put(SYSTEM, "id" + i, "текст номер " + i, "маска номер " + i);
}
@Test
void forgetsEntriesAfterTheirLifetime() {
PayloadStore store = new PayloadStore(1_000_000L, 0);
store.put(SYSTEM, "id", "исходный текст", "маска");
assertTrue(store.charsHeld() <= 100, "объём хранилища вышел за предел: " + store.charsHeld());
assertNull(store.byId(SYSTEM, "id0"), "самая старая запись должна быть вытеснена");
assertNotNull(store.byId(SYSTEM, "id49"), "последняя запись должна остаться");
}
assertNull(store.byId(SYSTEM, "id"), "запись с истёкшим сроком жизни не должна отдаваться");
assertNull(store.originalForMask(SYSTEM, "маска"));
}
@Test
void unknownKeysReturnNothing() {
PayloadStore store = new PayloadStore(1_000_000L, 30);
assertNull(store.byId(SYSTEM, "нет такого"));
assertNull(store.originalForMask(SYSTEM, "нет такой маски"));
}
@Test
void evictsOldestWhenOverSizeLimit() {
PayloadStore store = new PayloadStore(100L, 30);
for (int i = 0; i < 50; i++) {
store.put(SYSTEM, "id" + i, "текст номер " + i, "маска номер " + i);
}
/**
* Поиск по маске идёт только внутри своей системы. Маски детерминированы и низкоэнтропийны: без
* разделения чужую маску можно было бы подобрать и обменять на исходные данные другого
* потребителя.
*/
@Test
void oneSystemCannotReadAnotherSystemData() {
PayloadStore store = new PayloadStore(1_000_000L, 30);
store.put("crm", "общий-id", "Иванов Иван Иванович", "И. И. И.");
assertTrue(store.charsHeld() <= 100, "объём хранилища вышел за предел: " + store.charsHeld());
assertNull(store.byId(SYSTEM, "id0"), "самая старая запись должна быть вытеснена");
assertNotNull(store.byId(SYSTEM, "id49"), "последняя запись должна остаться");
}
@Test
void unknownKeysReturnNothing() {
PayloadStore store = new PayloadStore(1_000_000L, 30);
assertNull(store.byId(SYSTEM, "нет такого"));
assertNull(store.originalForMask(SYSTEM, "нет такой маски"));
}
/**
* Поиск по маске идёт только внутри своей системы. Маски детерминированы и
* низкоэнтропийны: без разделения чужую маску можно было бы подобрать и обменять
* на исходные данные другого потребителя.
*/
@Test
void oneSystemCannotReadAnotherSystemData() {
PayloadStore store = new PayloadStore(1_000_000L, 30);
store.put("crm", "общий-id", "Иванов Иван Иванович", "И. И. И.");
assertNull(store.originalForMask("analytics", "И. И. И."),
"чужую маску нельзя обменять на исходный текст");
assertNull(store.byId("analytics", "общий-id"),
"совпадение идентификатора у другой системы не даёт доступа");
assertEquals("Иванов Иван Иванович", store.originalForMask("crm", "И. И. И."),
"своя система свои данные по-прежнему получает");
}
assertNull(
store.originalForMask("analytics", "И. И. И."),
"чужую маску нельзя обменять на исходный текст");
assertNull(
store.byId("analytics", "общий-id"),
"совпадение идентификатора у другой системы не даёт доступа");
assertEquals(
"Иванов Иван Иванович",
store.originalForMask("crm", "И. И. И."),
"своя система свои данные по-прежнему получает");
}
}