полнота точки — множество ключей, победитель — функция множества точек
- отношение победы было нетранзитивным: полнота (частичный порядок) плюс тай-брейк (тотальный) в попарной свёртке давали цикл, из-за которого одна и та же доставка меняла содержимое объекта при каждой пересборке - надмножество побеждает только при совпадении значений общих содержательных ключей: иначе точка без единого измерения вытесняла измерение - Less стал тотальным, isEmpty не материализует значение, имя метрики в координате столкновения обрезается, отпечаток витрины включает units и sealed - на живом архиве строгий no-op: 1737 объектов, содержимое совпало побайтово
This commit is contained in:
@@ -40,7 +40,7 @@ func TestReplayЖивогоАрхива(t *testing.T) {
|
||||
f, arch, st := newFold(t)
|
||||
ctx := context.Background()
|
||||
|
||||
var folded, failed int
|
||||
var folded, failed, incomparable int
|
||||
for _, path := range bodies {
|
||||
body, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
@@ -55,14 +55,21 @@ func TestReplayЖивогоАрхива(t *testing.T) {
|
||||
id := strings.TrimSuffix(filepath.Base(path), ".json.gz")
|
||||
deliver(t, arch, st, id, "", "auto", gunzip(t, body))
|
||||
|
||||
if _, err := f.Fold(ctx, id); err != nil {
|
||||
res, err := f.Fold(ctx, id)
|
||||
if err != nil {
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
folded++
|
||||
incomparable += res.Incomparable
|
||||
}
|
||||
|
||||
t.Logf("доставок %d: свёрнуто %d, не свёрнуто %d", len(bodies), folded, failed)
|
||||
// Несравнимые наборы полей — посылка, на которой стоит отказ от объединения
|
||||
// полей: их не было ни разу на всём корпусе. Число печатается, а не
|
||||
// проверяется: появление такого набора — событие для разбора, а не отказ
|
||||
// сходимости.
|
||||
t.Logf("доставок %d: свёрнуто %d, не свёрнуто %d, несравнимых наборов %d",
|
||||
len(bodies), folded, failed, incomparable)
|
||||
|
||||
if folded == 0 {
|
||||
t.Fatal("ни одна доставка не свернулась")
|
||||
@@ -70,10 +77,19 @@ func TestReplayЖивогоАрхива(t *testing.T) {
|
||||
|
||||
// Повторный прогон того же журнала не меняет состояния: свёртка
|
||||
// детерминирована, и пересборка даёт то же, что живой приём.
|
||||
//
|
||||
// Сравнивается ОТПЕЧАТОК содержимого, а не число объектов: на координате
|
||||
// всегда лежит ровно одна точка, и правило разрешения столкновений выбирает,
|
||||
// какая это будет точка, а не сколько их. Счёт объектов совпал бы и при
|
||||
// заведомо сломанном правиле.
|
||||
before, err := st.CountBuckets(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("счёт объектов: %v", err)
|
||||
}
|
||||
fingerprintBefore, err := st.Fingerprint(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("отпечаток: %v", err)
|
||||
}
|
||||
var refolded int
|
||||
for _, path := range bodies {
|
||||
if _, err := f.Fold(ctx, strings.TrimSuffix(filepath.Base(path), ".json.gz")); err != nil {
|
||||
@@ -92,6 +108,20 @@ func TestReplayЖивогоАрхива(t *testing.T) {
|
||||
if before != after {
|
||||
t.Errorf("повторный прогон журнала изменил число объектов: %d → %d", before, after)
|
||||
}
|
||||
fingerprintAfter, err := st.Fingerprint(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("отпечаток: %v", err)
|
||||
}
|
||||
if fingerprintBefore != fingerprintAfter {
|
||||
t.Errorf("повторный прогон журнала изменил содержимое объектов:\n %s\n %s",
|
||||
fingerprintBefore, fingerprintAfter)
|
||||
}
|
||||
|
||||
// Отпечаток печатается всегда: это единственный способ сравнить состояние с
|
||||
// тем, что давала прежняя редакция правила слияния. Эталон в репозитории не
|
||||
// живёт — он производен от архива, которого нет ни на одной другой машине.
|
||||
// Значений точек отпечаток не раскрывает: содержимое входит в него хешем.
|
||||
t.Logf("объектов %d, отпечаток содержимого %s", after, fingerprintAfter)
|
||||
|
||||
// Главное измеренное число: ключ по метке дал бы 170 координат сна, ключ по
|
||||
// интервалу — 174 (docs/local-research.md, находка 47). Если координата
|
||||
|
||||
Reference in New Issue
Block a user