Skip to content

Commit

Permalink
Test cardano-testnet executable
Browse files Browse the repository at this point in the history
  • Loading branch information
smelc committed Feb 26, 2025
1 parent 0844d79 commit b26b198
Show file tree
Hide file tree
Showing 8 changed files with 1,075 additions and 0 deletions.
1 change: 1 addition & 0 deletions cardano-testnet/cardano-testnet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ test-suite cardano-testnet-test
Cardano.Testnet.Test.Gov.TreasuryDonation
Cardano.Testnet.Test.Gov.TreasuryGrowth
Cardano.Testnet.Test.Gov.TreasuryWithdrawal
Cardano.Testnet.Test.CommandLineExecutable
Cardano.Testnet.Test.Misc
Cardano.Testnet.Test.Node.Shutdown
Cardano.Testnet.Test.SanityCheck
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{-# LANGUAGE OverloadedStrings #-}

module Cardano.Testnet.Test.CommandLineExecutable
( hprop_cardano_testnet_executable
) where

import Control.Monad
import Control.Monad.IO.Class (liftIO)
import Data.Aeson (decodeFileStrict', encodeFile, (.=))
import Data.Aeson.Types (Value (Object))
import Data.Maybe (fromJust)
import Data.Time.Clock (addUTCTime, getCurrentTime)
import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds)
import Data.Time.Format (defaultTimeLocale, formatTime)
import System.Directory
import System.Exit (ExitCode (..))
import System.FilePath
import System.IO (hClose, hGetContents)
import System.Process

import Testnet.Property.Util (integrationWorkspace)

import Hedgehog
import qualified Hedgehog as H
import qualified Hedgehog.Extras as H

{- HLINT ignore "Use uncurry" -}

-- | Function to update the @systemStart@ field of the Shelley genesis
-- and return the value set a seconds in Posix time.
updateShelleySystemStart :: Value -> IO (Value, Int)
updateShelleySystemStart (Object obj) = do
currentTime <- getCurrentTime
let futureTime = addUTCTime 15 currentTime
formattedTime = formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%SZ" futureTime
timestamp = round $ utcTimeToPOSIXSeconds futureTime
return (Object (obj <> ("systemStart" .= formattedTime)), timestamp)
updateShelleySystemStart _ = error "Expected a JSON object"

-- Function to update the @startTime@ field of the Byron genesis
updateByronStartTime :: Int -> Value -> Value
updateByronStartTime newStartTime (Object obj) =
Object (obj <> ("startTime" .= newStartTime))
updateByronStartTime _ _ = error "Expected a JSON object"

-- | Test the `cardano-testnet` executable
-- Execute me with:
-- @cabal test cardano-testnet-test --test-options '-p "/cardano-testnet-executable/"'@
hprop_cardano_testnet_executable :: Property
hprop_cardano_testnet_executable = integrationWorkspace "cardano-testnet-executable" $ \tempAbsBasePath -> H.runWithDefaultWatchdog_ $ do
-- Install configuration and genesis files
let referenceInputsFileDir = "test/cardano-testnet-test/files/input/executable"
allFiles = ["configuration.json", "alonzo-genesis.json", "byron-genesis.json", "conway-genesis.json", "shelley-genesis.json"]
liftIO $ forM_ allFiles $ \file -> copyFile (referenceInputsFileDir </> file) (tempAbsBasePath </> file)

-- Amend the start time in the Genesis configuration file
let shelleyGenesisFilePath = tempAbsBasePath </> "shelley-genesis.json"
genesisValue <- liftIO $ fromJust <$> decodeFileStrict' shelleyGenesisFilePath
(updatedShelleyGenesisValue, startTime) <- liftIO $ updateShelleySystemStart genesisValue
liftIO $ encodeFile shelleyGenesisFilePath updatedShelleyGenesisValue

-- Amend the start time in the Byron Genesis configuration file
let byronGenesisFilePath = tempAbsBasePath </> "byron-genesis.json"
byronGenesisValue <- liftIO $ fromJust <$> decodeFileStrict' byronGenesisFilePath
let updatedByronGenesisValue = updateByronStartTime startTime byronGenesisValue
liftIO $ encodeFile byronGenesisFilePath updatedByronGenesisValue

-- Alright, all files are in place, let's start the node:
let cmd = ("cabal", [ "run", "cardano-testnet", "--", "cardano"
, "--node-config", tempAbsBasePath </> "configuration.json"
, "--testnet-magic", "44"])
cmdString = unwords $ fst cmd : snd cmd
(_, Just hout, Just herr, ph) <- liftIO $ createProcess (uncurry proc cmd) { std_out = CreatePipe, std_err = CreatePipe }
exitCode <- liftIO $ waitForProcess ph
stdOut <- liftIO $ hGetContents hout
stdErr <- liftIO $ hGetContents herr
case exitCode of
ExitSuccess ->
H.note_ $ "Command succeeded: " <> cmdString
ExitFailure code -> do
H.note_ $ "Command failed with exit code " ++ show code ++ ": " <> cmdString
unless (null stdOut) $ H.note_ $ "stdout: " <> stdOut
unless (null stdErr) $ H.note_ $ "stderr: " <> stdErr
H.assert False
liftIO $ do
hClose hout
hClose herr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Main
( main
) where


import qualified Cardano.Crypto.Init as Crypto
import qualified Cardano.Testnet.Test.Cli.Conway.Plutus
import qualified Cardano.Testnet.Test.Cli.KesPeriodInfo
Expand All @@ -12,6 +13,7 @@ import qualified Cardano.Testnet.Test.Cli.QuerySlotNumber
import qualified Cardano.Testnet.Test.Cli.StakeSnapshot
import qualified Cardano.Testnet.Test.Cli.Transaction
import qualified Cardano.Testnet.Test.Cli.Transaction.RegisterDeregisterStakeAddress
import qualified Cardano.Testnet.Test.CommandLineExecutable
import qualified Cardano.Testnet.Test.FoldEpochState
import qualified Cardano.Testnet.Test.Gov.CommitteeAddNew as Gov
import qualified Cardano.Testnet.Test.Gov.DRepDeposit as Gov
Expand Down Expand Up @@ -76,6 +78,7 @@ tests = do
]
, T.testGroup "CLI"
[ ignoreOnWindows "Shutdown" Cardano.Testnet.Test.Node.Shutdown.hprop_shutdown
, ignoreOnWindows "cardano-testnet-executable" Cardano.Testnet.Test.CommandLineExecutable.hprop_cardano_testnet_executable
-- ShutdownOnSigint fails on Mac with
-- "Log file: /private/tmp/tmp.JqcjW7sLKS/kes-period-info-2-test-30c2d0d8eb042a37/logs/test-spo.stdout.log had no logs indicating the relevant node has minted blocks."
, ignoreOnMacAndWindows "Shutdown On Sigint" Cardano.Testnet.Test.Node.Shutdown.hprop_shutdownOnSigint
Expand Down
Loading

0 comments on commit b26b198

Please sign in to comment.