Skip to content

Commit

Permalink
Wallet E2E: start wallet and wait until synced
Browse files Browse the repository at this point in the history
  • Loading branch information
Unisay committed Aug 28, 2023
1 parent db887c2 commit 072c0ae
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 46 deletions.
2 changes: 2 additions & 0 deletions lib/wallet-e2e/cardano-wallet-e2e.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ library
, scientific ^>=0.3.7
, tagged ^>=0.8.7
, temporary-resourcet ^>=0.1.0.1
, time ^>=1.9.3
, timespan ^>=0.4
, typed-process ^>=0.2.11

Expand Down Expand Up @@ -109,6 +110,7 @@ library
Cardano.Wallet.Spec.Network.Node.Cli
Cardano.Wallet.Spec.Network.Preprod
Cardano.Wallet.Spec.Network.Wallet
Cardano.Wallet.Spec.Network.Wallet.Cli
Cardano.Wallet.Spec.Stories.Language
Cardano.Wallet.Spec.Stories.Wallet
Cardano.Wallet.Spec.TimeoutSpec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import qualified Wallet as W
data NodeStatus = NodeIsSynced | NodeIsSyncing | NodeIsNotResponding
deriving stock (Eq, Show)

fromString :: String -> Maybe NodeStatus
fromString "ready" = Just NodeIsSynced
fromString "syncing" = Just NodeIsSyncing
fromString "not_responding" = Just NodeIsNotResponding
fromString _ = Nothing

fromClientResponse
:: W.GetNetworkInformationResponseBody200Sync_progress -> Maybe NodeStatus
fromClientResponse
Expand Down
6 changes: 5 additions & 1 deletion lib/wallet-e2e/src/Cardano/Wallet/Spec/Network/Manual.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ nodeWalletSetup withNetworkConfig = do
withNetworkConfig
NetworkConfig
{ networkConfigWallet =
WalletApi{walletInstanceApiUrl = "http://localhost:8090/v2"}
WalletApi
{ walletInstanceApiUrl = "http://localhost:8090/v2"
, walletInstanceApiHost = "localhost"
, walletInstanceApiPort = 8090
}
}
33 changes: 17 additions & 16 deletions lib/wallet-e2e/src/Cardano/Wallet/Spec/Network/Node.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,8 @@ import Path
import System.Process.Typed
( Process, shell, startProcess, stopProcess )

newtype NodeApi = NodeApi (Path Abs File)

nodeApiSocket :: NodeApi -> Path Abs File
nodeApiSocket (NodeApi socket) = socket

data NodeProcessConfig = NodeProcessConfig
{ nodeDir :: Path Abs Dir
, nodeConfig :: Path Abs File
, nodeTopology :: Path Abs File
, nodeDatabase :: Path Abs Dir
}

newtype NodeInstance = NodeInstance (Process () () ())

start :: NodeProcessConfig -> IO (NodeInstance, NodeApi)
start NodeProcessConfig{..} = do
putTextLn "Starting node"
let nodeSocket = nodeDir </> [relfile|node.sock|]
nodeProcess <-
startProcess . shell
Expand All @@ -48,5 +33,21 @@ start NodeProcessConfig{..} = do

stop :: NodeInstance -> IO ()
stop (NodeInstance process) = do
putTextLn "Stopping node"
stopProcess process

--------------------------------------------------------------------------------
-- Data types ------------------------------------------------------------------

newtype NodeApi = NodeApi (Path Abs File)

nodeApiSocket :: NodeApi -> Path Abs File
nodeApiSocket (NodeApi socket) = socket

data NodeProcessConfig = NodeProcessConfig
{ nodeDir :: Path Abs Dir
, nodeConfig :: Path Abs File
, nodeTopology :: Path Abs File
, nodeDatabase :: Path Abs Dir
}

newtype NodeInstance = NodeInstance (Process () () ())
10 changes: 6 additions & 4 deletions lib/wallet-e2e/src/Cardano/Wallet/Spec/Network/Node/Cli.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ module Cardano.Wallet.Spec.Network.Node.Cli where
import qualified Data.Aeson as Aeson
import qualified Data.String as String

import Cardano.Wallet.Spec.Network.Node
( NodeApi, nodeApiSocket )
import Data.Aeson
( FromJSON, withObject, (.:) )
import Path
( Abs, File, Path, toFilePath )
( toFilePath )
import Prelude hiding
( stderr, stdout )
import System.Process.Typed
Expand Down Expand Up @@ -42,8 +44,8 @@ data CliError
| CliErrorDecode String LByteString
deriving stock (Eq, Show)

queryTip :: Path Abs File -> IO (Either CliError NodeTip)
queryTip nodeSocket = do
queryTip :: NodeApi -> IO (Either CliError NodeTip)
queryTip nodeApi = do
(exitCode, stdout, stderr) <-
readProcess . shell
$ String.unwords
Expand All @@ -53,7 +55,7 @@ queryTip nodeSocket = do
, "--testnet-magic"
, "1"
, "--socket-path"
, toFilePath nodeSocket
, toFilePath (nodeApiSocket nodeApi)
]
case exitCode of
ExitFailure code -> pure $ Left $ CliErrorExitCode code stderr
Expand Down
63 changes: 47 additions & 16 deletions lib/wallet-e2e/src/Cardano/Wallet/Spec/Network/Preprod.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ module Cardano.Wallet.Spec.Network.Preprod
) where

import qualified Cardano.Wallet.Spec.Network.Node as Node
import qualified Cardano.Wallet.Spec.Network.Node.Cli as Cli
import qualified Cardano.Wallet.Spec.Network.Node.Cli as NodeCli
import qualified Cardano.Wallet.Spec.Network.Wallet as Wallet
import qualified Cardano.Wallet.Spec.Network.Wallet.Cli as WalletCli

import Cardano.Wallet.Spec.Data.Network.NodeStatus
( NodeStatus (..) )
import Cardano.Wallet.Spec.Network.Config
( NetworkConfig (..) )
import Cardano.Wallet.Spec.Network.Node
( NodeProcessConfig (..), nodeApiSocket )
( NodeApi, NodeProcessConfig (..) )
import Cardano.Wallet.Spec.Network.Wallet
( WalletProcessConfig (..) )
import Control.Monad.Trans.Resource
( ResIO, allocate, runResourceT )
import Control.Retry
Expand All @@ -23,24 +28,45 @@ import Path.IO

nodeWalletSetup :: Path Abs Dir -> (NetworkConfig -> IO ()) -> IO ()
nodeWalletSetup stateDir withNetworkConfig = runResourceT do
-- Start node
nodeProcessConfig <- makeNodeProcessConfig stateDir
(_nodeReleaseKey, (_nodeInstance, nodeApi)) <-
allocate (Node.start nodeProcessConfig) (Node.stop . fst)
(_walletReleaseKey, (_walletInstance, networkConfigWallet)) <-
allocate Wallet.start (Wallet.stop . fst)

let expectedProgress :: Double = 99.0
policy = capDelay 10_000_000 (fibonacciBackoff 500_000)
_ <- retrying policy (\_rs -> pure . (< expectedProgress)) \_ -> liftIO do
Cli.queryTip (nodeApiSocket nodeApi) >>= \case
-- Start wallet
walletProcessConfig <- makeWalletProcessConfig stateDir nodeApi
(_walletReleaseKey, (_walletInstance, walletApi)) <-
allocate (Wallet.start walletProcessConfig) (Wallet.stop . fst)

-- Wait for the node to sync with the network
let policy = capDelay 10_000_000 (fibonacciBackoff 500_000)

_ <- retrying policy (\_rs -> pure . (< 99.99)) \_ -> liftIO do
NodeCli.queryTip nodeApi >>= \case
Left err ->
0.0 <$ putTextLn ("Waiting for node to start: " <> show err)
Right tip -> do
let progress = Cli.syncProgress tip
let progress = NodeCli.syncProgress tip
progress <$ putTextLn do
"Node sync progress: " <> show progress <> "%"

liftIO $ withNetworkConfig NetworkConfig{..}
-- Wait for the wallet to sync with the node
_ <- retrying policy (\_rs -> pure . (== Just NodeIsSynced)) \_ -> liftIO do
WalletCli.queryNetworkInformation walletApi >>= \case
Left err ->
Nothing
<$ putTextLn ("Waiting for wallet to start: " <> show err)
Right networkInformation -> do
let nodeStatus = WalletCli.nodeStatus networkInformation
Just nodeStatus <$ putTextLn do
"Node status as reported by Wallet: " <> show nodeStatus

liftIO
$ withNetworkConfig
NetworkConfig
{ networkConfigWallet = walletApi
, ..
}

makeNodeProcessConfig :: Path Abs Dir -> ResIO NodeProcessConfig
makeNodeProcessConfig temp = do
Expand All @@ -54,9 +80,14 @@ makeNodeProcessConfig temp = do
, nodeDatabase = nodeDir </> [reldir|db|]
}

{-
temporaryDirectory :: ResIO (Path Abs Dir)
temporaryDirectory = do
temp <- getTempDir
snd <$> allocate (createTempDir temp "cardano-wallet-e2e") removeDirRecur
-}
makeWalletProcessConfig :: Path Abs Dir -> NodeApi -> ResIO WalletProcessConfig
makeWalletProcessConfig temp nodeApi = do
let walletDir = temp </> [reldir|wallet|]
pure
WalletProcessConfig
{ walletDir
, walletDatabase = walletDir </> [reldir|db|]
, walletNodeApi = nodeApi
, walletListenHost = Nothing
, walletListenPort = Nothing
}
51 changes: 42 additions & 9 deletions lib/wallet-e2e/src/Cardano/Wallet/Spec/Network/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,59 @@ module Cardano.Wallet.Spec.Network.Wallet
, stop
, WalletInstance (..)
, WalletApi (..)
, WalletProcessConfig (..)
) where

import Cardano.Wallet.Spec.Network.Node
( NodeApi, nodeApiSocket )
import Path
( Abs, Dir, Path, toFilePath )
import System.Process.Typed
( Process, shell, startProcess, stopProcess )

newtype WalletInstance = WalletInstance (Process () () ())

newtype WalletApi = WalletApi {walletInstanceApiUrl :: Text}
data WalletApi = WalletApi
{ walletInstanceApiUrl :: Text
, walletInstanceApiHost :: Text
, walletInstanceApiPort :: Int
}

start :: IO (WalletInstance, WalletApi)
start = do
putTextLn "Starting wallet"
data WalletProcessConfig = WalletProcessConfig
{ walletDir :: Path Abs Dir
, walletNodeApi :: NodeApi
, walletDatabase :: Path Abs Dir
, walletListenHost :: Maybe Text
, walletListenPort :: Maybe Int
}

start :: WalletProcessConfig -> IO (WalletInstance, WalletApi)
start WalletProcessConfig{..} = do
let host = fromMaybe "localhost" walletListenHost
port = fromMaybe 8090 walletListenPort
let config =
WalletApi
{ walletInstanceApiUrl = "http://localhost:8090/v2"
{ walletInstanceApiUrl =
"http://" <> host <> ":" <> show port <> "/v2"
, walletInstanceApiHost = host
, walletInstanceApiPort = port
}
process <- startProcess $ shell "cardano-wallet version"
process <-
startProcess . shell . fold
$ [ "cardano-wallet"
, "serve"
, "--node-socket"
, toFilePath (nodeApiSocket walletNodeApi)
, "--database"
, ""
, "--listen-address"
, toString host
, "--port"
, show port
, "--log-level"
, "INFO"
]
pure (WalletInstance process, config)

stop :: WalletInstance -> IO ()
stop (WalletInstance process) = do
putTextLn "Stopping wallet"
stopProcess process
stop (WalletInstance process) = stopProcess process
Loading

0 comments on commit 072c0ae

Please sign in to comment.