Skip to content

Commit bdfd065

Browse files
committed
Fix flaky tests by using retryUntilJustM which should provide more reliable wait
1 parent fbc8187 commit bdfd065

14 files changed

Lines changed: 96 additions & 104 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
### Tests
3+
4+
- Replaced `waitForBlocks 1` followed by immediate assertions with `retryUntilJustM` polling in seven test sites.
5+
The old pattern was flaky on aarch64-linux because `waitForBlocks` only guarantees the block number advanced, not that a submitted transaction was included in that block.
6+
Affected tests: Simple Script Mint, Simple Script CostCalculation, TxReferenceInputDatum (two sites), RegisterDeregisterStakeAddress (two sites), and MultiAssetReturnCollateral.
7+
8+
- Switched all remaining `integrationWorkspace` tests to `integrationRetryWorkspace 2` so that transient failures are retried automatically.
9+
Affected tests: FoldEpochState, Simple Script Mint, DRep Deposits, DRep Activity, Predefined Abstain DRep, PlutusV3 purposes, PlutusV2 two script certs, Collateral With Multiassets, Committee Add New, No Confidence, and Transaction Build Estimate.
10+

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Api/TxReferenceInputDatum.hs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -164,20 +164,18 @@ hprop_tx_refin_datum = integrationRetryWorkspace 2 "api-tx-refin-dat" $ \tempAbs
164164
expectTxSubmissionSuccess =<< submitTx sbe connectionInfo tx
165165

166166
-- wait till transaction gets included in the block
167-
_ <- waitForBlocks epochStateView 1
168-
169-
-- test if it's in UTxO set
170-
utxo1 <- findAllUtxos epochStateView sbe
171-
let txUtxo = Utxo.filterWithKey (\(TxIn txId' _) _ -> txId == txId') utxo1
172-
(length txOuts + 1) === length (toList txUtxo)
167+
txUtxo <- retryUntilJustM epochStateView (WaitForBlocks 5) $ do
168+
utxo1 <- findAllUtxos epochStateView sbe
169+
let txUtxo = Utxo.filterWithKey (\(TxIn txId' _) _ -> txId == txId') utxo1
170+
pure $ txUtxo <$ guard (length (toList txUtxo) == length txOuts + 1)
173171

174172
let chainTxOuts =
175173
reverse
176174
. drop 1
177175
. reverse
178176
. map snd
179177
. toList
180-
$ Utxo.filterWithKey (\(TxIn txId' _) _ -> txId == txId') utxo1
178+
$ Utxo.filterWithKey (\(TxIn txId' _) _ -> txId == txId') txUtxo
181179

182180
-- check that the transaction's outputs are the same as we've submitted them
183181
-- i.e. check the datums
@@ -227,11 +225,10 @@ hprop_tx_refin_datum = integrationRetryWorkspace 2 "api-tx-refin-dat" $ \tempAbs
227225
expectTxSubmissionSuccess =<< submitTx sbe connectionInfo tx
228226

229227
-- wait till transaction gets included in the block
230-
_ <- waitForBlocks epochStateView 1
231-
232-
-- test if the transaction is visible in UTxO set
233-
utxo1 <- findAllUtxos epochStateView sbe
234-
let txUtxo = Utxo.filterWithKey (\(TxIn txId' _) _ -> txId == txId') utxo1
228+
txUtxo <- retryUntilJustM epochStateView (WaitForBlocks 5) $ do
229+
utxo1 <- findAllUtxos epochStateView sbe
230+
let txUtxo = Utxo.filterWithKey (\(TxIn txId' _) _ -> txId == txId') utxo1
231+
pure $ txUtxo <$ guard (not . null $ toList txUtxo)
235232
[toCtxUTxOTxOut txOut] === (snd <$> toList txUtxo)
236233
pure txUtxo
237234

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Plutus/MultiAssetReturnCollateral.hs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
{-# LANGUAGE ScopedTypeVariables #-}
55
{-# LANGUAGE TypeApplications #-}
66

7-
module Cardano.Testnet.Test.Cli.Plutus.MultiAssetReturnCollateral
7+
module Cardano.Testnet.Test.Cli.Plutus.MultiAssetReturnCollateral
88
( hprop_collateral_with_tokens
9-
) where
9+
) where
1010

1111
import Cardano.Api
12+
1213
import Cardano.Testnet
1314

1415
import Prelude
15-
import qualified Data.Aeson as Aeson
16+
1617
import Control.Monad (void)
18+
import qualified Data.Aeson as Aeson
1719
import Data.Default.Class
1820
import qualified Data.Text as T
1921
import System.FilePath ((</>))
@@ -22,7 +24,7 @@ import Testnet.Components.Configuration
2224
import Testnet.Components.Query
2325
import Testnet.Defaults
2426
import Testnet.Process.Run (execCli', mkExecConfig)
25-
import Testnet.Property.Util (integrationWorkspace)
27+
import Testnet.Property.Util (integrationRetryWorkspace)
2628
import Testnet.Types
2729

2830
import Hedgehog (Property)
@@ -31,7 +33,7 @@ import qualified Hedgehog.Extras as H
3133

3234
-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/Collateral With Multiassets/"'@
3335
hprop_collateral_with_tokens :: Property
34-
hprop_collateral_with_tokens = integrationWorkspace "collateral-with-tokens" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
36+
hprop_collateral_with_tokens = integrationRetryWorkspace 2 "collateral-with-tokens" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
3537
conf@Conf { tempAbsPath } <- mkConf tempAbsBasePath'
3638
let tempAbsPath' = unTmpAbsPath tempAbsPath
3739
work <- H.createDirectoryIfMissing $ tempAbsPath' </> "work"
@@ -71,22 +73,22 @@ hprop_collateral_with_tokens = integrationWorkspace "collateral-with-tokens" $ \
7173
]
7274
utxo1 <- findUtxosWithAddress epochStateView sbe $ paymentKeyInfoAddr wallet0
7375

74-
H.noteShow_ utxo1
76+
H.noteShow_ utxo1
7577
-- Create a simple always-succeeds Plutus V3 script
7678
plutusScript <- H.note $ work </> "always-succeeds-script.plutusV3"
7779
H.writeFile plutusScript $ T.unpack plutusV3Script
7880

79-
81+
8082
-- Get the policy ID
8183
mintingPolicyId <- filter (/= '\n') <$>
8284
execCli' execConfig
8385
[ anyEraToString anyEra, "transaction"
8486
, "policyid"
8587
, "--script-file", plutusScript
8688
]
87-
89+
8890
let assetName = "7161636f696e" -- "qacoin" in hex
89-
91+
9092
-- Create a Plutus script address
9193
plutusSpendingScriptAddr <-
9294
execCli' execConfig
@@ -113,7 +115,7 @@ hprop_collateral_with_tokens = integrationWorkspace "collateral-with-tokens" $ \
113115
, "--tx-in-collateral", T.unpack $ renderTxIn txinCollateral
114116
, "--tx-out-return-collateral", adaOnlyCollateralValue
115117
, "--witness-override", show @Int 2
116-
, "--tx-out", collateralToBeValue
118+
, "--tx-out", collateralToBeValue
117119
, "--tx-out", fundPlutusScriptAddrVal
118120
, "--tx-out-datum-hash-value", "0"
119121
, "--mint", mintValue
@@ -144,14 +146,11 @@ hprop_collateral_with_tokens = integrationWorkspace "collateral-with-tokens" $ \
144146

145147
-- STEP 2: Attempt to spend from script with collateral containing tokens
146148
-- This will fail because collateral cannot contain non-ADA tokens
147-
149+
148150
-- Wait for transactions to be processed and find UTxOs
149-
_ <- waitForBlocks epochStateView 1
150-
151-
-- Find the UTxO with tokens at wallet1 (for collateral)
152-
txinCollateralWithTokensM <-
153-
findLargestMultiAssetUtxoWithAddress epochStateView sbe $ T.pack maCollateralAddress
154-
(txinCollateralWithTokens, collateralTxOut) <- H.evalMaybe txinCollateralWithTokensM
151+
(txinCollateralWithTokens, collateralTxOut) <-
152+
retryUntilJustM epochStateView (WaitForBlocks 5) $
153+
findLargestMultiAssetUtxoWithAddress epochStateView sbe $ T.pack maCollateralAddress
155154
H.note_ "Collateral TxOut"
156155
H.noteShow_ collateralTxOut
157156
-- Find the UTxO at the script address
@@ -173,8 +172,8 @@ hprop_collateral_with_tokens = integrationWorkspace "collateral-with-tokens" $ \
173172
, "--out-file", spendScriptUTxOTxBody
174173
]
175174
let prettyTxBodyFile = work </> "spend-script-utxo-tx-body-view.json"
176-
void $ execCli' execConfig ["debug", "transaction", "view", "--tx-body-file", spendScriptUTxOTxBody, "--out-file", prettyTxBodyFile]
177-
175+
void $ execCli' execConfig ["debug", "transaction", "view", "--tx-body-file", spendScriptUTxOTxBody, "--out-file", prettyTxBodyFile]
176+
178177
txBodyPrettyJson :: Aeson.Value <- H.leftFailM . H.readJsonFile $ prettyTxBodyFile
179178
H.note_ "Tx body"
180179
H.noteShowPretty_ txBodyPrettyJson
@@ -186,10 +185,10 @@ hprop_collateral_with_tokens = integrationWorkspace "collateral-with-tokens" $ \
186185
, "--signing-key-file", signingKeyFp $ paymentKeyInfoPair wallet2
187186
, "--out-file", spendScriptUTxOTx
188187
]
189-
188+
190189
let prettyTxFile = work </> "spend-script-utxo-tx-view.json"
191-
void $ execCli' execConfig ["debug", "transaction", "view", "--tx-file", spendScriptUTxOTx, "--out-file", prettyTxFile]
192-
190+
void $ execCli' execConfig ["debug", "transaction", "view", "--tx-file", spendScriptUTxOTx, "--out-file", prettyTxFile]
191+
193192
txPrettyJson :: Aeson.Value <- H.leftFailM . H.readJsonFile $ prettyTxFile
194193
H.noteShowPretty_ txPrettyJson
195194

@@ -198,4 +197,4 @@ hprop_collateral_with_tokens = integrationWorkspace "collateral-with-tokens" $ \
198197
, "--tx-file", spendScriptUTxOTx
199198
]
200199

201-
H.success
200+
H.success

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Plutus/Scripts.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import Testnet.Components.Query
2828
import Testnet.Defaults
2929
import Testnet.Process.Cli.SPO
3030
import Testnet.Process.Run (execCli', execCliAny, mkExecConfig)
31-
import Testnet.Property.Util (integrationWorkspace)
31+
import Testnet.Property.Util (integrationRetryWorkspace)
3232
import Testnet.Types
3333

3434
import Hedgehog (Property)
@@ -46,7 +46,7 @@ import qualified Hedgehog.Extras as H
4646
-- Execute me with:
4747
-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/PlutusV3 purposes/"'@
4848
hprop_plutus_purposes_v3 :: Property
49-
hprop_plutus_purposes_v3 = integrationWorkspace "all-plutus-script-purposes" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
49+
hprop_plutus_purposes_v3 = integrationRetryWorkspace 2 "all-plutus-script-purposes" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
5050
conf@Conf { tempAbsPath } <- mkConf tempAbsBasePath'
5151
let tempAbsPath' = unTmpAbsPath tempAbsPath
5252
work <- H.createDirectoryIfMissing $ tempAbsPath' </> "work"
@@ -196,7 +196,7 @@ hprop_plutus_purposes_v3 = integrationWorkspace "all-plutus-script-purposes" $ \
196196
-- Execute me with:
197197
-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/PlutusV2 transaction with two script certs/"'@
198198
hprop_tx_two_script_certs_v2 :: Property
199-
hprop_tx_two_script_certs_v2 = integrationWorkspace "tx-2-script-certs" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
199+
hprop_tx_two_script_certs_v2 = integrationRetryWorkspace 2 "tx-2-script-certs" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
200200
conf@Conf { tempAbsPath } <- mkConf tempAbsBasePath'
201201
let tempAbsPath' = unTmpAbsPath tempAbsPath
202202
work <- H.createDirectoryIfMissing $ tempAbsPath' </> "work"
@@ -257,8 +257,8 @@ hprop_tx_two_script_certs_v2 = integrationWorkspace "tx-2-script-certs" $ \tempA
257257
let txbody = work </> "two-certs-tx-body"
258258
tx = work </> "two-certs-tx"
259259
txout = mconcat [ utxoAddr, "+", show @Int 2_000_000 ]
260-
261-
s <- execCli' execConfig [anyEraToString anyEra, "transaction", "policyid", "--script-file", plutusScript]
260+
261+
s <- execCli' execConfig [anyEraToString anyEra, "transaction", "policyid", "--script-file", plutusScript]
262262
H.note_ $ "Script hash: " <> s
263263
let txBuildArgs =
264264
[ anyEraToString anyEra, "transaction", "build"

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Scripts/Simple/CostCalculation.hs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,27 @@ import Cardano.Api hiding (Value)
1111
import Cardano.Api.Experimental (Some (Some))
1212
import Cardano.Api.Ledger (EpochInterval (..))
1313
import Cardano.Api.UTxO (difference, size)
14+
1415
import Cardano.Testnet
1516

1617
import Prelude
17-
import Testnet.Types
18-
19-
import Control.Monad (void)
2018

19+
import Control.Monad (guard, void)
2120
import Data.Default.Class (Default (def))
2221
import qualified Data.Text as Text
2322
import System.FilePath ((</>))
2423
import qualified System.Info as SYS
2524

26-
import Testnet.Components.Query (getEpochStateView, getTxIx, waitForBlocks,
27-
watchEpochStateUpdate, findAllUtxos)
28-
import qualified Testnet.Defaults as Defaults
25+
import Testnet.Components.Query (TestnetWaitPeriod (..), findAllUtxos, getEpochStateView,
26+
getTxIx, retryUntilJustM, watchEpochStateUpdate)
27+
import qualified Testnet.Defaults as Defaults
2928
import Testnet.Process.Cli.Transaction (TxOutAddress (..), mkSpendOutputsOnlyTx,
3029
retrieveTransactionId, signTx, submitTx)
3130
import Testnet.Process.Run (execCli', mkExecConfig)
3231
import Testnet.Property.Util (integrationRetryWorkspace)
3332
import Testnet.Start.Types (eraToString)
33+
import Testnet.Types
34+
3435
import Hedgehog (Property)
3536
import qualified Hedgehog as H
3637
import qualified Hedgehog.Extras.Test.Base as H
@@ -60,7 +61,7 @@ hprop_ref_simple_script_mint = integrationRetryWorkspace 2 "ref-simple-script" $
6061
, wallets = wallet0 : wallet1 : _
6162
} <-
6263
createAndRunTestnet options def conf
63-
64+
6465
poolNode1 <- H.headM testnetNodes
6566
poolSprocket1 <- H.noteShow $ nodeSprocket poolNode1
6667
execConfig <- mkExecConfig tempBaseAbsPath poolSprocket1 testnetMagic
@@ -69,7 +70,7 @@ hprop_ref_simple_script_mint = integrationRetryWorkspace 2 "ref-simple-script" $
6970
refScriptSizeWork <- H.createDirectoryIfMissing $ work </> "ref-script-publish"
7071

7172
let utxoVKeyFile2 = verificationKeyFp $ paymentKeyInfoPair wallet1
72-
73+
7374
reqSignerHash <- filter (/= '\n') <$>
7475
execCli' execConfig
7576
[ eraName, "address", "key-hash"
@@ -148,7 +149,7 @@ hprop_ref_simple_script_mint = integrationRetryWorkspace 2 "ref-simple-script" $
148149
-- Attempt to mint from a refernce script
149150
let assetName = "4D696C6C6172436F696E"
150151

151-
152+
152153
simpleMintingPolicyId <- filter (/= '\n') <$>
153154
execCli' execConfig
154155
[ eraName, "transaction"
@@ -186,14 +187,12 @@ hprop_ref_simple_script_mint = integrationRetryWorkspace 2 "ref-simple-script" $
186187
"signed-tx"
187188
unsignedUnlockTx
188189
[Some $ paymentKeyInfoPair wallet1]
189-
190+
190191
utxoPre <- findAllUtxos epochStateView sbe
191192

192193

193194
submitTx execConfig cEra signedUnlockTx
194-
void $ waitForBlocks epochStateView 1
195-
utxoPost <- findAllUtxos epochStateView sbe
196-
197-
let diff = difference utxoPost utxoPre
198-
199-
size diff H.=== 2
195+
void $ retryUntilJustM epochStateView (WaitForBlocks 5) $ do
196+
utxoPost <- findAllUtxos epochStateView sbe
197+
let diff = difference utxoPost utxoPre
198+
pure . guard $ size diff == 2

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Scripts/Simple/Mint.hs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Cardano.Testnet
1919

2020
import Prelude
2121

22-
import Control.Monad (void)
22+
import Control.Monad (guard, void)
2323
import Data.Default.Class
2424
import qualified Data.Text as T
2525
import System.FilePath ((</>))
@@ -29,16 +29,15 @@ import Testnet.Components.Query
2929
import Testnet.Defaults
3030
import Testnet.Process.Cli.SPO
3131
import Testnet.Process.Run (execCli', mkExecConfig)
32-
import Testnet.Property.Util (integrationWorkspace)
32+
import Testnet.Property.Util (integrationRetryWorkspace)
3333
import Testnet.Types
3434

3535
import Hedgehog (Property)
36-
import qualified Hedgehog as H
3736
import qualified Hedgehog.Extras as H
3837

3938
-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/Simple Script.Simple Script Mint/"'@
4039
hprop_simple_script_mint :: Property
41-
hprop_simple_script_mint = integrationWorkspace "simple-script-mint" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
40+
hprop_simple_script_mint = integrationRetryWorkspace 2 "simple-script-mint" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
4241
conf@Conf { tempAbsPath } <- mkConf tempAbsBasePath'
4342
let tempAbsPath' = unTmpAbsPath tempAbsPath
4443
work <- H.createDirectoryIfMissing $ tempAbsPath' </> "work"
@@ -138,10 +137,10 @@ hprop_simple_script_mint = integrationWorkspace "simple-script-mint" $ \tempAbsB
138137

139138
let spendScriptUTxOTxBody = work </> "spend-script-utxo-tx-body"
140139
spendScriptUTxOTx = work </> "spend-script-utxo-tx"
141-
140+
142141
txoutWithSupplementalDatum = mconcat [utxoAddr, "+", show @Int 1_000_000]
143142

144-
-- Mint with a simple script
143+
-- Mint with a simple script
145144
reqSignerHash <- filter (/= '\n') <$>
146145
execCli' execConfig
147146
[ anyEraToString anyEra, "address", "key-hash"
@@ -168,7 +167,7 @@ hprop_simple_script_mint = integrationWorkspace "simple-script-mint" $ \tempAbsB
168167
]
169168

170169
H.note_ plutusScriptTestPolId
171-
170+
172171
let mintValue = mconcat ["5 ", simpleMintingPolicyId, ".", assetName]
173172
txout = mconcat [ utxoAddr, "+", show @Int 2_000_000
174173
, "+", mintValue
@@ -203,9 +202,7 @@ hprop_simple_script_mint = integrationWorkspace "simple-script-mint" $ \tempAbsB
203202
[ "latest", "transaction", "submit"
204203
, "--tx-file", spendScriptUTxOTx
205204
]
206-
void $ waitForBlocks epochStateView 1
207-
utxoPost <- findAllUtxos epochStateView sbe
208-
209-
let diff = difference utxoPost utxoPre
210-
211-
size diff H.=== 3
205+
void $ retryUntilJustM epochStateView (WaitForBlocks 5) $ do
206+
utxoPost <- findAllUtxos epochStateView sbe
207+
let diff = difference utxoPost utxoPre
208+
pure . guard $ size diff == 3

0 commit comments

Comments
 (0)