summaryrefslogtreecommitdiff
path: root/Omni/Task/RaceTest.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Task/RaceTest.hs')
-rw-r--r--Omni/Task/RaceTest.hs58
1 files changed, 58 insertions, 0 deletions
diff --git a/Omni/Task/RaceTest.hs b/Omni/Task/RaceTest.hs
new file mode 100644
index 0000000..8ab797a
--- /dev/null
+++ b/Omni/Task/RaceTest.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Omni.Task.RaceTest where
+
+import Alpha
+import Control.Concurrent.Async (mapConcurrently)
+import Data.List (nub)
+import qualified Data.Text as T
+import Omni.Task.Core
+import qualified Omni.Test as Test
+import System.Directory (doesFileExist, removeFile)
+import System.Environment (setEnv)
+
+test :: Test.Tree
+test = Test.group "Omni.Task.Race" [raceTest]
+
+raceTest :: Test.Tree
+raceTest =
+ Test.unit "concurrent child creation (race condition)" <| do
+ -- Set up test mode (uses _/tmp/tasks-test.db)
+ setEnv "TASK_TEST_MODE" "1"
+
+ -- Clean up test database
+ let testFile = "_/tmp/tasks-test.db"
+ exists <- doesFileExist testFile
+ when exists <| removeFile testFile
+ initTaskDb
+
+ -- Create a parent epic
+ parent <- createTask "Parent Epic" Epic Nothing Nothing P2 Nothing [] "Parent Epic description"
+ let parentId = taskId parent
+
+ -- Create multiple children concurrently
+ -- We'll create 10 children in parallel
+ let childCount = 10
+ indices = [1 .. childCount]
+
+ -- Run concurrent creations
+ children <-
+ mapConcurrently
+ (\i -> createTask ("Child " <> tshow i) WorkTask (Just parentId) Nothing P2 Nothing [] ("Child " <> tshow i <> " description"))
+ indices
+
+ -- Check for duplicates in generated IDs
+ let ids = map taskId children
+ uniqueIds = nub ids
+
+ -- If there was a race condition, we'd have fewer unique IDs than children
+ length uniqueIds Test.@?= length children
+ length uniqueIds Test.@?= childCount
+
+ -- Verify IDs follow the pattern parentId.N
+ for_ ids <| \tid -> do
+ (parentId `T.isPrefixOf` tid) Test.@?= True
+
+ -- Cleanup
+ removeFile testFile