Files
Bridge-and-Join-s/internal/lkgateway/depo_setup_live_test.go
T
zuevav 7af6cdf2f6 Учёт DEPO: скрипт снова выполняется; логин bj виден в обоих способах; новые логин и пароль — только после проверки входа
- EXEC(...) в T-SQL склеивает только строки и переменные: REPLACE/QUOTENAME внутри
  давали ошибку 102, и SQL Server отклонял весь скрипт (.06.4–.06.6). Команда входа
  собирается в @sql заранее; тест ловит вызовы функций внутри EXEC; живая проверка
  синтаксиса на SQL Server без выполнения (SET PARSEONLY) — TestDepoSetupScriptParseLive.
- «Логин bj / Пароль bj» и в способе «Дать логин администратора»: на общем сервере
  bj_user может быть занят другим bj — подготовка сменила бы ему пароль. Предупреждение.
- Показ скрипта на странице ничего не сохраняет. Логин и пароль из выданного скрипта
  и из «Проверить подключение» хранятся черновиком (DepoNewUser/DepoNewPass) и
  становятся рабочими только после успешного входа: службы bj с неверным паролем
  за минуты блокировали логин на сервере (CHECK_POLICY) — у всех, кто им пользуется.

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

68 lines
3.0 KiB
Go

package lkgateway
import (
"context"
"os"
"testing"
"time"
)
// Синтаксис скрипта подготовки DEPO на настоящем SQL Server — без выполнения (SET PARSEONLY ON: сервер только
// разбирает текст). BJ_DEPO_PARSE_CFG=<копия setup.json с подключением к DEPO> go test -run TestDepoSetupScriptParseLive.
// Для надёжности база в скрипте — заведомо несуществующая: даже без PARSEONLY скрипт остановился бы до изменений.
func TestDepoSetupScriptParseLive(t *testing.T) {
cfg := os.Getenv("BJ_DEPO_PARSE_CFG")
if cfg == "" {
t.Skip("BJ_DEPO_PARSE_CFG не задан")
}
rc, err := NewRuntimeConfig(cfg)
if err != nil {
t.Fatal(err)
}
f := rc.Snapshot().Fancy
if f.IsPostgres() || f.Server == "" {
t.Skip("в настройках нет SQL Server DEPO")
}
ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second)
defer cancel()
db, err := fancyOpen(f, "")
if err != nil {
t.Fatal(err)
}
defer db.Close()
conn, err := db.Conn(ctx)
if err != nil {
t.Fatal(err)
}
defer conn.Close()
if _, err := conn.ExecContext(ctx, "SET PARSEONLY ON"); err != nil {
t.Fatal(err)
}
// режим действует: ошибка, поднятая командой, не возникает — значит, ничего не выполняется
if _, err := conn.ExecContext(ctx, "RAISERROR(N'parseonly-probe', 16, 1)"); err != nil {
t.Fatalf("SET PARSEONLY не действует — дальше не идём: %s", quikErrorDetail(err))
}
// и ловит ровно ту ошибку, что была в выпусках .06.4–.06.6: вызов функции внутри EXEC(...)
if _, err := conn.ExecContext(ctx, "DECLARE @p nvarchar(10) = N'a'; EXEC(N'SELECT ' + REPLACE(@p, N'a', N'1'))"); err == nil {
t.Fatal("разбор не заметил функцию внутри EXEC(...) — проверка ничего не стоит")
}
const nodb, login, pass = "BJ_PARSE_CHECK_NO_SUCH_DB", "bj_parse_check", "Xk7pQ2mN'9vR4tL8w"
for _, agent := range []bool{true, false} {
if _, err := conn.ExecContext(ctx, depoSetupScript(f, nodb, login, pass, agent)); err != nil {
t.Fatalf("скрипт (задание Agent: %v): %s", agent, quikErrorDetail(err))
}
}
// команды, которые скрипт собирает и выполняет через EXEC, — по отдельности
stmts := []string{
"CREATE LOGIN [" + login + "] WITH PASSWORD = N'" + sqlStr(pass) + "', CHECK_POLICY = ON, DEFAULT_DATABASE = [" + nodb + "]",
"ALTER LOGIN [" + login + "] WITH PASSWORD = N'" + sqlStr(pass) + "'",
}
stmts = append(stmts, depoTablesDDL(false)...)
stmts = append(stmts, depoTablesGrantSQL(false, login)...)
for _, q := range stmts {
if _, err := conn.ExecContext(ctx, q); err != nil {
t.Fatalf("%s → %s", depoStmtHead(q), quikErrorDetail(err))
}
}
}