Hello community,

here is the log from the commit of package ghc-consul-haskell for 
openSUSE:Factory checked in at 2017-03-03 17:49:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-consul-haskell (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-consul-haskell.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-consul-haskell"

Fri Mar  3 17:49:02 2017 rev:2 rq:461619 version:0.4.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-consul-haskell/ghc-consul-haskell.changes    
2016-09-25 14:39:32.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.ghc-consul-haskell.new/ghc-consul-haskell.changes   
    2017-03-03 17:49:03.246821089 +0100
@@ -1,0 +2,5 @@
+Sun Feb 12 14:14:58 UTC 2017 - [email protected]
+
+- Update to version 0.4.2 with cabal2obs.
+
+-------------------------------------------------------------------

Old:
----
  consul-haskell-0.3.tar.gz

New:
----
  consul-haskell-0.4.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-consul-haskell.spec ++++++
--- /var/tmp/diff_new_pack.AU5pWj/_old  2017-03-03 17:49:03.886730715 +0100
+++ /var/tmp/diff_new_pack.AU5pWj/_new  2017-03-03 17:49:03.894729584 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-consul-haskell
 #
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,20 +19,20 @@
 %global pkg_name consul-haskell
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.3
+Version:        0.4.2
 Release:        0
 Summary:        A consul client for Haskell
 License:        BSD-3-Clause
-Group:          System/Libraries
+Group:          Development/Languages/Other
 Url:            https://hackage.haskell.org/package/%{pkg_name}
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
 BuildRequires:  ghc-Cabal-devel
-# Begin cabal-rpm deps:
 BuildRequires:  ghc-aeson-devel
 BuildRequires:  ghc-base64-bytestring-devel
 BuildRequires:  ghc-bytestring-devel
 BuildRequires:  ghc-connection-devel
 BuildRequires:  ghc-either-devel
+BuildRequires:  ghc-exceptions-devel
 BuildRequires:  ghc-http-client-devel
 BuildRequires:  ghc-http-client-tls-devel
 BuildRequires:  ghc-http-types-devel
@@ -40,17 +40,21 @@
 BuildRequires:  ghc-lifted-base-devel
 BuildRequires:  ghc-monad-control-devel
 BuildRequires:  ghc-network-devel
+BuildRequires:  ghc-retry-devel
 BuildRequires:  ghc-rpm-macros
 BuildRequires:  ghc-stm-devel
 BuildRequires:  ghc-text-devel
 BuildRequires:  ghc-transformers-devel
+BuildRequires:  ghc-unordered-containers-devel
+BuildRequires:  ghc-vector-devel
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 %if %{with tests}
 BuildRequires:  ghc-HUnit-devel
+BuildRequires:  ghc-random-devel
 BuildRequires:  ghc-tasty-devel
 BuildRequires:  ghc-tasty-hunit-devel
+BuildRequires:  ghc-uuid-devel
 %endif
-# End cabal-rpm deps
 
 %description
 A consul client for Haskell
@@ -71,20 +75,14 @@
 %prep
 %setup -q -n %{pkg_name}-%{version}
 
-
 %build
 %ghc_lib_build
 
-
 %install
 %ghc_lib_install
 
-
 %check
-%if %{with tests}
-%{cabal} test
-%endif
-
+%cabal_test
 
 %post devel
 %ghc_pkg_recache

++++++ consul-haskell-0.3.tar.gz -> consul-haskell-0.4.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/consul-haskell-0.3/consul-haskell.cabal 
new/consul-haskell-0.4.2/consul-haskell.cabal
--- old/consul-haskell-0.3/consul-haskell.cabal 2015-09-30 18:33:32.000000000 
+0200
+++ new/consul-haskell-0.4.2/consul-haskell.cabal       2017-01-25 
17:42:27.000000000 +0100
@@ -1,5 +1,5 @@
 name:                consul-haskell
-version:             0.3
+version:             0.4.2
 synopsis:            A consul client for Haskell
 description:
   A consul client for Haskell
@@ -36,6 +36,7 @@
     bytestring,
     connection,
     either,
+    exceptions,
     http-client,
     http-client-tls,
     http-types,
@@ -43,9 +44,12 @@
     lifted-base,
     monad-control >= 1.0,
     network,
+    retry,
+    stm,
     text,
     transformers,
-    stm
+    unordered-containers,
+    vector
   ghc-options:
     -Wall
 
@@ -63,10 +67,12 @@
     consul-haskell,
     http-client,
     network,
+    random,
     tasty,
     tasty-hunit,
     text,
     transformers,
+    uuid,
     HUnit                      >= 1.2
   ghc-options:
     -Wall
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/consul-haskell-0.3/src/Network/Consul/Internal.hs 
new/consul-haskell-0.4.2/src/Network/Consul/Internal.hs
--- old/consul-haskell-0.3/src/Network/Consul/Internal.hs       2015-10-13 
06:56:36.000000000 +0200
+++ new/consul-haskell-0.4.2/src/Network/Consul/Internal.hs     2016-09-26 
00:23:08.000000000 +0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE OverloadedStrings #-}
 
@@ -37,15 +38,18 @@
   --Catalog
   , getDatacenters
   , getService
+  , getServices
   ) where
 
 import Control.Monad.IO.Class
-import Data.Aeson (decode,encode)
+import Data.Aeson (Value(..), decode,encode)
 import Data.ByteString (ByteString)
 import qualified Data.ByteString as B
 --import qualified Data.ByteString.Base64 as B64
 import qualified Data.ByteString.Lazy as BL
+import qualified Data.HashMap.Strict as H
 import Data.Maybe
+import qualified Data.Vector as V
 import Data.Text (Text)
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as TE
@@ -64,13 +68,23 @@
   let baseUrl = T.concat [hostWithScheme,":",T.pack $ show 
portNumber,endpoint,needQueryString
                          ,maybe "" id query, prefixAnd, maybe "" (\ 
(Datacenter x) -> T.concat["dc=",x]) dc]
   initReq <- liftIO $ parseUrl $ T.unpack baseUrl
+#if MIN_VERSION_http_client(0,5,0)
+  case body of
+      Just x -> return $ indef $ initReq{ method = "PUT", requestBody = 
RequestBodyBS x, checkResponse = \ _ _ -> return ()}
+      Nothing -> return $ indef $ initReq{checkResponse = \ _ _ -> return ()}
+#else
   case body of
     Just x -> return $ indef $ initReq{ method = "PUT", requestBody = 
RequestBodyBS x, checkStatus = \ _ _ _ -> Nothing}
     Nothing -> return $ indef $ initReq{checkStatus = \ _ _ _ -> Nothing}
+#endif
   where
     needQueryString = if isJust dc || isJust query then "?" else ""
     prefixAnd = if isJust query && isJust dc then "&" else ""
+#if MIN_VERSION_http_client(0,5,0)
+    indef req = if wait == True then req{responseTimeout = 
responseTimeoutNone} else req
+#else
     indef req = if wait == True then req{responseTimeout = Nothing} else req
+#endif
 
 {- Key Value Store -}
 getKey :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe Word64 
-> Maybe Consistency -> Maybe Datacenter -> m (Maybe 
Network.Consul.Types.KeyValue)
@@ -172,13 +186,17 @@
     query = T.intercalate "&" $ catMaybes [flags,cas,Just release]
     fquery = if query /= T.empty then Just query else Nothing
 
-deleteKey :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Bool -> 
Maybe Datacenter -> m ()
+deleteKey :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Bool -> 
Maybe Datacenter -> m Bool
 deleteKey manager hostname portNumber key recurse dc = do
   initReq <- createRequest hostname portNumber (T.concat ["/v1/kv/", key]) (if 
recurse then Just "recurse" else Nothing) Nothing False dc
   let httpReq = initReq { method = "DELETE"}
   liftIO $ withResponse httpReq manager $ \ response -> do
-    _bodyParts <- brConsume $ responseBody response
-    return ()
+    bodyParts <- brConsume $ responseBody response
+    let body = B.concat bodyParts
+    case TE.decodeUtf8 body of
+      "true" -> return True
+      "false" -> return False
+      _ -> return False
 
 {- Agent -}
 {-getHealthChecks :: MonadIO m => Manager -> Text -> PortNumber -> Maybe 
Datacenter -> m [Check]
@@ -289,8 +307,8 @@
       x | x == status200 -> return True
       _ -> return False
 
-getSessionInfo :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe 
Datacenter -> m (Maybe [SessionInfo])
-getSessionInfo manager hostname portNumber session dc = do
+getSessionInfo :: MonadIO m => Manager -> Text -> PortNumber -> Session -> 
Maybe Datacenter -> m (Maybe [SessionInfo])
+getSessionInfo manager hostname portNumber (Session session _) dc = do
   req <- createRequest hostname portNumber (T.concat 
["/v1/session/info/",session]) Nothing Nothing False dc
   liftIO $ withResponse req manager $ \ response -> do
     case responseStatus response of
@@ -317,3 +335,16 @@
   liftIO $ withResponse req manager $ \ response -> do
     bodyParts <- brConsume $ responseBody response
     return $ decode $ BL.fromStrict $ B.concat bodyParts
+
+getServices :: MonadIO m => Manager -> Text -> PortNumber -> Maybe Text -> 
Maybe Datacenter -> m [Text]
+getServices manager hostname portNumber tag dc = do
+    req <- createRequest hostname portNumber "/v1/catalog/services" Nothing 
Nothing False dc
+    liftIO $ withResponse req manager $ \ response -> do
+        bodyParts <- brConsume $ responseBody response
+        return $ parseServices tag $ decode $ BL.fromStrict $ B.concat 
bodyParts
+  where
+    parseServices t (Just (Object v)) = filterTags t $ H.toList v
+    parseServices _   _               = []
+    filterTags :: Maybe Text -> [(Text, Value)] -> [Text]
+    filterTags (Just t)               = map fst . filter (\ (_, (Array v)) -> 
(String t) `V.elem` v)
+    filterTags Nothing                = map fst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/consul-haskell-0.3/src/Network/Consul/Types.hs 
new/consul-haskell-0.4.2/src/Network/Consul/Types.hs
--- old/consul-haskell-0.3/src/Network/Consul/Types.hs  2015-10-13 
06:37:32.000000000 +0200
+++ new/consul-haskell-0.4.2/src/Network/Consul/Types.hs        2017-01-25 
17:41:15.000000000 +0100
@@ -292,10 +292,6 @@
 instance ToJSON SessionRequest where
   toJSON (SessionRequest lockDelay name node checks behavior ttl) = 
object["LockDelay" .= lockDelay, "Name" .= name, "Node" .= (fmap nNode node), 
"Checks" .= checks, "Behavior" .= behavior, "TTL" .= ttl]
 
-instance ToJSON (Either (Text,Text) Text) where
-  toJSON (Left (script,interval)) = object ["Script" .= script, "Interval" .= 
interval]
-  toJSON (Right ttl) = object ["TTL" .= ttl]
-
 instance ToJSON ServiceResult where
   toJSON (ServiceResult node addr sid sName sTags sAddress sPort) = 
object["Node" .= node, "Address" .= addr, "ServiceID" .= sid, "ServiceName" .= 
sName, "ServiceTags" .= sTags, "ServiceAddress" .= sAddress, "ServicePort" .= 
sPort]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/consul-haskell-0.3/src/Network/Consul.hs 
new/consul-haskell-0.4.2/src/Network/Consul.hs
--- old/consul-haskell-0.3/src/Network/Consul.hs        2015-09-30 
18:33:32.000000000 +0200
+++ new/consul-haskell-0.4.2/src/Network/Consul.hs      2017-01-10 
18:54:42.000000000 +0100
@@ -4,13 +4,15 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module Network.Consul (
-    createManagedSession
+    createSession
   , deleteKey
-  , destroyManagedSession
+  , destroySession
+  , deregisterService
   , getKey
   , getKeys
   , getSelf
   , getService
+  , getServices
   , getServiceHealth
   , getSessionInfo
   , getSequencerForLock
@@ -18,26 +20,27 @@
   , initializeTlsConsulClient
   , isValidSequencer
   , listKeys
-  , ManagedSession (..)
   , passHealthCheck
   , putKey
   , putKeyAcquireLock
   , putKeyReleaseLock
   , registerService
+  , renewSession
   , runService
-  , withManagedSession
-  , withSequencer
   , withSession
   , module Network.Consul.Types
 ) where
 
 import Control.Concurrent hiding (killThread)
 import Control.Concurrent.Async.Lifted
-import Control.Concurrent.Lifted (fork, killThread)
 import Control.Concurrent.STM
 import Control.Exception.Lifted
+import Control.Monad (forever)
 import Control.Monad.IO.Class
+import Control.Monad.Catch (MonadMask)
 import Control.Monad.Trans.Control
+import Control.Retry
+import Data.Monoid ((<>))
 import Data.Text (Text)
 import qualified Data.Text as T
 import qualified Data.Text.Read as TR
@@ -88,7 +91,7 @@
 putKeyReleaseLock :: MonadIO m => ConsulClient -> KeyValuePut -> Session -> 
Maybe Datacenter -> m Bool
 putKeyReleaseLock _client@ConsulClient{..} = I.putKeyReleaseLock ccManager 
(I.hostWithScheme _client) ccPort
 
-deleteKey :: MonadIO m => ConsulClient -> Text -> Bool -> Maybe Datacenter -> 
m ()
+deleteKey :: MonadIO m => ConsulClient -> Text -> Bool -> Maybe Datacenter -> 
m Bool
 deleteKey _client@ConsulClient{..} key = I.deleteKey ccManager 
(I.hostWithScheme _client) ccPort key
 
 {- Health Checks -}
@@ -102,10 +105,16 @@
 getService :: MonadIO m => ConsulClient -> Text -> Maybe Text -> Maybe 
Datacenter -> m (Maybe [ServiceResult])
 getService _client@ConsulClient{..} = I.getService ccManager (I.hostWithScheme 
_client) ccPort
 
+getServices :: MonadIO m => ConsulClient -> Maybe Text -> Maybe Datacenter -> 
m [Text]
+getServices _client@ConsulClient{..} = I.getServices ccManager 
(I.hostWithScheme _client) ccPort
+
 {- Agent -}
 getSelf :: MonadIO m => ConsulClient -> m (Maybe Self)
 getSelf _client@ConsulClient{..} = I.getSelf ccManager (I.hostWithScheme 
_client) ccPort
 
+deregisterService :: MonadIO m => ConsulClient -> Text -> m ()
+deregisterService _client@ConsulClient{..} = I.deregisterService ccManager 
(I.hostWithScheme _client) ccPort
+
 registerService :: MonadIO m => ConsulClient -> RegisterService -> Maybe 
Datacenter -> m Bool
 registerService _client@ConsulClient{..} = I.registerService ccManager 
(I.hostWithScheme _client) ccPort
 
@@ -115,61 +124,52 @@
   case r of
     True -> do
       mainFunc <- async action
+
+      --this is here instead of the where to prevent typechecking nastiness
       checkAction <- case rsCheck request of
                       Just(x@(Ttl _)) -> do
-                        a <- async $ ttlFunc x
+                        a <- async $ forever $ ttlFunc x
                         return $ Just a
                       _ -> return Nothing
-      _foo :: () <- wait mainFunc
+
+      _foo :: () <- wait mainFunc --prevent: 'StM’ is a type function, and may 
not be injective
       case checkAction of
         Just a -> cancel a
         Nothing -> return ()
     False -> return ()
   where
     ttlFunc y@(Ttl x) = do
-      (do
-        let ttl = parseTtl x
-        liftIO $ threadDelay $ (ttl - (fromIntegral $ floor (fromIntegral ttl 
/ fromIntegral 2))) * 1000000
-        let checkId = T.concat["service:",maybe (rsName request) id (rsId 
request)]
-        passHealthCheck client checkId dc) `catch` (\ e -> do
-           let _x :: SomeException = e
-           return ())
-      ttlFunc y
+      let ttl = parseTtl x
+      liftIO $ threadDelay $ (ttl - (fromIntegral $ floor (fromIntegral ttl / 
fromIntegral 2))) * 1000000
+      let checkId = T.concat["service:",maybe (rsName request) id (rsId 
request)]
+      passHealthCheck client checkId dc
 
 {- Session -}
-getSessionInfo :: MonadIO m => ConsulClient -> Text -> Maybe Datacenter -> m 
(Maybe [SessionInfo])
-getSessionInfo _client@ConsulClient{..} = I.getSessionInfo ccManager 
(I.hostWithScheme _client) ccPort
+createSession :: MonadIO m => ConsulClient -> SessionRequest -> Maybe 
Datacenter -> m (Maybe Session)
+createSession client@ConsulClient{..} = I.createSession ccManager 
(I.hostWithScheme client) ccPort
+
+destroySession :: MonadIO m => ConsulClient -> Session -> Maybe Datacenter ->  
m ()
+destroySession client@ConsulClient{..} = I.destroySession ccManager 
(I.hostWithScheme client) ccPort
+
+renewSession :: MonadIO m => ConsulClient -> Session -> Maybe Datacenter ->  m 
Bool
+renewSession client@ConsulClient{..} = I.renewSession ccManager 
(I.hostWithScheme client) ccPort
 
-withSession :: forall a m. (MonadIO m,MonadBaseControl IO m) => ConsulClient 
-> Session -> (Session -> m a) -> m a -> m a
-withSession client session action lostAction = do
-  var <- liftIO $ newEmptyTMVarIO
-  tidVar <- liftIO $ newEmptyTMVarIO
-  stid <- fork $ runThread var tidVar
-  tid <- fork $ action session >>= \ x -> liftIO $ atomically $ putTMVar var x
-  liftIO $ atomically $ putTMVar tidVar tid
-  ret <- liftIO $ atomically $ takeTMVar var
-  killThread stid
-  return ret
+getSessionInfo :: MonadIO m => ConsulClient -> Session -> Maybe Datacenter ->  
m (Maybe [SessionInfo])
+getSessionInfo client@ConsulClient{..} = I.getSessionInfo ccManager 
(I.hostWithScheme client) ccPort
+
+withSession :: forall m a. (MonadBaseControl IO m, MonadIO m, MonadMask m) => 
ConsulClient -> Maybe Text -> Int -> Session -> (Session -> m a) -> m a -> m a
+withSession client@ConsulClient{..} name delay session action lostAction = (do
+  withAsync (action session) $ \ mainAsync -> withAsync extendSession $ \ 
extendAsync -> do
+    result :: a <- return . snd =<< waitAnyCancel [mainAsync,extendAsync]
+    return result) `finally` (destroySession client session Nothing)
   where
-    runThread :: TMVar a -> TMVar ThreadId -> m ()
-    runThread var threadVar = do
-      liftIO $ threadDelay (10 * 1000000)
-      x <- getSessionInfo client (sId session) Nothing
+    extendSession :: m a
+    extendSession = do
+      liftIO $ threadDelay $ (delay * 1000000)
+      x <- renewSession client session Nothing
       case x of
-        Just [] -> cancelAction var threadVar
-        Nothing -> cancelAction var threadVar
-        Just _ -> runThread var threadVar
-
-    cancelAction :: TMVar a -> TMVar ThreadId -> m ()
-    cancelAction resultVar tidVar = do
-      tid <- liftIO $ atomically $ readTMVar tidVar
-      killThread tid
-      empty <- liftIO $ atomically $ isEmptyTMVar resultVar
-      if empty then do
-        result <- lostAction
-        liftIO $ atomically $ putTMVar resultVar result
-        return ()
-        else return ()
+        True -> extendSession
+        False -> lostAction
 
 getSequencerForLock :: MonadIO m => ConsulClient -> Text -> Session -> Maybe 
Datacenter -> m (Maybe Sequencer)
 getSequencerForLock client key session datacenter = do
@@ -187,54 +187,14 @@
     Just kv -> return $ (maybe False ((sId $ sSession sequencer) ==) $ 
kvSession kv) && (kvLockIndex kv) == (sLockIndex sequencer)
     Nothing -> return False
 
-withSequencer :: (MonadBaseControl IO m, MonadIO m) => ConsulClient -> 
Sequencer -> m a -> m a -> Int -> Maybe Datacenter -> m a
-withSequencer client sequencer action lostAction delay dc = do
-  mainFunc <- async action
-  pulseFunc <- async pulseLock
-  waitAny [mainFunc, pulseFunc] >>= return . snd
+withSequencer :: (MonadBaseControl IO m, MonadIO m, MonadMask m) => 
ConsulClient -> Sequencer -> m a -> m a -> Int -> Maybe Datacenter -> m a
+withSequencer client sequencer action lostAction delay dc =
+  withAsync action $ \ mainAsync -> withAsync pulseLock $ \ pulseAsync -> do
+    waitAnyCancel [mainAsync, pulseAsync] >>= return . snd
   where
-    pulseLock = do
+    pulseLock = recoverAll (exponentialBackoff 50000 <>  limitRetries 5) $ \ _ 
-> do
       liftIO $ threadDelay delay
       valid <- isValidSequencer client sequencer dc
       case valid of
         True -> pulseLock
         False -> lostAction
-
-{- Helper Functions -}
-{- ManagedSession is a session with an associated TTL healthcheck so the 
session will be terminated if the client dies. The healthcheck will be 
automatically updated. -}
-data ManagedSession = ManagedSession{
-  msSession :: Session,
-  msThreadId :: ThreadId
-}
-
-withManagedSession :: (MonadBaseControl IO m, MonadIO m) => ConsulClient -> 
Text -> (Session -> m ()) -> m () -> m ()
-withManagedSession client ttl action lostAction = do
-  x <- createManagedSession client Nothing ttl
-  case x of
-    Just s -> withSession client (msSession s) action lostAction >> 
destroyManagedSession client s
-    Nothing -> lostAction
-
-createManagedSession :: MonadIO m => ConsulClient -> Maybe Text -> Text -> m 
(Maybe ManagedSession)
-createManagedSession _client@ConsulClient{..} name ttl = do
-  let r = SessionRequest Nothing name Nothing [] (Just Release) (Just ttl)
-  s <- I.createSession ccManager (I.hostWithScheme _client) ccPort r Nothing
-  mapM f s
-  where
-    f x = do
-      tid <- liftIO $ forkIO $ runThread x
-      return $ ManagedSession x tid
-
-    saneTtl = let Right (x,_) = TR.decimal $ T.filter (/= 's') ttl in x
-
-    runThread :: Session -> IO ()
-    runThread s = do
-      threadDelay $ (saneTtl - (saneTtl - 10)) * 1000000
-      x <- I.renewSession ccManager (I.hostWithScheme _client) ccPort s Nothing
-      case x of
-        True -> runThread s
-        False -> return ()
-
-destroyManagedSession :: MonadIO m => ConsulClient -> ManagedSession -> m ()
-destroyManagedSession _client@ConsulClient{..} (ManagedSession session tid) = 
do
-  liftIO $ killThread tid
-  I.destroySession ccManager (I.hostWithScheme _client) ccPort session Nothing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/consul-haskell-0.3/tests/Main.hs 
new/consul-haskell-0.4.2/tests/Main.hs
--- old/consul-haskell-0.3/tests/Main.hs        2015-10-13 06:17:41.000000000 
+0200
+++ new/consul-haskell-0.4.2/tests/Main.hs      2017-01-10 18:54:42.000000000 
+0100
@@ -1,14 +1,18 @@
-{-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
 import Control.Concurrent
 import Control.Monad.IO.Class
 import Data.Maybe
 import Data.Text (Text)
-import Network.Consul 
(createManagedSession,getSessionInfo,initializeConsulClient,withSession,ConsulClient(..),ManagedSession(..))
+import Data.UUID
+import Network.Consul 
(deleteKey,getKey,getSessionInfo,initializeConsulClient,putKey,withSession,ConsulClient(..),runService,getServiceHealth)
 import Network.Consul.Types
 import qualified Network.Consul.Internal as I
 import Network.HTTP.Client
 import Network.Socket (PortNumber(..))
+import System.Random
 import Test.Tasty
 import Test.Tasty.HUnit
 
@@ -18,7 +22,7 @@
 {- Internal Tests -}
 internalKVTests :: TestTree
 internalKVTests = testGroup "Internal Key Value" [testGetInvalidKey, 
testPutKey,
-  testGetKey,testGetKeys,testListKeys,testDeleteKey,testGetNullValueKey]
+  
testGetKey,testGetKeys,testListKeys,testDeleteKey,testGetNullValueKey,testDeleteRecursive]
 
 testGetInvalidKey :: TestTree
 testGetInvalidKey = testCase "testGetInvalidKey" $ do
@@ -56,7 +60,6 @@
     Just x -> assertEqual "testGetNullValueKey: Incorrect Value" (kvValue x) 
Nothing
     Nothing -> assertFailure "testGetNullValueKey: No value returned"
 
-
 testGetKeys :: TestTree
 testGetKeys = testCase "testGetKeys" $ do
   _client@ConsulClient{..} <- client
@@ -87,9 +90,40 @@
   let put1 = KeyValuePut "/testDeleteKey" "Test" Nothing Nothing
   x1 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put1 Nothing
   assertEqual "testDeleteKey: Write failed" True x1
-  I.deleteKey ccManager (I.hostWithScheme _client) ccPort "/testDeleteKey" 
False Nothing
-  x2 <- I.getKey ccManager (I.hostWithScheme _client) ccPort "/testDeleteKey" 
Nothing Nothing Nothing
-  assertEqual "testDeleteKey: Key was not deleted" Nothing x2
+  x2 <- I.deleteKey ccManager (I.hostWithScheme _client) ccPort 
"/testDeleteKey" False Nothing
+  assertEqual "testDeleteKey: Delete Failed" True x2
+  x3 <- I.getKey ccManager (I.hostWithScheme _client) ccPort "/testDeleteKey" 
Nothing Nothing Nothing
+  assertEqual "testDeleteKey: Key was not deleted" Nothing x3
+
+testDeleteRecursive :: TestTree
+testDeleteRecursive = testCase "testDeleteRecursive" $ do
+  _client@ConsulClient{..} <- client
+  let put1 = KeyValuePut "/testDeleteRecursive/1" "Test" Nothing Nothing
+      put2 = KeyValuePut "/testDeleteRecursive/2" "Test" Nothing Nothing
+  x1 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put1 Nothing
+  assertEqual "testDeleteKey: Write failed" True x1
+  x2 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put2 Nothing
+  assertEqual "testDeleteKey: Write failed" True x2
+  I.deleteKey ccManager (I.hostWithScheme _client) ccPort 
"/testDeleteRecursive/" True Nothing
+  x3 <- I.getKey ccManager (I.hostWithScheme _client) ccPort 
"/testDeleteRecursive/1" Nothing Nothing Nothing
+  assertEqual "testDeleteKey: Key was not deleted" Nothing x3
+
+{- Client KV -}
+clientKVTests :: TestTree
+clientKVTests = testGroup "Client KV Tests" [testDeleteRecursiveClient]
+
+testDeleteRecursiveClient :: TestTree
+testDeleteRecursiveClient = testCase "testDeleteRecursiveClient" $ do
+  c <- client
+  let put1 = KeyValuePut "/testDeleteRecursive/1" "Test" Nothing Nothing
+      put2 = KeyValuePut "/testDeleteRecursive/2" "Test" Nothing Nothing
+  x1 <- putKey c put1 Nothing
+  assertEqual "testDeleteKey: Write failed" True x1
+  x2 <- putKey c put2 Nothing
+  assertEqual "testDeleteKey: Write failed" True x2
+  deleteKey c "/testDeleteRecursive/" True Nothing
+  x3 <- getKey c "/testDeleteRecursive/1" Nothing Nothing Nothing
+  assertEqual "testDeleteKey: Key was not deleted" Nothing x3
 
 {- Agent -}
 testRegisterService :: TestTree
@@ -98,6 +132,10 @@
   let req = RegisterService Nothing "testService" ["test"] Nothing (Just $ Ttl 
"10s")
   val <- I.registerService ccManager (I.hostWithScheme _client) ccPort req 
Nothing
   assertEqual "testRegisterService: Service was not created" val True
+  mService <- I.getService ccManager (I.hostWithScheme _client) ccPort 
"testService" Nothing Nothing
+  case mService of
+    Just _ -> return ()
+    Nothing -> assertFailure "testRegisterService: Service was not found"
 
 testGetSelf :: TestTree
 testGetSelf = testCase "testGetSelf" $ do
@@ -149,7 +187,7 @@
   result <- I.createSession ccManager (I.hostWithScheme _client) ccPort req 
Nothing
   case result of
     Just x -> do
-      x1 <- I.getSessionInfo ccManager (I.hostWithScheme _client) ccPort (sId 
x) Nothing
+      x1 <- I.getSessionInfo ccManager (I.hostWithScheme _client) ccPort x 
Nothing
       case x1 of
         Just _ -> return ()
         Nothing -> assertFailure "testGetSessionInfo: Session Info was not 
returned"
@@ -168,6 +206,16 @@
         False -> assertFailure "testRenewSession: Session was not renewed"
     Nothing -> assertFailure "testRenewSession: No session was created"
 
+testRenewNonexistentSession :: TestTree
+testRenewNonexistentSession = testCase "testRenewNonexistentSession" $ do
+  _client@ConsulClient{..} <- client
+  sessId :: UUID <- randomIO
+  let session = Session (toText sessId) Nothing
+  x <- I.renewSession ccManager (I.hostWithScheme _client) ccPort session 
Nothing
+  case x of
+    True -> assertFailure "testRenewNonexistentSession: Non-existent session 
was renewed"
+    False -> return ()
+
 testDestroySession :: TestTree
 testDestroySession = testCase "testDestroySession" $ do
   _client@ConsulClient{..} <- client
@@ -176,29 +224,26 @@
   case result of
     Just x -> do
       _ <- I.destroySession ccManager (I.hostWithScheme _client) ccPort x 
Nothing
-      x1 <- I.getSessionInfo ccManager (I.hostWithScheme _client) ccPort (sId 
x) Nothing
-      assertEqual "testDestroySession: Session info was returned after 
destruction" Nothing x1
+      x1 <- I.getSessionInfo ccManager (I.hostWithScheme _client) ccPort x 
Nothing
+      assertBool "testDestroySession: Session info was returned after 
destruction" $ (x1 == Nothing) || (x1 == Just [])
     Nothing -> assertFailure "testDestroySession: No session was created"
 
 testInternalSession :: TestTree
-testInternalSession = testGroup "Internal Session Tests" [testCreateSession, 
testGetSessionInfo, testRenewSession, testDestroySession]
+testInternalSession = testGroup "Internal Session Tests" [testCreateSession, 
testGetSessionInfo, testRenewSession, testRenewNonexistentSession, 
testDestroySession]
 
-{- Managed Session -}
-testCreateManagedSession :: TestTree
-testCreateManagedSession = testCase "testCreateManagedSession" $ do
-  client <- initializeConsulClient "localhost" 8500 Nothing
-  x <- createManagedSession client (Just "testCreateManagedSession") "60s"
-  assertEqual "testCreateManagedSession: Session not created" True (isJust x)
 
 testSessionMaintained :: TestTree
 testSessionMaintained = testCase "testSessionMaintained" $ do
-  client <- initializeConsulClient "localhost" 8500 Nothing
-  x <- createManagedSession client (Just "testCreateManagedSession") "10s"
-  assertEqual "testSessionMaintained: Session not created" True (isJust x)
-  let (Just foo) = x
-  threadDelay (12 * 1000000)
-  y <- getSessionInfo client (sId $ msSession foo) Nothing
-  assertEqual "testSessionMaintained: Session not found" True (isJust y)
+  client@ConsulClient{..} <- client
+  let req = SessionRequest Nothing (Just "testSessionMaintained") Nothing 
["serfHealth"] (Just Release) (Just "10s")
+  result <- I.createSession ccManager (I.hostWithScheme client) ccPort req 
Nothing
+  case result of
+    Just session -> do
+      threadDelay (12 * 1000000)
+      y <- getSessionInfo client session Nothing
+      assertEqual "testSessionMaintained: Session not found" True (isJust y)
+    Nothing -> assertFailure "testSessionMaintained: No Session was created"
+
 
 testWithSessionCancel :: TestTree
 testWithSessionCancel = testCase "testWithSessionCancel" $ do
@@ -206,26 +251,53 @@
   let req = SessionRequest Nothing (Just "testWithSessionCancel") Nothing 
["serfHealth"] (Just Release) (Just "10s")
   result <- I.createSession ccManager (I.hostWithScheme client) ccPort req 
Nothing
   case result of
-    Just x -> do
-      x1 <- withSession client x (\ y -> action y client ) cancelAction
+    Just session -> do
+      x1 <- withSession client Nothing 5 session (\ y -> action y client ) 
cancelAction
       assertEqual "testWithSessionCancel: Incorrect value" "Canceled" x1
+      z <- getSessionInfo client session Nothing
+      assertBool "testWithSessionCancel: Session was found" $ (z == Nothing) 
|| (z == Just [])
+
     Nothing -> assertFailure "testWithSessionCancel: No session was created"
   where
+    action :: MonadIO m => Session -> ConsulClient -> m Text
     action x client@ConsulClient{..} = do
       I.destroySession ccManager (I.hostWithScheme client) ccPort x Nothing
-      threadDelay (30 * 1000000)
+      liftIO $ threadDelay (30 * 1000000)
       return ("NotCanceled" :: Text)
+
+    cancelAction :: MonadIO m => m Text
     cancelAction = return ("Canceled" :: Text)
 
 
-managedSessionTests :: TestTree
-managedSessionTests = testGroup "Managed Session Tests" [ 
testCreateManagedSession, testSessionMaintained, testWithSessionCancel]
+testRunServiceTtl :: TestTree
+testRunServiceTtl = testCase "testRunServiceTtl" $ do
+  client@ConsulClient{..} <- initializeConsulClient "localhost" 8500 Nothing
+  let register = RegisterService Nothing "testRunServiceTtl" [] (Just 8000) $ 
Just $ Ttl "10s"
+  runService client register (action client) Nothing
+  where
+    action client = do
+      threadDelay 15000000
+      mHealth <- getServiceHealth client "testRunServiceTtl"
+      case mHealth of
+        Nothing -> assertFailure "testRunServiceTtl: No healthcheck was found"
+        Just [x] -> do
+          let checks = hChecks x
+          mapM_ (testCheck) checks
+    testCheck check = do
+      assertBool "testRunServiceTtl: Check not passing" $ cStatus check == 
Passing
+
+
+sessionWorkflowTests :: TestTree
+sessionWorkflowTests = testGroup "Session Workflow Tests" 
[testWithSessionCancel,testSessionMaintained]
+
+runServiceTests :: TestTree
+runServiceTests = testGroup "Run Service Tests" [testRunServiceTtl]
 
 agentTests :: TestTree
 agentTests = testGroup "Agent Tests" [testGetSelf,testRegisterService]
 
 allTests :: TestTree
-allTests = testGroup "All Tests" [testInternalSession, internalKVTests, 
managedSessionTests, agentTests,testHealth]
+allTests = testGroup "All Tests" [testInternalSession, internalKVTests, 
sessionWorkflowTests, agentTests,testHealth, clientKVTests, runServiceTests]
 
 main :: IO ()
 main = defaultMain allTests


Reply via email to