@dudousxd/nestjs-durable-testing 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1324,6 +1324,9 @@ function runStateStoreContract(name, makeStore) {
1324
1324
  engine.register("p-other", "1", async () => "done");
1325
1325
  await engine.start("p-root", {}, "pr");
1326
1326
  await engine.start("p-other", {}, "po");
1327
+ expect3((await engine.waitForRun("pr", {
1328
+ timeoutMs: 2e4
1329
+ })).status).toBe("suspended");
1327
1330
  expect3((await engine.waitForRun("pc", {
1328
1331
  timeoutMs: 2e4
1329
1332
  })).status).toBe("suspended");
@@ -1495,6 +1498,148 @@ function runStateStoreContract(name, makeStore) {
1495
1498
  expect3(await store.countCheckpoints("r1", 0, 4, [])).toBe(0);
1496
1499
  });
1497
1500
  registerCheckpointAggregationCases(t, () => store, run);
1501
+ t("listOrphanedRuns returns incomplete runs with a free or expired lease, oldest first", async () => {
1502
+ expect3(store.listOrphanedRuns).toBeDefined();
1503
+ if (!store.listOrphanedRuns) return;
1504
+ const created = /* @__PURE__ */ __name((offset) => new Date(at.getTime() + offset * 1e3), "created");
1505
+ await store.createRun(run({
1506
+ id: "held",
1507
+ createdAt: created(1)
1508
+ }));
1509
+ expect3(await store.tryLockRun("held", "live", NOW + 3e4, NOW)).toBe(true);
1510
+ await store.createRun(run({
1511
+ id: "expired",
1512
+ createdAt: created(3)
1513
+ }));
1514
+ expect3(await store.tryLockRun("expired", "dead", NOW, NOW - 1)).toBe(true);
1515
+ await store.createRun(run({
1516
+ id: "free",
1517
+ createdAt: created(2)
1518
+ }));
1519
+ await store.createRun(run({
1520
+ id: "compensating",
1521
+ status: "cancelling",
1522
+ createdAt: created(4)
1523
+ }));
1524
+ await store.createRun(run({
1525
+ id: "parked",
1526
+ status: "suspended",
1527
+ createdAt: created(0)
1528
+ }));
1529
+ await store.createRun(run({
1530
+ id: "done",
1531
+ status: "completed",
1532
+ createdAt: created(0)
1533
+ }));
1534
+ await store.createRun(run({
1535
+ id: "tenant",
1536
+ namespace: "beta",
1537
+ createdAt: created(5)
1538
+ }));
1539
+ expect3((await store.listOrphanedRuns(NOW, 10)).map((r) => r.id)).toEqual([
1540
+ "free",
1541
+ "expired",
1542
+ "compensating",
1543
+ "tenant"
1544
+ ]);
1545
+ expect3((await store.listOrphanedRuns(NOW, 2)).map((r) => r.id)).toEqual([
1546
+ "free",
1547
+ "expired"
1548
+ ]);
1549
+ expect3((await store.listOrphanedRuns(NOW, 10, "beta")).map((r) => r.id)).toEqual([
1550
+ "tenant"
1551
+ ]);
1552
+ expect3((await store.listOrphanedRuns(NOW + 3e4, 10)).map((r) => r.id)).toContain("held");
1553
+ expect3(await store.listOrphanedRuns(NOW, 0)).toEqual([]);
1554
+ });
1555
+ t("updateRunIf writes only over an expected status", async () => {
1556
+ expect3(store.updateRunIf).toBeDefined();
1557
+ if (!store.updateRunIf) return;
1558
+ await store.createRun(run({
1559
+ error: {
1560
+ message: "earlier attempt"
1561
+ }
1562
+ }));
1563
+ expect3(await store.updateRunIf("r1", [
1564
+ "suspended",
1565
+ "blocked"
1566
+ ], {
1567
+ status: "completed",
1568
+ output: {
1569
+ total: 1
1570
+ }
1571
+ })).toBe(false);
1572
+ let current = await store.getRun("r1");
1573
+ expect3(current?.status).toBe("running");
1574
+ expect3(current?.output).toBeUndefined();
1575
+ expect3(await store.updateRunIf("r1", [
1576
+ "pending",
1577
+ "running"
1578
+ ], {
1579
+ status: "suspended",
1580
+ wakeAt: 7e3,
1581
+ error: void 0,
1582
+ updatedAt: new Date(at.getTime() + 1e3)
1583
+ })).toBe(true);
1584
+ current = await store.getRun("r1");
1585
+ expect3(current?.status).toBe("suspended");
1586
+ expect3(current?.wakeAt).toBe(7e3);
1587
+ expect3(current?.error).toBeUndefined();
1588
+ expect3(current?.updatedAt.getTime()).toBe(at.getTime() + 1e3);
1589
+ await store.updateRun("r1", {
1590
+ status: "cancelled",
1591
+ error: {
1592
+ message: "cancelled"
1593
+ }
1594
+ });
1595
+ expect3(await store.updateRunIf("r1", [
1596
+ "running",
1597
+ "suspended"
1598
+ ], {
1599
+ status: "completed",
1600
+ output: {
1601
+ total: 2
1602
+ }
1603
+ })).toBe(false);
1604
+ current = await store.getRun("r1");
1605
+ expect3(current?.status).toBe("cancelled");
1606
+ expect3(current?.error).toEqual({
1607
+ message: "cancelled"
1608
+ });
1609
+ expect3(current?.output).toBeUndefined();
1610
+ expect3(await store.updateRunIf("missing", [
1611
+ "running"
1612
+ ], {
1613
+ status: "completed"
1614
+ })).toBe(false);
1615
+ expect3(await store.getRun("missing")).toBeNull();
1616
+ });
1617
+ t("updateRunIf settling a run terminal drops its singleton admission like updateRun", async () => {
1618
+ expect3(store.updateRunIf).toBeDefined();
1619
+ if (!store.updateRunIf) return;
1620
+ await store.createRun(run({
1621
+ tags: [
1622
+ "singleton:k",
1623
+ SINGLETON_ADMITTED_TAG
1624
+ ]
1625
+ }));
1626
+ expect3(await store.updateRunIf("r1", [
1627
+ "running"
1628
+ ], {
1629
+ status: "completed",
1630
+ output: {
1631
+ ok: true
1632
+ }
1633
+ })).toBe(true);
1634
+ const settled = await store.getRun("r1");
1635
+ expect3(settled?.status).toBe("completed");
1636
+ expect3(settled?.output).toEqual({
1637
+ ok: true
1638
+ });
1639
+ expect3(settled?.tags).toEqual([
1640
+ "singleton:k"
1641
+ ]);
1642
+ });
1498
1643
  t("saveCheckpointIfPending writes over a pending row only", async () => {
1499
1644
  expect3(store.saveCheckpointIfPending).toBeDefined();
1500
1645
  if (!store.saveCheckpointIfPending) return;