a9915bcc82
- «Подготовить» / «Проверить подключение» показывают ход: подключение логином администратора, проверка, что это база DEPO, применение скрипта, вход логином bj, таблицы обмена, задание, процедуры, «Готово». Сервер отдаёт шаги строками JSON (stream=1), на ошибке — шаг с крестиком и причина, без перехода со страницы. - Блоки «Администратор SQL — нужен один раз, не сохраняется» и «Логин bj — под ним bj будет работать»: bj сохраняет и использует ровно то, что вписано; «другой пароль»; на итоге шага — каким логином bj работает. - Пауза 15 минут после неудачного входа в DEPO (логин/пароль отвергнуты) для фоновых служб: с неверным паролем они за минуты блокировали логин на сервере (CHECK_POLICY) у всех, кто им пользуется. Действия человека идут без паузы; новый пароль — сразу; системное событие в «Новостях». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
57 lines
2.2 KiB
Go
57 lines
2.2 KiB
Go
package lkgateway
|
|
|
|
import (
|
|
"context"
|
|
"database/sql/driver"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
mssql "github.com/microsoft/go-mssqldb"
|
|
)
|
|
|
|
type fakeDepoConnector struct {
|
|
calls int
|
|
err error
|
|
}
|
|
|
|
func (f *fakeDepoConnector) Connect(context.Context) (driver.Conn, error) {
|
|
f.calls++
|
|
return nil, f.err
|
|
}
|
|
func (f *fakeDepoConnector) Driver() driver.Driver { return nil }
|
|
|
|
// После неудачного входа службы bj с тем же паролем к серверу не ходят (иначе блокировка логина у всех,
|
|
// кто им пользуется); вход по действию человека — идёт; сетевые ошибки паузы не дают; удачный вход её снимает.
|
|
func TestDepoLoginPause(t *testing.T) {
|
|
old := globalRC
|
|
globalRC = nil
|
|
defer func() { globalRC = old }()
|
|
ctx := context.Background()
|
|
base := &fakeDepoConnector{err: mssql.Error{Number: 18456, Message: "Login failed for user 'bj_user'."}}
|
|
c := &fancyConnector{base: base, key: "test|pause", user: "bj_user", srv: "sql"}
|
|
if _, err := c.Connect(ctx); err == nil || base.calls != 1 {
|
|
t.Fatalf("первый вход: %v, обращений %d", err, base.calls)
|
|
}
|
|
if _, err := c.Connect(ctx); err == nil || base.calls != 1 || !strings.Contains(err.Error(), "не повторяет") {
|
|
t.Fatalf("служба во время паузы не должна ходить на сервер: %v, обращений %d", err, base.calls)
|
|
}
|
|
if _, _ = c.Connect(depoLoginForce(ctx)); base.calls != 2 {
|
|
t.Fatalf("вход по действию человека должен идти: обращений %d", base.calls)
|
|
}
|
|
base.err = nil
|
|
if _, err := c.Connect(depoLoginForce(ctx)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _ = c.Connect(ctx); base.calls != 4 {
|
|
t.Fatalf("удачный вход снимает паузу: обращений %d", base.calls)
|
|
}
|
|
net := &fakeDepoConnector{err: errors.New("dial tcp 10.0.0.1:1433: i/o timeout")}
|
|
c2 := &fancyConnector{base: net, key: "test|net", user: "bj_user"}
|
|
_, _ = c2.Connect(ctx)
|
|
_, _ = c2.Connect(ctx)
|
|
if net.calls != 2 {
|
|
t.Fatalf("сетевая ошибка — не повод для паузы: обращений %d", net.calls)
|
|
}
|
|
}
|