Skip to content

Commit

Permalink
Add watchdog for property tests
Browse files Browse the repository at this point in the history
  • Loading branch information
carbolymer committed Feb 25, 2025
1 parent 63d001a commit 66d88da
Show file tree
Hide file tree
Showing 26 changed files with 76 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}

Expand All @@ -20,6 +21,7 @@ module Test.Cardano.CLI.Util
, noteTempFile
, redactJsonField
, expectFailure
, watchdogProp
)
where

Expand Down Expand Up @@ -55,7 +57,7 @@ import Hedgehog qualified as H
import Hedgehog.Extras (ExecConfig)
import Hedgehog.Extras qualified as H
import Hedgehog.Extras.Test (ExecConfig (..))
import Hedgehog.Internal.Property (Diff, MonadTest, liftTest, mkTest)
import Hedgehog.Internal.Property (Diff, MonadTest, Property (..), liftTest, mkTest)
import Hedgehog.Internal.Property qualified as H
import Hedgehog.Internal.Show (ValueDiff (ValueSame), mkValue, showPretty, valueDiff)
import Hedgehog.Internal.Source (getCaller)
Expand Down Expand Up @@ -355,3 +357,8 @@ expectFailure prop = GHC.withFrozenCallStack $ do
case res of
Left _ -> pure () -- Property failed so we succeed
_ -> H.failWith Nothing "Expected the test to fail but it passed" -- Property passed but we expected a failure

watchdogProp :: HasCallStack => H.Property -> H.Property
watchdogProp prop@Property{propertyTest} = prop{propertyTest = H.runWithWatchdog_ cfg propertyTest}
where
cfg = H.WatchdogConfig{H.watchdogTimeout = 10}
8 changes: 5 additions & 3 deletions cardano-cli/test/cardano-cli-test/Test/Cli/AddCostModels.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import Cardano.CLI.EraBased.Governance.Actions.Run
import Test.Gen.Cardano.Api.ProtocolParameters
import Test.Gen.Cardano.Api.Typed

import Test.Cardano.CLI.Util (watchdogProp)

import Hedgehog

hprop_roundtrip_Alonzo_addCostModelsToEraBasedProtocolParametersUpdate :: Property
hprop_roundtrip_Alonzo_addCostModelsToEraBasedProtocolParametersUpdate =
property $ do
watchdogProp . property $ do
ppu <- forAll genAlonzoEraBasedProtocolParametersUpdate
cmdl <- forAll genCostModels
tripping
Expand All @@ -30,7 +32,7 @@ hprop_roundtrip_Alonzo_addCostModelsToEraBasedProtocolParametersUpdate =

hprop_roundtrip_Babbage_addCostModelsToEraBasedProtocolParametersUpdate :: Property
hprop_roundtrip_Babbage_addCostModelsToEraBasedProtocolParametersUpdate =
property $ do
watchdogProp . property $ do
ppu <- forAll genBabbageEraBasedProtocolParametersUpdate
cmdl <- forAll genCostModels
tripping
Expand All @@ -44,7 +46,7 @@ hprop_roundtrip_Babbage_addCostModelsToEraBasedProtocolParametersUpdate =

hprop_roundtrip_Conway_addCostModelsToEraBasedProtocolParametersUpdate :: Property
hprop_roundtrip_Conway_addCostModelsToEraBasedProtocolParametersUpdate =
property $ do
watchdogProp . property $ do
ppu <- forAll genConwayEraBasedProtocolParametersUpdate
cmdl <- forAll genCostModels
tripping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import Data.Yaml qualified as Yaml
import GHC.IO.Exception (ExitCode (..))
import System.FilePath ((</>))

import Test.Cardano.CLI.Util (execCardanoCLI, execDetailCardanoCLI)
import Test.Cardano.CLI.Util (execCardanoCLI, execDetailCardanoCLI, watchdogProp)

import Hedgehog (Property)
import Hedgehog qualified as H
Expand All @@ -31,7 +31,7 @@ nodeConfigFile = "test/cardano-cli-test/files/input/check-node-configuration/nod
-- @cabal test cardano-cli-test --test-options '-p "/check node configuration success/"'@
hprop_check_node_configuration_success :: Property
hprop_check_node_configuration_success =
propertyOnce $ do
watchdogProp . propertyOnce $ do
H.noteM_ $
execCardanoCLI
[ "debug"
Expand Down
4 changes: 2 additions & 2 deletions cardano-cli/test/cardano-cli-test/Test/Cli/CreateCardano.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Test.Cli.CreateCardano where
import Control.Monad (void)
import System.FilePath ((</>))

import Test.Cardano.CLI.Util (execCardanoCLI)
import Test.Cardano.CLI.Util (execCardanoCLI, watchdogProp)

import Hedgehog (Property)
import Hedgehog.Extras (moduleWorkspace, propertyOnce)
Expand All @@ -15,7 +15,7 @@ import Hedgehog.Extras qualified as H
-- @cabal test cardano-cli-test --test-options '-p "/create cardano/'@
hprop_create_cardano :: Property
hprop_create_cardano =
propertyOnce $ moduleWorkspace "tmp" $ \tempDir -> do
watchdogProp . propertyOnce $ moduleWorkspace "tmp" $ \tempDir -> do
let outputDir = tempDir </> "out"
eras = ["byron", "shelley", "alonzo", "conway"]
templates =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Test.Cardano.CLI.Util
( assertDirectoryMissing
, execCardanoCLI
, execDetailCardanoCLI
, watchdogProp
)

import Hedgehog (Property, success, (===))
Expand All @@ -31,7 +32,7 @@ import Hedgehog.Extras qualified as H
-- @cabal test cardano-cli-test --test-options '-p "/create testnet data minimal/"'@
hprop_create_testnet_data_minimal :: Property
hprop_create_testnet_data_minimal =
propertyOnce $ moduleWorkspace "tmp" $ \tempDir -> do
watchdogProp . propertyOnce $ moduleWorkspace "tmp" $ \tempDir -> do
let outputDir = tempDir </> "out"

-- We test that the command doesn't crash, because otherwise
Expand Down Expand Up @@ -65,7 +66,7 @@ hprop_create_testnet_data_create_nonegative_supply = do
]
:: [(Int, Int, ExitCode)]

propertyOnce $ forM_ supplyValues $ \(totalSupply, delegatedSupply, expectedExitCode) ->
watchdogProp . propertyOnce $ forM_ supplyValues $ \(totalSupply, delegatedSupply, expectedExitCode) ->
moduleWorkspace "tmp" $ \tempDir -> do
let outputDir = tempDir </> "out"

Expand Down Expand Up @@ -128,7 +129,7 @@ data TestGenesis = TestGenesis
-- @cabal test cardano-cli-test --test-options '-p "/create testnet data transient stake delegators/'@
hprop_create_testnet_data_transient_stake_delegators :: Property
hprop_create_testnet_data_transient_stake_delegators =
propertyOnce $ moduleWorkspace "tmp" $ \tempDir -> do
watchdogProp . propertyOnce $ moduleWorkspace "tmp" $ \tempDir -> do
let outputDir = tempDir </> "out"

void $
Expand Down
6 changes: 3 additions & 3 deletions cardano-cli/test/cardano-cli-test/Test/Cli/DRepMetadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Test.Cardano.CLI.Hash
, serveFilesWhile
, tamperBase16Hash
)
import Test.Cardano.CLI.Util (execCardanoCLIWithEnvVars, expectFailure, propertyOnce)
import Test.Cardano.CLI.Util (execCardanoCLIWithEnvVars, expectFailure, propertyOnce, watchdogProp)

import Hedgehog (Property)
import Hedgehog qualified as H
Expand All @@ -25,7 +25,7 @@ import Hedgehog.Internal.Property (MonadTest)
-- @cabal test cardano-cli-test --test-options '-p "/drep metadata hash url wrong hash fails/"'@
hprop_drep_metadata_hash_url_wrong_hash_fails :: Property
hprop_drep_metadata_hash_url_wrong_hash_fails =
propertyOnce . expectFailure $ do
watchdogProp . propertyOnce . expectFailure $ do
-- We modify the hash slightly so that the hash check fails
alteredHash <- H.evalMaybe $ tamperBase16Hash exampleAnchorDataHash
-- We run the test with the modified hash
Expand All @@ -35,7 +35,7 @@ hprop_drep_metadata_hash_url_wrong_hash_fails =
-- @cabal test cardano-cli-test --test-options '-p "/drep metadata hash url correct hash/"'@
hprop_drep_metadata_hash_url_correct_hash :: Property
hprop_drep_metadata_hash_url_correct_hash =
propertyOnce $ baseDrepMetadataHashUrl exampleAnchorDataHash
watchdogProp . propertyOnce $ baseDrepMetadataHashUrl exampleAnchorDataHash

baseDrepMetadataHashUrl
:: (MonadBaseControl IO m, MonadTest m, MonadIO m, MonadCatch m)
Expand Down
4 changes: 2 additions & 2 deletions cardano-cli/test/cardano-cli-test/Test/Cli/FilePermissions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Cardano.Api.Internal.IO (checkVrfFilePermissions)

import Control.Monad (void)

import Test.Cardano.CLI.Util (execCardanoCLI)
import Test.Cardano.CLI.Util (execCardanoCLI, watchdogProp)

import Hedgehog (Property, success)
import Hedgehog.Extras.Test.Base qualified as H
Expand All @@ -19,7 +19,7 @@ import Hedgehog.Internal.Property (failWith)
-- | This property ensures that the VRF signing key file is created only with owner permissions
hprop_createVRFSigningKeyFilePermissions :: Property
hprop_createVRFSigningKeyFilePermissions =
H.propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
watchdogProp . H.propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
-- Key filepaths
vrfVerKey <- H.noteTempFile tempDir "VRF-verification-key-file"

Expand Down
5 changes: 3 additions & 2 deletions cardano-cli/test/cardano-cli-test/Test/Cli/Governance/Vote.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Test.Cardano.CLI.Util
, expectFailure
, noteInputFile
, propertyOnce
, watchdogProp
)

import Hedgehog (MonadTest, Property)
Expand All @@ -30,7 +31,7 @@ import Hedgehog.Extras qualified as H
-- @cabal test cardano-cli-test --test-options '-p "/governance vote create wrong hash fails/"'@
hprop_governance_vote_create_wrong_hash_fails :: Property
hprop_governance_vote_create_wrong_hash_fails =
propertyOnce . expectFailure . H.moduleWorkspace "tmp" $ \tempDir -> do
watchdogProp . propertyOnce . expectFailure . H.moduleWorkspace "tmp" $ \tempDir -> do
-- We modify the hash slightly so that the hash check fails
alteredHash <- H.evalMaybe $ tamperBase16Hash exampleAnchorDataHash
-- We run the test with the altered
Expand All @@ -42,7 +43,7 @@ hprop_governance_vote_create_wrong_hash_fails =
-- @cabal test cardano-cli-test --test-options '-p "/governance vote create right hash works/"'@
hprop_governance_vote_create_right_hash_works :: Property
hprop_governance_vote_create_right_hash_works =
propertyOnce . H.moduleWorkspace "tmp" $ \tempDir ->
watchdogProp . propertyOnce . H.moduleWorkspace "tmp" $ \tempDir ->
baseGovernanceVoteCreateHashCheck exampleAnchorDataHash tempDir

baseGovernanceVoteCreateHashCheck
Expand Down
12 changes: 6 additions & 6 deletions cardano-cli/test/cardano-cli-test/Test/Cli/Hash.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import Hedgehog.Extras qualified as H
-- @cabal test cardano-cli-test --test-options '-p "/generate anchor data hash from file/"'@
hprop_generate_anchor_data_hash_from_file :: Property
hprop_generate_anchor_data_hash_from_file =
propertyOnce $ do
watchdogProp . propertyOnce $ do
result <-
execCardanoCLI
[ "hash"
Expand All @@ -39,7 +39,7 @@ hprop_generate_anchor_data_hash_from_file =
-- @cabal test cardano-cli-test --test-options '-p "/check anchor data hash from file/"'@
hprop_check_anchor_data_hash_from_file :: Property
hprop_check_anchor_data_hash_from_file =
propertyOnce $ do
watchdogProp . propertyOnce $ do
void $
execCardanoCLI
[ "hash"
Expand All @@ -54,7 +54,7 @@ hprop_check_anchor_data_hash_from_file =
-- @cabal test cardano-cli-test --test-options '-p "/check anchor data hash from file fails/"'@
hprop_check_anchor_data_hash_from_file_fails :: Property
hprop_check_anchor_data_hash_from_file_fails =
propertyOnce $ do
watchdogProp . propertyOnce $ do
(ec, _, _) <-
execDetailCardanoCLI
[ "hash"
Expand All @@ -70,7 +70,7 @@ hprop_check_anchor_data_hash_from_file_fails =
-- @cabal test cardano-cli-test --test-options '-p "/generate anchor data hash from file uri/"'@
hprop_generate_anchor_data_hash_from_file_uri :: Property
hprop_generate_anchor_data_hash_from_file_uri =
propertyOnce $ do
watchdogProp . propertyOnce $ do
cwd <- H.evalIO getCurrentDirectory
posixCwd <- toPOSIX cwd
result <-
Expand Down Expand Up @@ -101,7 +101,7 @@ hprop_generate_anchor_data_hash_from_file_uri =
-- @cabal test cardano-cli-test --test-options '-p "/check anchor data hash from http uri/"'@
hprop_check_anchor_data_hash_from_http_uri :: Property
hprop_check_anchor_data_hash_from_http_uri =
propertyOnce $ do
watchdogProp . propertyOnce $ do
let relativeUrl = ["example", "url", "file.txt"]

-- Create temporary HTTP server with files required by the call to `cardano-cli`
Expand All @@ -123,7 +123,7 @@ hprop_check_anchor_data_hash_from_http_uri =
-- @cabal test cardano-cli-test --test-options '-p "/check anchor data hash from ipfs uri/"'@
hprop_check_anchor_data_hash_from_ipfs_uri :: Property
hprop_check_anchor_data_hash_from_ipfs_uri =
propertyOnce $ do
watchdogProp . propertyOnce $ do
let relativeUrl = ["ipfs", exampleAnchorDataIpfsHash]

-- Create temporary HTTP server with files required by the call to `cardano-cli`
Expand Down
8 changes: 4 additions & 4 deletions cardano-cli/test/cardano-cli-test/Test/Cli/ITN.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ itnSignKey = "ed25519_sk1yhnetcmla9pskrvp5z5ff2v8gkenhmluy736jd6nrxrlxcgn70zsy94
-- | 1. Convert a bech32 ITN key pair to a haskell stake verification key and signing key
-- 2. Derive the haskell verification key from the haskell signing key.
hprop_convertITNKeys :: Property
hprop_convertITNKeys = propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
hprop_convertITNKeys = watchdogProp . propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
-- ITN input file paths
itnVerKeyFp <- noteTempFile tempDir "itnVerKey.key"
itnSignKeyFp <- noteTempFile tempDir "itnSignKey.key"
Expand Down Expand Up @@ -79,7 +79,7 @@ hprop_convertITNKeys = propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do

-- | 1. Convert a bech32 ITN extended signing key to a haskell stake signing key
hprop_convertITNExtendedSigningKey :: Property
hprop_convertITNExtendedSigningKey = propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
hprop_convertITNExtendedSigningKey = watchdogProp . propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
let itnExtendedSignKey =
mconcat
[ "ed25519e_sk1qpcplz38tg4fusw0fkqljzspe9qmj06ldu9lgcve99v4fphuk9a535kwj"
Expand Down Expand Up @@ -113,7 +113,7 @@ hprop_convertITNExtendedSigningKey = propertyOnce . H.moduleWorkspace "tmp" $ \t

-- | 1. Convert a bech32 ITN BIP32 signing key to a haskell stake signing key
hprop_convertITNBIP32SigningKey :: Property
hprop_convertITNBIP32SigningKey = propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
hprop_convertITNBIP32SigningKey = watchdogProp . propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
let itnExtendedSignKey =
mconcat
[ "xprv1spkw5suj39723c40mr55gwh7j3vryjv2zdm4e47xs0deka"
Expand Down Expand Up @@ -150,7 +150,7 @@ hprop_convertITNBIP32SigningKey = propertyOnce . H.moduleWorkspace "tmp" $ \temp
-- | We check our 'decodeBech32' outputs against https://slowli.github.io/bech32-buffer/
-- using 'itnVerKey' & 'itnSignKey' as inputs.
hprop_golden_bech32Decode :: Property
hprop_golden_bech32Decode = propertyOnce $ do
hprop_golden_bech32Decode = watchdogProp . propertyOnce $ do
(vHumReadPart, vDataPart, _) <- H.evalEither $ decodeBech32 itnVerKey
Just vDataPartBase16 <- pure (dataPartToBase16 vDataPart)

Expand Down
6 changes: 4 additions & 2 deletions cardano-cli/test/cardano-cli-test/Test/Cli/Json.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ import Test.Gen.Cardano.Api.Typed
, genVerificationKeyHash
)

import Test.Cardano.CLI.Util (watchdogProp)

import Hedgehog (Gen, Property, forAll, property, tripping)
import Hedgehog.Gen as Gen
import Hedgehog.Range as Range

-- TODO: Move to cardano-api
hprop_json_roundtrip_delegations_and_rewards :: Property
hprop_json_roundtrip_delegations_and_rewards =
property $ do
watchdogProp . property $ do
dAndG <- forAll genDelegationsAndRewards
tripping dAndG encode eitherDecode

Expand Down Expand Up @@ -74,6 +76,6 @@ genKesPeriodInfoOutput =
<*> genWord64

hprop_roundtrip_kes_period_info_output_JSON :: Property
hprop_roundtrip_kes_period_info_output_JSON = property $ do
hprop_roundtrip_kes_period_info_output_JSON = watchdogProp . property $ do
kesPeriodOutput <- forAll genKesPeriodInfoOutput
tripping kesPeriodOutput encode eitherDecode
4 changes: 3 additions & 1 deletion cardano-cli/test/cardano-cli-test/Test/Cli/MonadWarning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import Cardano.CLI.Type.MonadWarning (MonadWarning, reportIssue, runWarningState
import Control.Monad (when)
import Control.Monad.Trans.State (State, runState)

import Test.Cardano.CLI.Util (watchdogProp)

import Hedgehog (Property, property, (===))

hprop_monad_warning :: Property
hprop_monad_warning = property $ do
hprop_monad_warning = watchdogProp . property $ do
(-8, [warning]) === duplicateNumber (-4)
(4, []) === duplicateNumber 2
where
Expand Down
8 changes: 5 additions & 3 deletions cardano-cli/test/cardano-cli-test/Test/Cli/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import Data.Either (isLeft, isRight)
import Data.Word (Word16)
import Text.Parsec qualified as Parsec

import Test.Cardano.CLI.Util (watchdogProp)

import Hedgehog (Gen, Property, assert, property, (===))
import Hedgehog.Extras (assertWith, propertyOnce)
import Hedgehog.Gen qualified as Gen
Expand All @@ -30,7 +32,7 @@ import Hedgehog.Range qualified as Range
-- | Execute me with:
-- @cabal test cardano-cli-test --test-options '-p "/integral reader/"'@
hprop_integral_reader :: Property
hprop_integral_reader = property $ do
hprop_integral_reader = watchdogProp . property $ do
parse @Word "0" === Right 0
parse @Word "42" === Right 42
assertWith (parse @Word "-1") isLeft
Expand All @@ -56,7 +58,7 @@ hprop_integral_reader = property $ do
-- | Execute me with:
-- @cabal test cardano-cli-test --test-options '-p "/integral pair reader positive/"'@
hprop_integral_pair_reader_positive :: Property
hprop_integral_pair_reader_positive = property $ do
hprop_integral_pair_reader_positive = watchdogProp . property $ do
validArbitraryTuple <- forAll $ genNumberTuple (Proxy :: Proxy Word)
assert $ isRight $ parse @Word validArbitraryTuple
where
Expand All @@ -83,7 +85,7 @@ genArbitrarySpace = Gen.string (Range.linear 0 5) (return ' ')
-- | Execute me with:
-- @cabal test cardano-cli-test --test-options '-p "/integral pair reader negative/"'@
hprop_integral_pair_reader_negative :: Property
hprop_integral_pair_reader_negative = propertyOnce $ do
hprop_integral_pair_reader_negative = watchdogProp . propertyOnce $ do
assertWith (parse @Word "(0, 0, 0)") isLeft
assertWith (parse @Word "(-1, 0)") isLeft
assertWith (parse @Word "(18446744073709551616, 0)") isLeft
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Hedgehog.Extras.Test.File qualified as H
-- 2. Check for the existence of the key pair
-- 3. We use the generated verification key to build a shelley payment address.
hprop_buildShelleyPaymentAddress :: Property
hprop_buildShelleyPaymentAddress = propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
hprop_buildShelleyPaymentAddress = watchdogProp . propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
-- Key filepaths
verKey <- noteTempFile tempDir "payment-verification-key-file"
signKey <- noteTempFile tempDir "payment-signing-key-file"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import Hedgehog.Extras.Test.File qualified as H
-- 2. We create a tx body
-- 3. We sign the tx body with the generated payment signing key
hprop_createTransaction :: Property
hprop_createTransaction = propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
hprop_createTransaction = watchdogProp . propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
-- Key filepaths
paymentVerKey <- noteTempFile tempDir "payment-verification-key-file"
paymentSignKey <- noteTempFile tempDir "payment-signing-key-file"
Expand Down
Loading

0 comments on commit 66d88da

Please sign in to comment.