Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add watchdog for property tests in cardano-cli-test #1072

Merged
merged 1 commit into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 = 20}
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
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
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
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
Loading