ests :: TestTree
tests = testGroup "CommitQueue"
  [ testGroup "single repo"
      [ testCase "update then dequeue and empty queue" $ runEmptyQueue $ \_ -> do
          updateNonEmpty pipes ["1", "3", "2"]
          assertDequeuedCommitFromRepo pipes "1"
          assertDequeuedCommitFromRepo pipes "3"
          assertDequeuedCommitFromRepo pipes "2"
          tryDequeue >>= liftIO . assertNothing "empty queue should lead to blocking"
          -- Even if we there aren't any more items to dequeue, the queue might not
          -- not be empty, since items are just blacklisted, meaning they are executing
          -- right now. We have to clear all items for that repo to effectively have
          -- an empty CommitQueue.
          updateEmpty pipes
      , testCase "concurrent update leads to unblocking of the dequeuer" $ runEmptyQueue $ \q -> do
          liftIO . forkIO . runQueue q $ updateNonEmpty pipes ["1"]
          assertDequeuedCommitFromRepo pipes "1"
      ]
  , testGroup "multiple repos"
      [ testCase "fairness" $ runEmptyQueue $ \_ -> do
          updateNonEmpty pipes ["1", "2"]
          assertDequeuedCommitFromRepo pipes "1"
          updateNonEmpty conduit ["4", "3"]
          -- we point now to what comes after pipes entry, so we wrap around
          assertDequeuedCommitFromRepo conduit "4"
          updateNonEmpty servant ["7", "5", "6"]
          -- lastRepo was conduit, so we continue with pipes
          assertDequeuedCommitFromRepo pipes "2"
          updateNonEmpty pipes ["8", "9"]
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "7"
          -- servant -> conduit
          assertDequeuedCommitFromRepo conduit "3"
          -- conduit -> pipes
          assertDequeuedCommitFromRepo pipes "8"
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "5"
          -- servant -> conduit, which is depleted, so -> pipes
          assertDequeuedCommitFromRepo pipes "9"
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "6"
          -- that should be all, see if dequeue blocks
          tryDequeue >>= liftIO . assertNothing "empty queue should lead to blocking"
          -- now tear down the queue
          updateNonEmpty conduit []
          updateNonEmpty pipes []
          updateEmpty servant
      ]
  ]

tests :: TestTree
tests = testGroup "CommitQueue"
  [ testGroup "single repo"
      [ testCase "update then dequeue and empty queue" $ runEmptyQueue $ \_ -> do
          updateNonEmpty pipes ["1", "3", "2"]
          assertDequeuedCommitFromRepo pipes "1"
          assertDequeuedCommitFromRepo pipes "3"
          assertDequeuedCommitFromRepo pipes "2"
          tryDequeue >>= liftIO . assertNothing "empty queue should lead to blocking"
          -- Even if we there aren't any more items to dequeue, the queue might not
          -- not be empty, since items are just blacklisted, meaning they are executing
          -- right now. We have to clear all items for that repo to effectively have
          -- an empty CommitQueue.
          updateEmpty pipes
      , testCase "concurrent update leads to unblocking of the dequeuer" $ runEmptyQueue $ \q -> do
          liftIO . forkIO . runQueue q $ updateNonEmpty pipes ["1"]
          assertDequeuedCommitFromRepo pipes "1"
      ]
  , testGroup "multiple repos"
      [ testCase "fairness" $ runEmptyQueue $ \_ -> do
          updateNonEmpty pipes ["1", "2"]
          assertDequeuedCommitFromRepo pipes "1"
          updateNonEmpty conduit ["4", "3"]
          -- we point now to what comes after pipes entry, so we wrap around
          assertDequeuedCommitFromRepo conduit "4"
          updateNonEmpty servant ["7", "5", "6"]
          -- lastRepo was conduit, so we continue with pipes
          assertDequeuedCommitFromRepo pipes "2"
          updateNonEmpty pipes ["8", "9"]
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "7"
          -- servant -> conduit
          assertDequeuedCommitFromRepo conduit "3"
          -- conduit -> pipes
          assertDequeuedCommitFromRepo pipes "8"
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "5"
          -- servant -> conduit, which is depleted, so -> pipes
          assertDequeuedCommitFromRepo pipes "9"
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "6"
          -- that should be all, see if dequeue blocks
          tryDequeue >>= liftIO . assertNothing "empty queue should lead to blocking"
          -- now tear down the queue
          updateNonEmpty conduit []
          updateNonEmpty pipes []
          updateEmpty servant
      ]
  ]
tests = testGroup "CommitQueue"
  [ testGroup "single repo"
      [ testCase "update then dequeue and empty queue" $ runEmptyQueue $ \_ -> do
          updateNonEmpty pipes ["1", "3", "2"]
          assertDequeuedCommitFromRepo pipes "1"
          assertDequeuedCommitFromRepo pipes "3"
          assertDequeuedCommitFromRepo pipes "2"
          tryDequeue >>= liftIO . assertNothing "empty queue should lead to blocking"
          -- Even if we there aren't any more items to dequeue, the queue might not
          -- not be empty, since items are just blacklisted, meaning they are executing
          -- right now. We have to clear all items for that repo to effectively have
          -- an empty CommitQueue.
          updateEmpty pipes
      , testCase "concurrent update leads to unblocking of the dequeuer" $ runEmptyQueue $ \q -> do
          liftIO . forkIO . runQueue q $ updateNonEmpty pipes ["1"]
          assertDequeuedCommitFromRepo pipes "1"
      ]
  , testGroup "multiple repos"
      [ testCase "fairness" $ runEmptyQueue $ \_ -> do
          updateNonEmpty pipes ["1", "2"]
          assertDequeuedCommitFromRepo pipes "1"
          updateNonEmpty conduit ["4", "3"]
          -- we point now to what comes after pipes entry, so we wrap around
          assertDequeuedCommitFromRepo conduit "4"
          updateNonEmpty servant ["7", "5", "6"]
          -- lastRepo was conduit, so we continue with pipes
          assertDequeuedCommitFromRepo pipes "2"
          updateNonEmpty pipes ["8", "9"]
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "7"
          -- servant -> conduit
          assertDequeuedCommitFromRepo conduit "3"
          -- conduit -> pipes
          assertDequeuedCommitFromRepo pipes "8"
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "5"
          -- servant -> conduit, which is depleted, so -> pipes
          assertDequeuedCommitFromRepo pipes "9"
          -- pipes -> servant
          assertDequeuedCommitFromRepo servant "6"
          -- that should be all, see if dequeue blocks
          tryDequeue >>= liftIO . assertNothing "empty queue should lead to blocking"
          -- now tear down the queue
          updateNonEmpty conduit []
          updateNonEmpty pipes []
          updateEmpty servant
      ]
  ]