Scert/backend/internal/database/sqlite_lock_boundary_test.go

57 lines
1.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package database
import (
"context"
"errors"
"testing"
"time"
"modernc.org/sqlite"
)
func TestSQLiteNativeBusyWaitBoundaries(t *testing.T) {
for _, name := range []string{"busy_timeout", "manual_cancel_without_deadline"} {
t.Run(name, func(t *testing.T) {
first, second := newSQLiteConcurrencyPools(t)
writer, err := first.BeginTx(t.Context(), nil)
if err != nil {
t.Fatal(err)
}
defer writer.Rollback()
if _, err := writer.ExecContext(t.Context(), "UPDATE lock_probe SET value = 1 WHERE id = 1"); err != nil {
t.Fatal(err)
}
ctx := t.Context()
if name == "manual_cancel_without_deadline" {
var cancel context.CancelFunc
ctx, cancel = context.WithCancel(ctx)
defer cancel()
timer := time.AfterFunc(150*time.Millisecond, cancel)
defer timer.Stop()
}
started := time.Now()
_, err = second.ExecContext(ctx, "UPDATE lock_probe SET value = 99 WHERE id = 1")
elapsed := time.Since(started)
t.Logf("原生忙等待边界:%s,耗时=%s,错误=%v", name, elapsed, err)
if name == "busy_timeout" {
var sqliteErr *sqlite.Error
if !errors.As(err, &sqliteErr) || sqliteErr.Code() != 5 || elapsed < 4*time.Second {
t.Errorf("无截止时间的等待没有遵守默认忙等待:耗时=%s,错误=%v", elapsed, err)
}
} else if !errors.Is(err, context.Canceled) {
t.Errorf("手动取消后错误不正确:%v", err)
}
// 本测试记录现存原生等待上限,不代表无截止时间的取消可在一秒内完成。
if elapsed > 7*time.Second {
t.Errorf("原生忙等待超过允许的测试上限:%s", elapsed)
}
if err := writer.Rollback(); err != nil {
t.Fatal(err)
}
if value := readSQLiteProbe(t, second); value != 0 {
t.Fatalf("失败写入产生了副作用:%d", value)
}
})
}
}