Skip to content

Commit

Permalink
Merge pull request #413 from input-output-hk/piotr/testing
Browse files Browse the repository at this point in the history
Additional tests checking if files exists when using --database and --state-dir options
  • Loading branch information
KtorZ committed Jun 18, 2019
2 parents 713cef8 + a82d265 commit 43e49aa
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 84 deletions.
28 changes: 27 additions & 1 deletion lib/core/test/integration/Test/Integration/Framework/DSL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module Test.Integration.Framework.DSL
, unsafeRequest

-- * Expectations
, expectCmdStarts
, expectSuccess
, expectError
, expectErrorMessage
Expand Down Expand Up @@ -88,6 +89,8 @@ module Test.Integration.Framework.DSL
import Prelude hiding
( fail )

import Cardano.Launcher
( Command (..), launch )
import Cardano.Wallet.Api.Types
( ApiAddress, ApiT (..), ApiTransaction, ApiWallet )
import Cardano.Wallet.Primitive.AddressDiscovery
Expand All @@ -109,7 +112,7 @@ import Cardano.Wallet.Primitive.Types
import Control.Concurrent
( threadDelay )
import Control.Concurrent.Async
( race )
( async, cancel, race, wait )
import Control.Monad
( forM_, unless, void )
import Control.Monad.Catch
Expand Down Expand Up @@ -169,6 +172,8 @@ import System.Process
, waitForProcess
, withCreateProcess
)
import Test.Hspec
( expectationFailure )
import Test.Hspec.Expectations.Lifted
( shouldBe, shouldContain, shouldNotBe )
import Test.Integration.Faucet
Expand Down Expand Up @@ -387,6 +392,27 @@ expectCliListItemFieldEqual i getter a out
"expectCliListItemFieldEqual: trying to access the #" <> show i <>
" element from a list but there's none! "

---
--- Misc Expectations
---

-- | Expect command does not terminate
-- this may be useful for testing if commands that suppose to act as processes
-- do not terminate (e.g. cardano-wallet server)
expectCmdStarts :: Command -> IO ()
expectCmdStarts cmd = do
handle <- async $ void $ launch [cmd]
let fiveSeconds = 5000000
winner <- race (threadDelay fiveSeconds) (wait handle)
case winner of
Left _ -> do
cancel handle
threadDelay 1000000
Right _ ->
expectationFailure $
( cmdName cmd ) ++ " isn't supposed to terminate. \
\Something went wrong."

--
-- Lenses
--
Expand Down
84 changes: 29 additions & 55 deletions lib/core/test/integration/Test/Integration/Scenario/CLI/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,41 @@ module Test.Integration.Scenario.CLI.Server

import Prelude

import Cardano.Launcher
( Command (..), StdStream (..) )
import System.Directory
( listDirectory, removeDirectory )
import System.Exit
( ExitCode (..) )
( doesFileExist )
import System.IO.Temp
( withSystemTempDirectory )
import System.Process
( CreateProcess (..)
, StdStream (..)
, createProcess
, proc
, terminateProcess
, waitForProcess
, withCreateProcess
)
import Test.Hspec
( Spec, describe, it, shouldContain, shouldReturn )
( SpecWith, describe, it )
import Test.Hspec.Expectations.Lifted
( shouldReturn )
import Test.Integration.Framework.DSL
( Context (..), expectCmdStarts )

import qualified Data.Text.IO as TIO

spec :: Spec
spec :: SpecWith (Context t)
spec = do
describe "Launcher should start the server with a database" $ do
it "should create the database file" $ withTempDir $ \d -> do
launcher d
ls <- listDirectory d
ls `shouldContain` ["wallet.db"]

it "should work with empty state directory" $ withTempDir $ \d -> do
removeDirectory d
launcher d
ls <- listDirectory d
ls `shouldContain` ["wallet.db"]

describe "DaedalusIPC" $ do
it "should reply with the port when asked" $ do
(_, _, _, ph) <-
createProcess (proc "test/integration/js/mock-daedalus.js" [])
waitForProcess ph `shouldReturn` ExitSuccess
describe "SERVER - cardano-wallet serve" $ do
it "SERVER - Can just start cardano-wallet serve" $ \_ -> do
let cardanoWalletServer = Command "stack"
[ "exec", "--", "cardano-wallet", "serve"
] (return ())
Inherit
expectCmdStarts cardanoWalletServer

it "SERVER - Can start cardano-wallet serve --database" $ \_ -> do
withTempDir $ \d -> do
let dbFile = d ++ "/db-file"
let cardanoWalletServer = Command "stack"
[ "exec", "--", "cardano-wallet", "serve"
, "--database", dbFile
] (return ())
Inherit
expectCmdStarts cardanoWalletServer
doesFileExist dbFile `shouldReturn` True
doesFileExist (dbFile ++ "-shm") `shouldReturn` True
doesFileExist (dbFile ++ "-wal") `shouldReturn` True

withTempDir :: (FilePath -> IO a) -> IO a
withTempDir = withSystemTempDirectory "integration-state"

launcher :: FilePath -> IO ()
launcher stateDir = withCreateProcess cmd $ \_ _ (Just stderr) ph -> do
TIO.hGetContents stderr >>= TIO.putStrLn
terminateProcess ph
where
cmd = proc' "cardano-wallet" ["launch", "--state-dir", stateDir]

-- There is a dependency cycle in the packages.
--
-- cardano-wallet-launcher depends on cardano-wallet-http-bridge so that it can
-- import the HttpBridge module.
--
-- This package (cardano-wallet-http-bridge) should have
-- build-tool-depends: cardano-wallet:cardano-wallet-launcher so that it can
-- run launcher in the tests. But that dependency can't be expressed in the
-- cabal file, because otherwise there would be a cycle.
--
-- So one hacky way to work around it is by running programs under "stack exec".
proc' :: FilePath -> [String] -> CreateProcess
proc' cmd args = (proc "stack" (["exec", "--", cmd] ++ args))
{ std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe }
1 change: 1 addition & 0 deletions lib/http-bridge/cardano-wallet-http-bridge.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ test-suite integration
Test.Integration.Scenario.CLI.Transactions
Test.Integration.Scenario.CLI.Wallets
Test.Integration.Scenario.CLI.Port
Test.Integration.Scenario.CLI.Server
Paths_cardano_wallet_http_bridge

benchmark restore
Expand Down
88 changes: 62 additions & 26 deletions lib/http-bridge/test/integration/Cardano/LauncherSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,68 @@ module Cardano.LauncherSpec
import Prelude

import Cardano.Launcher
( Command (..), StdStream (..), launch )
import Control.Concurrent
( threadDelay )
import Control.Concurrent.Async
( async, cancel, race, wait )
import Control.Monad
( void )
( Command (..), StdStream (..) )
import System.Directory
( doesDirectoryExist, doesFileExist, removeDirectory )
import System.Exit
( ExitCode (..) )
import System.IO.Temp
( withSystemTempDirectory )
import System.Process
( createProcess, proc, waitForProcess )
import Test.Hspec
( Spec, describe, expectationFailure, it )
( Spec, describe, it )
import Test.Hspec.Expectations.Lifted
( shouldReturn )
import Test.Integration.Framework.DSL
( expectCmdStarts )

spec :: Spec
spec = describe "cardano-wallet launch" $ do
it "Can start launcher against testnet" $ do
let cardanoWalletLauncher = Command "stack"
[ "exec", "--", "cardano-wallet", "launch"
, "--bridge-port", "8080"
] (return ())
Inherit
handle <- async $ void $ launch [cardanoWalletLauncher]
let fiveSeconds = 5000000
winner <- race (threadDelay fiveSeconds) (wait handle)
case winner of
Left _ -> do
cancel handle
threadDelay 1000000
Right _ ->
expectationFailure
"cardano-wallet launch isn't supposed to terminate. \
\Something went wrong."
spec = do
describe "LAUNCH - cardano-wallet launch" $ do
it "LAUNCH - Can start launcher against testnet" $ withTempDir $ \d -> do
removeDirectory d
let cardanoWalletLauncher = Command "stack"
[ "exec", "--", "cardano-wallet", "launch"
, "--network", "testnet"
] (return ())
Inherit
expectCmdStarts cardanoWalletLauncher
doesDirectoryExist d `shouldReturn` False

it "LAUNCH - Can start launcher with --state-dir" $ withTempDir $ \d -> do
let cardanoWalletLauncher = Command "stack"
[ "exec", "--", "cardano-wallet", "launch"
, "--state-dir", d
] (return ())
Inherit
expectCmdStarts cardanoWalletLauncher
expectStateDirExists d

it "LAUNCH - Can start launcher with --state-dir <emptydir>"
$ withTempDir $ \d -> do
removeDirectory d
let cardanoWalletLauncher = Command "stack"
[ "exec", "--", "cardano-wallet", "launch"
, "--state-dir", d
] (return ())
Inherit
expectCmdStarts cardanoWalletLauncher
expectStateDirExists d

describe "DaedalusIPC" $ do
it "should reply with the port when asked" $ do
(_, _, _, ph) <-
createProcess (proc "test/integration/js/mock-daedalus.js" [])
waitForProcess ph `shouldReturn` ExitSuccess

expectStateDirExists :: FilePath -> IO ()
expectStateDirExists dir = do
doesDirectoryExist dir `shouldReturn` True
doesDirectoryExist (dir ++ "/testnet") `shouldReturn` True
doesFileExist (dir ++ "/wallet.db") `shouldReturn` True
doesFileExist (dir ++ "/wallet.db-shm") `shouldReturn` True
doesFileExist (dir ++ "/wallet.db-wal") `shouldReturn` True

withTempDir :: (FilePath -> IO a) -> IO a
withTempDir = withSystemTempDirectory "integration-state"
3 changes: 1 addition & 2 deletions lib/http-bridge/test/integration/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ main = hspec $ do
describe "Cardano.Wallet.HttpBridge.NetworkSpec" HttpBridge.spec
describe "CLI commands not requiring bridge" $ do
describe "Mnemonics CLI tests" MnemonicsCLI.spec
describe "Server CLI tests" ServerCLI.spec
describe "--port CLI tests" $ do
cardanoWalletServer Nothing
& beforeAll
Expand All @@ -120,7 +119,7 @@ main = hspec $ do
describe "Wallets CLI tests" WalletsCLI.spec
describe "Transactions CLI tests" TransactionsCLI.spec
describe "Addresses CLI tests" AddressesCLI.spec

describe "Server CLI tests" ServerCLI.spec
where
oneSecond :: Int
oneSecond = 1 * 1000 * 1000 -- 1 second in microseconds
Expand Down

0 comments on commit 43e49aa

Please sign in to comment.