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
55 lines
2.1 KiB
Go
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)
|
|
}
|
|
}
|