124 lines
5.6 KiB
Go
124 lines
5.6 KiB
Go
package data
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/consts"
|
|
service "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/service/data"
|
|
)
|
|
|
|
func TestSubBatchFrozenOrderNewClaimFirstDoesNotCancelOlderCards(t *testing.T) {
|
|
repo, ctx := testSubBatchDB(t)
|
|
for _, q := range []string{
|
|
`UPDATE batch_detail SET item_id=CASE id WHEN 2 THEN 'B' ELSE 'A' END,snapshot='{"authorized":true}'`,
|
|
`UPDATE batch_detail SET batch_type=109 WHERE batch_no='S-2'`,
|
|
`INSERT INTO t_sim_card_info(id,tenant_id,iccid,data_service_status)VALUES(1,'tenant','A',1),(2,'tenant','B',1)`,
|
|
} {
|
|
if _, err := repo.database().Exec(ctx, q); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
older := testSub("S-1", "frozen-stop-AB", "a", []int64{1, 2}, []string{"A", "B"})
|
|
newer := testSub("S-2", "frozen-open-A", "a", []int64{3}, []string{"A"})
|
|
newer.BatchType = 109
|
|
newer.Request.ReqData.OperType = "0"
|
|
for _, sub := range []service.SubBatch{older, newer} {
|
|
if err := repo.PrepareSubBatch(ctx, sub); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if got, err := repo.ClaimSubBatch(ctx, newer.OperationID, "new-first", time.Now()); err != nil || got != nil {
|
|
t.Fatalf("newer overtook frozen predecessor: %+v %v", got, err)
|
|
}
|
|
row, err := repo.database().GetOne(ctx, "SELECT status FROM data_operation_sub_batch WHERE operation_id=?", older.OperationID)
|
|
if err != nil || row["status"].String() != "prepared" {
|
|
t.Fatalf("older work cancelled: %v %v", row, err)
|
|
}
|
|
first, err := repo.ClaimSubBatch(ctx, older.OperationID, "old-first", time.Now())
|
|
if err != nil || first == nil {
|
|
t.Fatalf("older not claimable: %+v %v", first, err)
|
|
}
|
|
if err := repo.CompleteSubBatch(ctx, *first, []service.Outcome{{Success: true}, {Success: true}}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rows, err := repo.database().GetAll(ctx, "SELECT iccid,data_service_status FROM t_sim_card_info ORDER BY iccid")
|
|
if err != nil || len(rows) != 2 || rows[0]["data_service_status"].Int() != 0 || rows[1]["data_service_status"].Int() != 0 {
|
|
t.Fatalf("stop A/B not persisted: %v %v", rows, err)
|
|
}
|
|
if _, err := repo.database().Exec(ctx, "UPDATE data_operation_sub_batch SET next_check_at=NULL WHERE operation_id=?", newer.OperationID); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second, err := repo.ClaimSubBatch(ctx, newer.OperationID, "new-after-old", time.Now())
|
|
if err != nil || second == nil {
|
|
t.Fatalf("newer not released after old terminal: %+v %v", second, err)
|
|
}
|
|
if err := repo.CompleteSubBatch(ctx, *second, []service.Outcome{{Success: true}}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rows, err = repo.database().GetAll(ctx, "SELECT iccid,data_service_status FROM t_sim_card_info ORDER BY iccid")
|
|
if err != nil || rows[0]["data_service_status"].Int() != 1 || rows[1]["data_service_status"].Int() != 0 {
|
|
t.Fatalf("reverse should reopen only A, keep B stopped: %v %v", rows, err)
|
|
}
|
|
details, err := repo.database().GetAll(ctx, "SELECT detail_status FROM batch_detail ORDER BY id")
|
|
if err != nil || len(details) != 3 {
|
|
t.Fatalf("details: %v %v", details, err)
|
|
}
|
|
for _, d := range details {
|
|
if d["detail_status"].Int() != consts.BatchDetailStatusSuccess {
|
|
t.Fatalf("card was omitted or cancelled: %v", details)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSubBatchParentOrderSurvivesReverseFreezeOrder(t *testing.T) {
|
|
repo, ctx := testSubBatchDB(t)
|
|
older := testSub("S-1", "parent-old-freeze-second", "a", []int64{1, 2}, []string{"A", "B"})
|
|
newer := testSub("S-2", "parent-new-freeze-first", "a", []int64{3}, []string{"A"})
|
|
for _, b := range []service.SubBatch{newer, older} {
|
|
if err := repo.PrepareSubBatch(ctx, b); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
oldStored, _ := repo.GetSubBatch(ctx, older.OperationID)
|
|
newStored, _ := repo.GetSubBatch(ctx, newer.OperationID)
|
|
if oldStored.ID <= newStored.ID {
|
|
t.Fatal("未实际复现父批与冻结ID相反顺序")
|
|
}
|
|
if got, err := repo.ClaimSubBatch(ctx, newer.OperationID, "new-first", time.Now()); err != nil || got != nil {
|
|
t.Fatalf("新批越过已冻结的旧父批: %+v %v", got, err)
|
|
}
|
|
if got, err := repo.ClaimSubBatch(ctx, older.OperationID, "old-first", time.Now()); err != nil || got == nil {
|
|
t.Fatalf("旧停AB应完整可领取: %+v %v", got, err)
|
|
}
|
|
n, err := repo.database().Model(claimTable).Ctx(ctx).Where("active_operation_id", older.OperationID).Count()
|
|
if err != nil || n != 2 {
|
|
t.Fatalf("旧批不能遗漏B: %d %v", n, err)
|
|
}
|
|
}
|
|
|
|
func TestSubBatchPreparedPredecessorWaitHasFiniteUnsubmittedOutcome(t *testing.T) {
|
|
repo, ctx := testSubBatchDB(t)
|
|
older := testSub("S-1", "prepared-old", "a", []int64{1}, []string{"A"})
|
|
newer := testSub("S-2", "prepared-new", "a", []int64{3}, []string{"A"})
|
|
for _, sub := range []service.SubBatch{older, newer} {
|
|
if err := repo.PrepareSubBatch(ctx, sub); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if _, err := repo.database().Exec(ctx, "UPDATE data_operation_sub_batch SET created_at=?,next_check_at=NULL WHERE operation_id=?", time.Now().Add(-16*time.Minute), newer.OperationID); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got, err := repo.ClaimSubBatch(ctx, newer.OperationID, "expired", time.Now()); err != nil || got != nil {
|
|
t.Fatalf("expired later intent was submitted: %+v %v", got, err)
|
|
}
|
|
row, err := repo.database().GetOne(ctx, "SELECT status,submitted_at,poll_count FROM data_operation_sub_batch WHERE operation_id=?", newer.OperationID)
|
|
if err != nil || row["status"].String() != "review" || !row["submitted_at"].IsNil() || row["poll_count"].Int() != 0 {
|
|
t.Fatalf("later intent not finitely closed unsent: %v %v", row, err)
|
|
}
|
|
row, err = repo.database().GetOne(ctx, "SELECT status FROM data_operation_sub_batch WHERE operation_id=?", older.OperationID)
|
|
if err != nil || row["status"].String() != "prepared" {
|
|
t.Fatalf("older intent cancelled: %v %v", row, err)
|
|
}
|
|
}
|