@@ -34,6 +34,7 @@ import Data.Functor
34
34
import Data.Int
35
35
import Data.Map.Strict (Map )
36
36
import qualified Data.Map.Strict as Map
37
+ import qualified Data.Maybe as M
37
38
import Data.Text (Text )
38
39
import qualified Data.Text as Text
39
40
import Data.Time (Day (ModifiedJulianDay ))
@@ -44,6 +45,7 @@ import DiscoverInstances (discoverInstances)
44
45
import GHC.Generics
45
46
import GHC.Stack (SrcLoc (.. ), callStack , fromCallSiteList )
46
47
import IntegrationSpec.HangingWorkflow
48
+ import IntegrationSpec.NoOpWorkflow
47
49
import IntegrationSpec.TimeoutsInWorkflows
48
50
import OpenTelemetry.Trace
49
51
import RequireCallStack
@@ -315,6 +317,7 @@ spec = do
315
317
(Just $ seconds 2 )
316
318
317
319
aroundAll setup needsClient
320
+ aroundAll setup terminateTests
318
321
where
319
322
setup :: (TestEnv -> IO () ) -> IO ()
320
323
setup go = do
@@ -1540,6 +1543,166 @@ needsClient = do
1540
1543
incompatibleReplayResult <- runReplayHistory globalRuntime incompatibleConf history
1541
1544
incompatibleReplayResult `shouldSatisfy` isLeft
1542
1545
1546
+
1547
+ terminateTests :: SpecWith TestEnv
1548
+ terminateTests = do
1549
+ describe " Terminate" $ do
1550
+ describe " when neither runId nor firstExecutionRunId is provided" $ do
1551
+ it " returns" $ \ TestEnv {.. } -> do
1552
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1553
+ baseConf
1554
+ withWorker conf $ do
1555
+ let opts =
1556
+ (C. startWorkflowOptions taskQueue)
1557
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1558
+ }
1559
+ useClient $ do
1560
+ C. start NoOpWorkflow " test-terminate-works-without-run-ids" opts
1561
+ h <- C. getHandle (workflowRef NoOpWorkflow ) " test-terminate-works-without-run-ids" Nothing Nothing
1562
+ C. terminate
1563
+ h {C. workflowHandleRunId = Nothing , C. workflowHandleFirstExecutionRunId = Nothing }
1564
+ C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1565
+ describe " when runId is provided without firstExecutionRunId" $ do
1566
+ it " returns if runId matches a workflow" $ \ TestEnv {.. } -> do
1567
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1568
+ baseConf
1569
+ withWorker conf $ do
1570
+ let opts =
1571
+ (C. startWorkflowOptions taskQueue)
1572
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1573
+ }
1574
+ useClient $ do
1575
+ h <- C. start NoOpWorkflow " test-terminate-works-with-good-run-id" opts
1576
+ h' <- C. getHandle (workflowRef NoOpWorkflow ) " test-terminate-works-with-good-run-id" h. workflowHandleRunId Nothing
1577
+ C. terminate h' C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1578
+ it " throws if runId does not match a workflow" $ \ TestEnv {.. } -> do
1579
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1580
+ baseConf
1581
+ withWorker conf $
1582
+ do
1583
+ let opts =
1584
+ (C. startWorkflowOptions taskQueue)
1585
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1586
+ }
1587
+ ( useClient $ do
1588
+ h <- C. start NoOpWorkflow " test-terminate-throws-with-bad-run-id" opts
1589
+ h' <- C. getHandle (workflowRef NoOpWorkflow ) " test-terminate-throws-with-bad-run-id" (Just " bad-run-id" ) Nothing
1590
+ C. terminate h' C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1591
+ )
1592
+ `shouldThrow` \ case
1593
+ RpcError {} -> True
1594
+ _ -> False
1595
+ describe " when firstExecutionRunId is provided without runId" $ do
1596
+ it " returns if firstExecutionRunId matches a workflow" $ \ TestEnv {.. } -> do
1597
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1598
+ baseConf
1599
+ withWorker conf $ do
1600
+ let opts =
1601
+ (C. startWorkflowOptions taskQueue)
1602
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1603
+ }
1604
+ useClient $ do
1605
+ h <- C. start NoOpWorkflow " test-terminate-works-with-good-first-execution-run-id" opts
1606
+ h' <-
1607
+ C. getHandle
1608
+ (workflowRef NoOpWorkflow )
1609
+ " test-terminate-works-with-good-first-execution-run-id"
1610
+ Nothing
1611
+ $ Just C. GetHandleOptions {C. firstExecutionRunId = Just $ M. fromJust h. workflowHandleFirstExecutionRunId}
1612
+ C. terminate h' C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1613
+ it " throws if firstExecutionRunId does not match a workflow" $ \ TestEnv {.. } -> do
1614
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1615
+ baseConf
1616
+ withWorker conf $
1617
+ do
1618
+ let opts =
1619
+ (C. startWorkflowOptions taskQueue)
1620
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1621
+ }
1622
+ ( useClient $ do
1623
+ h <- C. start NoOpWorkflow " test-terminate-throws-with-bad-first-execution-run-id" opts
1624
+ h' <-
1625
+ C. getHandle
1626
+ (workflowRef NoOpWorkflow )
1627
+ " test-terminate-throws-with-bad-first-execution-run-id"
1628
+ Nothing
1629
+ $ Just C. GetHandleOptions {C. firstExecutionRunId = Just " bad-first-execution-run-id" }
1630
+ C. terminate h' C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1631
+ )
1632
+ `shouldThrow` \ case
1633
+ RpcError {} -> True
1634
+ _ -> False
1635
+ describe " when both runId and firstExecutionRunId are provided" $ do
1636
+ it " returns if both runId and firstExecutionRunId match a workflow" $ \ TestEnv {.. } -> do
1637
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1638
+ baseConf
1639
+ withWorker conf $ do
1640
+ let opts =
1641
+ (C. startWorkflowOptions taskQueue)
1642
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1643
+ }
1644
+ useClient $ do
1645
+ h <- C. start NoOpWorkflow " test-terminate-works-with-good-run-id-bad-first-execution-run-id" opts
1646
+ h' <-
1647
+ C. getHandle
1648
+ (workflowRef NoOpWorkflow )
1649
+ " test-terminate-works-with-good-run-id-bad-first-execution-run-id"
1650
+ h. workflowHandleRunId
1651
+ $ Just
1652
+ C. GetHandleOptions
1653
+ { C. firstExecutionRunId = Just $ M. fromJust h. workflowHandleFirstExecutionRunId
1654
+ }
1655
+ C. terminate h' C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1656
+ it " throws if runId does not match a workflow" $ \ TestEnv {.. } -> do
1657
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1658
+ baseConf
1659
+ withWorker conf $ do
1660
+ let opts =
1661
+ (C. startWorkflowOptions taskQueue)
1662
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1663
+ }
1664
+ useClient
1665
+ ( do
1666
+ h <- C. start NoOpWorkflow " test-terminate-works-with-bad-run-id-good-first-execution-run-id" opts
1667
+ h' <-
1668
+ C. getHandle
1669
+ (workflowRef NoOpWorkflow )
1670
+ " test-terminate-works-with-bad-run-id-good-first-execution-run-id"
1671
+ (Just " bad-run-id" )
1672
+ ( Just
1673
+ C. GetHandleOptions
1674
+ { C. firstExecutionRunId = Just $ M. fromJust h. workflowHandleFirstExecutionRunId
1675
+ }
1676
+ )
1677
+ C. terminate h' C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1678
+ )
1679
+ `shouldThrow` \ case
1680
+ RpcError {} -> True
1681
+ _ -> False
1682
+ it " throws if firstExecutionRunId does not match a workflow" $ \ TestEnv {.. } -> do
1683
+ let conf = provideCallStack $ configure () (discoverDefinitions @ () $$ (discoverInstances) $$ (discoverInstances)) $ do
1684
+ baseConf
1685
+ withWorker conf $
1686
+ do
1687
+ let opts =
1688
+ (C. startWorkflowOptions taskQueue)
1689
+ { C. workflowIdReusePolicy = Just W. WorkflowIdReusePolicyAllowDuplicate
1690
+ }
1691
+ useClient
1692
+ ( do
1693
+ h <- C. start NoOpWorkflow " test-terminate-throws-good-run-id-bad-first-execution-run-id" opts
1694
+ h' <-
1695
+ C. getHandle
1696
+ (workflowRef NoOpWorkflow )
1697
+ " test-terminate-throws-with-good-run-id-bad-first-execution-run-id"
1698
+ (Just $ M. fromJust h. workflowHandleRunId)
1699
+ (Just C. GetHandleOptions {C. firstExecutionRunId = Just " bad-first-execution-run-id" })
1700
+ C. terminate h' C. TerminationOptions {terminationReason = " testing" , terminationDetails = [] }
1701
+ )
1702
+ `shouldThrow` \ case
1703
+ RpcError {} -> True
1704
+ _ -> False
1705
+
1543
1706
-- describe "WorkflowClient" $ do
1544
1707
-- specify "WorkflowExecutionAlreadyStartedError" pending
1545
1708
-- specify "follows only own execution chain" pending
0 commit comments