-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c6daa34
commit 76df809
Showing
3 changed files
with
101 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,76 @@ | ||
module Main (main) where | ||
|
||
import Control.Exception (fromException, try) | ||
import Control.Monad.Catch (throwM) | ||
import Data.IORef (newIORef, readIORef, writeIORef) | ||
import Data.Time.Clock (secondsToNominalDiffTime) | ||
import Network.HTTP.Client qualified as HTTP | ||
import Stamina qualified | ||
import Stamina.HTTP qualified | ||
import Test.Hspec | ||
|
||
main :: IO () | ||
main = putStrLn "Test suite not yet implemented." | ||
main = hspec $ do | ||
describe "Stamina" $ do | ||
it "should be able to retry until it recovers" $ do | ||
lastStatus <- newIORef $ Stamina.initialRetryStatus Stamina.defaults | ||
result <- Stamina.retry Stamina.defaults $ \status -> do | ||
if Stamina.attempts status < 5 | ||
then throwM $ userError "error" | ||
else do | ||
writeIORef lastStatus status | ||
return "ok" | ||
result `shouldBe` "ok" | ||
status <- readIORef lastStatus | ||
Stamina.attempts status `shouldBe` 5 | ||
Stamina.totalDelay status `shouldSatisfy` (> secondsToNominalDiffTime 8) | ||
it "should be able to retry until maxAttemps" $ do | ||
lastStatus <- newIORef $ Stamina.initialRetryStatus Stamina.defaults | ||
result <- try $ Stamina.retry (Stamina.defaults {Stamina.maxAttempts = Just 2}) $ \status -> do | ||
writeIORef lastStatus status | ||
throwM $ userError "error" | ||
(result :: Either IOError String) `shouldBe` Left (userError "error") | ||
status <- readIORef lastStatus | ||
Stamina.attempts status `shouldBe` 2 | ||
Stamina.totalDelay status `shouldSatisfy` (< secondsToNominalDiffTime 5) | ||
it "should be able to retry until maxTime" $ do | ||
lastStatus <- newIORef $ Stamina.initialRetryStatus Stamina.defaults | ||
result <- try $ Stamina.retry (Stamina.defaults {Stamina.maxTime = Just $ secondsToNominalDiffTime 2}) $ \status -> do | ||
writeIORef lastStatus status | ||
throwM $ userError "error" | ||
(result :: Either IOError String) `shouldBe` Left (userError "error") | ||
status <- readIORef lastStatus | ||
Stamina.attempts status `shouldBe` 1 | ||
Stamina.totalDelay status `shouldSatisfy` (< secondsToNominalDiffTime 3) | ||
it "should respect resetInitial the retry status" $ do | ||
lastStatus <- newIORef $ Stamina.initialRetryStatus Stamina.defaults | ||
result <- Stamina.retry Stamina.defaults $ \status -> do | ||
if Stamina.attempts status < 3 | ||
&& (Stamina.lastException status >>= fromException) /= Just (userError "error2") | ||
then throwM $ userError "error1" | ||
else | ||
if (Stamina.lastException status >>= fromException) == Just (userError "error1") | ||
then do | ||
Stamina.resetInitial status | ||
throwM $ userError "error2" | ||
else do | ||
writeIORef lastStatus status | ||
return "ok" | ||
result `shouldBe` "ok" | ||
status <- readIORef lastStatus | ||
Stamina.attempts status `shouldBe` 1 | ||
Stamina.totalDelay status `shouldSatisfy` (< secondsToNominalDiffTime 2) | ||
|
||
describe "Stamina.HTTP" $ do | ||
it "should be able to retry on http exceptions until IO exception" $ do | ||
lastStatus <- newIORef $ Stamina.initialRetryStatus Stamina.defaults | ||
result <- try $ Stamina.HTTP.retry Stamina.defaults $ \status -> do | ||
writeIORef lastStatus status | ||
if Stamina.attempts status < 3 | ||
then throwM $ HTTP.HttpExceptionRequest HTTP.defaultRequest HTTP.ResponseTimeout | ||
else throwM $ userError "error" | ||
(result :: Either IOError String) `shouldBe` Left (userError "error") | ||
status <- readIORef lastStatus | ||
Stamina.attempts status `shouldBe` 3 | ||
|
||
-- TODO: test RetryAfter |