fix: устойчивость Redis-кластера под нагрузкой и код-ревью замечания
Redis timeout 200ms давал ложные срабатывания под пиковой нагрузкой на общем хосте — подняли до 800ms и добавили cpu/mem лимиты сервисам в compose, чтобы соседи не выедали CPU у Redis. Добавили метрику и WARN на случай, когда демаскирование не находит соответствие ни по id, ни по отпечатку маски (раньше тихо превращалось в повторное маскирование без единого следа в логах). Кластерные узлы (node-a/node-b) получили обе NER-модели (WikiNEuRal для имён, ruBERT для адресов) — раньше конфиг ссылался на несуществующие свойства и вторая ступень молча не работала. lb (nginx) и volume для prometheus/grafana данных зафиксированы в compose. Плюс код-ревью фиксы: утечка нативных ONNX-ресурсов при ошибке загрузки модели (BLOCKER), неверный HTTP-статус при сбое обработки, generic Exception в LlmClient заменён на конкретные, лишние same-package импорты убраны.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package ru.pdguard;
|
||||
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import ru.pdguard.config.SystemPolicy;
|
||||
import ru.pdguard.core.PayloadStore;
|
||||
import ru.pdguard.core.Pipeline;
|
||||
import ru.pdguard.detect.RuleRegistry;
|
||||
import ru.pdguard.detect.Span;
|
||||
import ru.pdguard.mask.Masker;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
||||
|
||||
/**
|
||||
* 200 вручную составленных текстовых тестов из {@code dataset-200.txt} — по одному
|
||||
* предложению на строку, каждое своя отдельная проверка (не сборка одного большого
|
||||
* текста, как в {@link HugeDatasetTest}). Набор покрывает все типы ПДН из
|
||||
* {@link RuleRegistry} (кроме ADDRESS_REGION/ADDRESS_DISTRICT — для них нет правил,
|
||||
* только модель второй ступени), варианты написания (регистр, формат даты, разделяющие
|
||||
* слова) и несколько строк-ловушек без разметки (известный человек, адрес отделения,
|
||||
* дата без якоря) — они не должны маскироваться вовсе.
|
||||
*
|
||||
* <p>На каждой строке: маскирование не оставляет исходное значение ПДН в открытом
|
||||
* виде, а демаскирование побайтово восстанавливает исходный текст.
|
||||
*/
|
||||
class Dataset200Test {
|
||||
|
||||
private static final RuleRegistry REGISTRY = new RuleRegistry();
|
||||
private static final Masker MASKER = new Masker();
|
||||
private static final List<BenchmarkFixtures.Sample> DATASET = BenchmarkFixtures.load("/dataset-200.txt");
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> datasetOf200Cases() {
|
||||
List<DynamicTest> cases = new java.util.ArrayList<>(DATASET.size());
|
||||
for (int i = 0; i < DATASET.size(); i++) {
|
||||
BenchmarkFixtures.Sample sample = DATASET.get(i);
|
||||
int index = i;
|
||||
cases.add(dynamicTest(
|
||||
String.format("#%03d: %s", index, preview(sample.text())),
|
||||
() -> runCase(sample, index)));
|
||||
}
|
||||
return cases.stream();
|
||||
}
|
||||
|
||||
private void runCase(BenchmarkFixtures.Sample sample, int index) {
|
||||
Pipeline pipeline = new Pipeline(REGISTRY, MASKER, new PayloadStore(1_000_000L, 30));
|
||||
String payloadId = "dataset200-" + index;
|
||||
|
||||
String masked = pipeline.process(sample.text(), payloadId, SystemPolicy.DEFAULT);
|
||||
for (Span gold : sample.gold()) {
|
||||
String value = sample.text().substring(gold.start(), gold.end());
|
||||
assertFalse(masked.contains(value),
|
||||
"ПДН типа " + gold.type() + " утекло в замаскированный текст: " + value);
|
||||
}
|
||||
|
||||
String restored = pipeline.process(masked, payloadId, SystemPolicy.DEFAULT);
|
||||
assertEquals(sample.text(), restored, "демаскирование не восстановило исходный текст");
|
||||
}
|
||||
|
||||
private static String preview(String text) {
|
||||
return text.length() <= 40 ? text : text.substring(0, 40) + "...";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user