8febe12d7d
真实本机 PG/ES/MinIO:v071 目录镜像 10 模式、结构引用/游标 15 模式、 8 表×2 外部范围身份矩阵、13 模式自然键(含软删除与合法同 parent 正例)、 备份期间三注入、收尾故障与授权撤销两个真实治理 PG 用例。 需隔离服务的用例在 test-scope.json 显式声明:普通 CI 跳过不算通过。
52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestContractExecutionMutexWaitsForActualWriter(t *testing.T) {
|
|
store, _ := newIdentityStore(t)
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
key := fmt.Sprintf("isolated-%s-%d", t.Name(), time.Now().UnixNano())
|
|
entered := make(chan struct{})
|
|
release := make(chan struct{})
|
|
finished := make(chan error, 1)
|
|
go func() {
|
|
finished <- store.WithLibraryExecution(ctx, key, func(ctx context.Context, ping func(context.Context) error) error {
|
|
if err := ping(ctx); err != nil {
|
|
return err
|
|
}
|
|
close(entered)
|
|
<-ctx.Done()
|
|
<-release
|
|
return ctx.Err()
|
|
})
|
|
}()
|
|
select {
|
|
case <-entered:
|
|
case err := <-finished:
|
|
t.Fatalf("first executor: %v", err)
|
|
case <-time.After(5 * time.Second):
|
|
t.Fatal("first executor timeout")
|
|
}
|
|
cancel()
|
|
called := false
|
|
err := store.WithLibraryExecution(context.Background(), key, func(context.Context, func(context.Context) error) error { called = true; return nil })
|
|
close(release)
|
|
if err2 := <-finished; !errors.Is(err2, context.Canceled) {
|
|
t.Fatalf("first executor exit: %v", err2)
|
|
}
|
|
if !errors.Is(err, ErrLibraryExecutionBusy) || called {
|
|
t.Fatalf("cancelled but still-writing executor was overlapped: err=%v called=%v", err, called)
|
|
}
|
|
called = false
|
|
if err = store.WithLibraryExecution(context.Background(), key, func(context.Context, func(context.Context) error) error { called = true; return nil }); err != nil || !called {
|
|
t.Fatalf("finished executor not released: %v %v", err, called)
|
|
}
|
|
}
|