sync: 同步 v1.0.4 开源代码并脱敏
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
batchdomain "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/batch"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/dao"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/library/batchfields"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/model/do"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/model/entity"
|
||||
)
|
||||
@@ -71,6 +72,11 @@ func (r *Repository) MarkProcessing(ctx context.Context, batchNo string, batchTy
|
||||
Update(); updateErr != nil {
|
||||
return gerror.Wrap(updateErr, "mark pending batch details running failed")
|
||||
}
|
||||
if batchType == 107 || batchType == 109 || batchType == 110 {
|
||||
if _, insertErr := tx.Exec("INSERT INTO data_operation_parent (batch_no,ready) VALUES (?,0)", batchNo); insertErr != nil {
|
||||
return gerror.Wrap(insertErr, "create durable APN parent marker failed")
|
||||
}
|
||||
}
|
||||
claimed = true
|
||||
return nil
|
||||
})
|
||||
@@ -114,7 +120,7 @@ func (r *Repository) MarkFailed(ctx context.Context, batchNo string, batchType i
|
||||
Data(do.BatchMain{
|
||||
BatchAsyncStatus: batchdomain.AsyncStatusFailed,
|
||||
RunResult: batchdomain.RunResultFailed,
|
||||
FailReason: reason,
|
||||
FailReason: batchfields.FailureReason(reason),
|
||||
EndTime: gtime.Now(),
|
||||
}).
|
||||
Update()
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
batchdomain "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/batch"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/dao"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/library/batchfields"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/model/do"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/model/entity"
|
||||
)
|
||||
@@ -150,6 +151,26 @@ func TestMarkFailedTruncatesDetailReason(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarkFailedKeepsMainReasonWithinTextColumn(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repository := newTestRepository(t, ctx)
|
||||
insertBatch(t, ctx, repository.db, "B-LONG", batchdomain.Type103)
|
||||
if claimed, err := repository.MarkProcessing(ctx, "B-LONG", batchdomain.Type103); err != nil || !claimed {
|
||||
t.Fatalf("claim batch = (%t, %v)", claimed, err)
|
||||
}
|
||||
reason := "database error: INSERT INTO batch_detail VALUES (" + strings.Repeat("错", 30000) + ")"
|
||||
if marked, err := repository.MarkFailed(ctx, "B-LONG", batchdomain.Type103, reason); err != nil || !marked {
|
||||
t.Fatalf("mark failed = (%t, %v)", marked, err)
|
||||
}
|
||||
var main entity.BatchMain
|
||||
if err := repository.db.Model(dao.BatchMain.Table()).Ctx(ctx).Where(dao.BatchMain.Columns().BatchNo, "B-LONG").Scan(&main); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(main.FailReason) > batchfields.FailureReasonByteLimit || strings.Contains(main.FailReason, "VALUES") {
|
||||
t.Fatalf("unsafe failure reason: %q", main.FailReason)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestRepository(t *testing.T, ctx context.Context) *Repository {
|
||||
t.Helper()
|
||||
db, err := gdb.New(gdb.ConfigNode{
|
||||
@@ -192,6 +213,42 @@ func insertBatch(t *testing.T, ctx context.Context, db gdb.DB, batchNo string, b
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarkProcessingAPNMarkerIsAtomic(t *testing.T) {
|
||||
for _, batchType := range []int{107, 109, 110} {
|
||||
t.Run(string(rune('A'+batchType-107)), func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repo := newTestRepository(t, ctx)
|
||||
insertBatch(t, ctx, repo.db, "APN", batchType)
|
||||
claimed, err := repo.MarkProcessing(ctx, "APN", batchType)
|
||||
if err == nil || claimed {
|
||||
t.Fatalf("缺少迁移必须安全失败: claimed=%t err=%v", claimed, err)
|
||||
}
|
||||
assertStatus(t, ctx, repo.db, "batch_main", "batch_async_status", batchdomain.AsyncStatusPending)
|
||||
main, err := repo.FindMain(ctx, "APN")
|
||||
if err != nil || main.StartTime != nil {
|
||||
t.Fatalf("失败未回滚首发时间: %+v %v", main, err)
|
||||
}
|
||||
pending, err := repo.db.Model("batch_detail").Ctx(ctx).Where("detail_status", batchdomain.DetailStatusPending).Count()
|
||||
if err != nil || pending != 1 {
|
||||
t.Fatalf("明细没有安全回滚: %d %v", pending, err)
|
||||
}
|
||||
if _, err := repo.db.Exec(ctx, "CREATE TABLE data_operation_parent(batch_no TEXT PRIMARY KEY,ready INTEGER DEFAULT 0)"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if claimed, err := repo.MarkProcessing(ctx, "APN", batchType); err != nil || !claimed {
|
||||
t.Fatalf("新批领取: %t %v", claimed, err)
|
||||
}
|
||||
n, err := repo.db.Model("data_operation_parent").Ctx(ctx).Where("batch_no", "APN").Where("ready", 0).Count()
|
||||
if err != nil || n != 1 {
|
||||
t.Fatalf("新批缺少原子凭据: %d %v", n, err)
|
||||
}
|
||||
if claimed, err := repo.MarkProcessing(ctx, "APN", batchType); err != nil || claimed {
|
||||
t.Fatalf("重投不应重复创建凭据: %t %v", claimed, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertStatus(t *testing.T, ctx context.Context, db gdb.DB, table, column string, expected int) {
|
||||
t.Helper()
|
||||
actual, err := db.Model(table).Ctx(ctx).Value(column)
|
||||
|
||||
Reference in New Issue
Block a user