{-# LANGUAGE OverloadedStrings #-}
module Main where
import Test.Hspec
import Servant.Client
import Servant.API
import qualified Data.Map.Strict as Map
import Control.Concurrent (threadDelay)
import System.Process (withCreateProcess, proc, CreateProcess)
import System.IO.Silently (silence)
import Network.HTTP.Client (newManager, defaultManagerSettings)
import Data.Either (isLeft)
import Data.Time.Clock.POSIX (getPOSIXTime)
import Toxiproxy
main :: IO ()
main = hspec $ do
describe "Toxiproxy API" $ do
it "get version" $
withToxiproxyServer $
run getVersion `shouldReturn` Right version
it "post reset" $
withToxiproxyServer $
run postReset `shouldReturn` Right NoContent
it "create, update, get and delete a proxy" $
withToxiproxyServer $ do
let name = "myProxy"
let proxy = Proxy
{ proxyName = name
, proxyListen = "127.0.0.1:4444"
, proxyUpstream = "127.0.0.1:4445"
, proxyEnabled = False
, proxyToxics = []
}
run (createProxy proxy) `shouldReturn` Right proxy
run getProxies `shouldReturn` Right (Map.fromList [(name, proxy)])
run (getProxy name) `shouldReturn` Right proxy
let enabled = proxy { proxyEnabled = True }
run (updateProxy name enabled) `shouldReturn` Right enabled
run (deleteProxy name) `shouldReturn` Right NoContent
run getProxies `shouldReturn` Right Map.empty
it "populate proxies" $
withToxiproxyServer $ do
let proxy1 = Proxy
{ proxyName = "myProxy"
, proxyListen = "127.0.0.1:4444"
, proxyUpstream = "127.0.0.1:4445"
, proxyEnabled = False
, proxyToxics = []
}
let proxy2 = Proxy
{ proxyName = "myOtherProxy"
, proxyListen = "127.0.0.1:4446"
, proxyUpstream = "127.0.0.1:4447"
, proxyEnabled = False
, proxyToxics = []
}
run (postPopulate [proxy1, proxy2]) `shouldReturn` Right (Populate [proxy1, proxy2])
it "create get, update and delete toxic" $
withToxiproxyServer $ do
let name = "myProxy"
let toxicName = "latency"
let toxic = Toxic
{ toxicName = toxicName
, toxicType = Latency
, toxicStream = Upstream
, toxicToxicity = 1
, toxicAttributes = Map.fromList [("latency", 1000), ("jitter", 0)]
}
let proxy = Proxy
{ proxyName = name
, proxyListen = "127.0.0.1:4444"
, proxyUpstream = "127.0.0.1:4445"
, proxyEnabled = False
, proxyToxics = []
}
let proxyWithToxic = proxy { proxyToxics = [toxic] }
let updatedToxic =
toxic { toxicAttributes = Map.fromList [("latency", 1000), ("jitter", 0)] }
run (createProxy proxy) `shouldReturn` Right proxy
run (createToxic name toxic) `shouldReturn` Right toxic
run (getToxics name) `shouldReturn` Right [toxic]
run (getProxy name) `shouldReturn` Right proxyWithToxic
run (updateToxic name toxicName updatedToxic) `shouldReturn` Right updatedToxic
run (deleteToxic name toxicName) `shouldReturn` Right NoContent
run (getToxics name) `shouldReturn` Right []
describe "Toxiproxy Helpers" $ do
it "disabled temporarily using withDisabled" $
withToxiproxyServer $ do
let proxy = Proxy
{ proxyName = "myProxy"
, proxyListen = "127.0.0.1:4444"
, proxyUpstream = "127.0.0.1:8474"
, proxyEnabled = True
, proxyToxics = []
}
withProxy proxy $ \proxy -> do
runThroughProxy getVersion `shouldReturn` Right version
withDisabled proxy $ do
resp <- runThroughProxy getVersion
isLeft resp `shouldBe` True
runThroughProxy getVersion `shouldReturn` Right version
it "has temporary toxic using withToxic" $
withToxiproxyServer $ do
let proxy = Proxy
{ proxyName = "myProxy"
, proxyListen = "127.0.0.1:4444"
, proxyUpstream = "127.0.0.1:8474"
, proxyEnabled = True
, proxyToxics = []
}
let toxic = Toxic
{ toxicName = "latency"
, toxicType = Latency
, toxicStream = Upstream
, toxicToxicity = 1
, toxicAttributes = Map.fromList [("latency", 1000), ("jitter", 0)]
}
withProxy proxy $ \proxy -> do
runThroughProxy getVersion `shouldReturn` Right version
withToxic proxy toxic $ do
before <- getPOSIXTime
runThroughProxy getVersion `shouldReturn` Right version
after <- getPOSIXTime
after - before > 1 `shouldBe` True
runThroughProxy getVersion `shouldReturn` Right version
withToxiproxyServer :: IO a -> IO a
withToxiproxyServer f =
silence $
withCreateProcess server $ \_ _ _ _ -> threadDelay 100000 >> f
where
server :: CreateProcess
server = proc "toxiproxy-server" []
version :: Version
version = Version "git-fe6bf4f"
proxyUrl :: BaseUrl
proxyUrl = BaseUrl Http "127.0.0.1" 4444 ""
runThroughProxy :: ClientM a -> IO (Either ServantError a)
runThroughProxy f = do
manager <- newManager defaultManagerSettings
runClientM f (ClientEnv manager proxyUrl)