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) } }