Files
Bridge-and-Join-s/internal/lkgateway/validatarng_test.go
T
zuevav cf1da4a0a9 Ключ: датчик случайных чисел Валидаты инициализируется из мастера — человек водит мышью в браузере
На сервере без экрана окно Валидаты «Пожалуйста, двигайте мышью» никто не видел, ключ в тихом режиме
падал с 0x80090022 (ИШ: «Не найден ключ ЭП (E0700009)»), пересборка справочника — тоже.
bj-validata-rng: тихая проверка датчика (testcsp -silent -random), сеанс на виртуальном экране,
движения из поля мастера повторяются в окне Валидаты (XTEST), прогресс — по полосе её окна.
Установщик ключа проверяет датчик до записи на флешку. zpki.ini: Count = числу профилей, блоки подряд.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
2026-10-06 19:53:18 +03:00

55 lines
2.1 KiB
Go

package lkgateway
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
// Движения из поля мастера доходят до сеанса датчика файлом — только допустимые, и только пока сеанс идёт.
func TestRNGMoves(t *testing.T) {
old := rngDir
rngDir = t.TempDir()
defer func() { rngDir = old }()
rngReady.Lock()
rngReady.ok = true // без обращения к root-воркеру
rngReady.Unlock()
defer func() { rngReady.Lock(); rngReady.ok = false; rngReady.Unlock() }()
_ = os.MkdirAll(filepath.Join(rngDir, "in"), 0o700)
h := &setupHandlers{}
post := func() *httptest.ResponseRecorder {
w := httptest.NewRecorder()
h.rngMoves(w, httptest.NewRequest(http.MethodPost, "/admin/setup/rng/moves", strings.NewReader(`{"m":[[10,20,0],[1001,5,3],[500,500,16],[-1,0,0]]}`)))
return w
}
if w := post(); w.Code != http.StatusConflict {
t.Fatalf("без сеанса движения не принимаются: %d", w.Code)
}
st := fmt.Sprintf(`{"state":"running","progress":0.42,"window":true,"at":%d}`, time.Now().Unix())
_ = os.WriteFile(filepath.Join(rngDir, "status.json"), []byte(st), 0o644)
w := post()
var v rngView
if err := json.Unmarshal(w.Body.Bytes(), &v); err != nil || w.Code != 200 || v.Progress != 0.42 || !v.Window {
t.Fatalf("ответ: %d %s", w.Code, w.Body.String())
}
files, _ := filepath.Glob(filepath.Join(rngDir, "in", "*.mv"))
if len(files) != 1 {
t.Fatalf("файлов движений: %d", len(files))
}
b, _ := os.ReadFile(files[0])
if string(b) != "10 20 0\n500 500 16\n" {
t.Fatalf("движения: %q", b)
}
// сеанс кончился (файл давно не обновлялся) — датчик готов, итог «done» показывается
_ = os.WriteFile(filepath.Join(rngDir, "status.json"), []byte(fmt.Sprintf(`{"state":"done","progress":1,"at":%d}`, time.Now().Unix())), 0o644)
if v := rngCheck(t.Context()); !v.Ready || v.State != "done" {
t.Fatalf("после сеанса: %+v", v)
}
}