Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
check-node-configuration: add tests
  • Loading branch information
smelc committed Oct 30, 2024
commit 38f2ef5a77278379d1ece1bcc447199e21e145df
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ cardano-cli/test/cardano-cli-golden/files/input/example_anchor_data.txt -text
cardano-cli/test/cardano-cli-golden/files/input/example_anchor_data2.txt -text
cardano-cli/test/cardano-cli-test/files/input/example_anchor_data.txt -text
cardano-cli/test/cardano-cli-test/files/input/example_anchor_data2.txt -text
cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.alonzo.spec.json -text
cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.byron.spec.json -text
cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.conway.spec.json -text
cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.shelley.spec.json -text
3 changes: 3 additions & 0 deletions cardano-cli/cardano-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ test-suite cardano-cli-test
type: exitcode-stdio-1.0
build-depends:
aeson,
aeson-pretty,
base16-bytestring,
bech32 >=1.1.0,
bytestring,
Expand All @@ -329,10 +330,12 @@ test-suite cardano-cli-test
text,
time,
transformers,
yaml,

build-tool-depends: tasty-discover:tasty-discover
other-modules:
Test.Cli.AddCostModels
Test.Cli.CheckNodeConfiguration
Test.Cli.CreateCardano
Test.Cli.CreateTestnetData
Test.Cli.DRepMetadata
Expand Down
127 changes: 127 additions & 0 deletions cardano-cli/test/cardano-cli-test/Test/Cli/CheckNodeConfiguration.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Test.Cli.CheckNodeConfiguration where

import Cardano.Api

import Control.Monad (forM_)
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Encode.Pretty as Aeson
import qualified Data.Aeson.Key as Aeson
import qualified Data.Aeson.KeyMap as Aeson
import qualified Data.ByteString.Lazy as LBS
import Data.List (isInfixOf)
import qualified Data.Text as Text
import qualified Data.Yaml as Yaml
import GHC.IO.Exception (ExitCode (..))
import System.FilePath ((</>))

import Test.Cardano.CLI.Util (FileSem, bracketSem, execCardanoCLI, execDetailCardanoCLI,
newFileSem)

import Hedgehog (Property)
import qualified Hedgehog as H
import Hedgehog.Extras (propertyOnce)
import qualified Hedgehog.Extras as H

-- | Semaphore protecting against locked file error, when running properties concurrently.
nodeConfigSem :: FileSem
nodeConfigSem = newFileSem "test/cardano-cli-test/files/input/check-node-configuration/node-config.json"
Copy link
Contributor

@Jimbo4350 Jimbo4350 Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these tests actually run concurrently?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes parallelism happens even within a single file. cc @carbolymer

{-# NOINLINE nodeConfigSem #-}

-- Execute this test with:
-- @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
-- We test that the command doesn't crash, because otherwise
-- execCardanoCLI would fail.
bracketSem nodeConfigSem $ \nodeConfigFile -> do
H.noteM_ $
execCardanoCLI
[ "debug"
, "check-node-configuration"
, "--node-configuration-file"
, nodeConfigFile
]

data FiddleKind
= FiddleByron
| FiddleNonByron
deriving (Bounded, Enum)

-- Execute this test with:
-- @cabal test cardano-cli-test --test-options '-p "/check node configuration failure/"'@
hprop_check_node_configuration_failure :: Property
hprop_check_node_configuration_failure = do
let supplyValues :: [(FilePath, FiddleKind)] =
[ (path, fiddleKind)
| path <-
[ "test/cardano-cli-test/files/input/check-node-configuration/node-config.json"
, "test/cardano-cli-test/files/input/check-node-configuration/node-config.yaml"
]
, fiddleKind <- [minBound .. maxBound]
]

propertyOnce $ forM_ supplyValues $ \(nodeConfigPath, fiddleKind) -> H.moduleWorkspace "tmp" $ \tempDir ->
bracketSem nodeConfigSem $ \_ -> do
let finalInputConfig = tempDir </> "node-config-changed.json"
-- TODO why is that writing to "AlonzoGenesisHash" writes one more 0 than specified here? (and hence the need for this hack)
wrongHash = Text.pack $ replicate (case fiddleKind of FiddleByron -> 65; FiddleNonByron -> 64) '0'

-- Install the genesis files in the sandbox
forM_
[AnyCardanoEra ByronEra, AnyCardanoEra AlonzoEra, AnyCardanoEra ConwayEra, AnyCardanoEra ShelleyEra]
$ \(AnyCardanoEra era) -> do
let filename = Text.unpack $ "genesis." <> Text.toLower (eraToStringKey era) <> ".spec.json"
genesisFile = "test/cardano-cli-test/files/input/check-node-configuration" </> filename
H.copyFile genesisFile (tempDir </> filename)

-- We make a hash value incorrect, and check that
-- check-node-configuration fails.

nodeConfigValue :: Aeson.Value <- Yaml.decodeFileThrow nodeConfigPath
nodeConfigObject :: Aeson.Object <-
case nodeConfigValue of
Aeson.Object obj -> pure obj
_ ->
do
H.note_ "Expected an Object, but got something else"
H.failure

-- We make a hash value incorrect, and check that
-- check-node-configuration finds the mistake.

-- Prepare file with incorrect hash

let fiddledEraKey =
Aeson.fromText $ eraToGenesisHashKey $ case fiddleKind of
FiddleByron -> AnyCardanoEra ByronEra
FiddleNonByron -> AnyCardanoEra AlonzoEra
finalConfigObject =
Aeson.Object $ Aeson.insert fiddledEraKey (Aeson.String wrongHash) nodeConfigObject

-- Write file with incorrect hash
liftIO $ LBS.writeFile finalInputConfig $ Aeson.encodePretty finalConfigObject

(exitCode, _stdout, stderr) <-
H.noteShowM $
execDetailCardanoCLI
[ "debug"
, "check-node-configuration"
, "--node-configuration-file"
, finalInputConfig
]

H.assertWith exitCode (ExitSuccess /=)
H.assertWith stderr ("Wrong genesis hash" `isInfixOf`)

-- | The JSON key of the genesis hash for the given era.
eraToGenesisHashKey :: AnyCardanoEra -> Text.Text
eraToGenesisHashKey (AnyCardanoEra era) = eraToStringKey era <> "GenesisHash"

-- | Part of the JSON keys associated with the given era. For example,
-- @eraToStringKey ByronEra@ returns @"Byron"@.
eraToStringKey :: CardanoEra a -> Text.Text
eraToStringKey = docToText . pretty
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
{
"lovelacePerUTxOWord": 34482,
"executionPrices": {
"prSteps": {
"numerator": 721,
"denominator": 10000000
},
"prMem": {
"numerator": 577,
"denominator": 10000
}
},
"maxTxExUnits": {
"exUnitsMem": 10000000,
"exUnitsSteps": 10000000000
},
"maxBlockExUnits": {
"exUnitsMem": 50000000,
"exUnitsSteps": 40000000000
},
"maxValueSize": 5000,
"collateralPercentage": 150,
"maxCollateralInputs": 3,
"costModels": {
"PlutusV1": {
"sha2_256-memory-arguments": 4,
"equalsString-cpu-arguments-constant": 1000,
"cekDelayCost-exBudgetMemory": 100,
"lessThanEqualsByteString-cpu-arguments-intercept": 103599,
"divideInteger-memory-arguments-minimum": 1,
"appendByteString-cpu-arguments-slope": 621,
"blake2b-cpu-arguments-slope": 29175,
"iData-cpu-arguments": 150000,
"encodeUtf8-cpu-arguments-slope": 1000,
"unBData-cpu-arguments": 150000,
"multiplyInteger-cpu-arguments-intercept": 61516,
"cekConstCost-exBudgetMemory": 100,
"nullList-cpu-arguments": 150000,
"equalsString-cpu-arguments-intercept": 150000,
"trace-cpu-arguments": 150000,
"mkNilData-memory-arguments": 32,
"lengthOfByteString-cpu-arguments": 150000,
"cekBuiltinCost-exBudgetCPU": 29773,
"bData-cpu-arguments": 150000,
"subtractInteger-cpu-arguments-slope": 0,
"unIData-cpu-arguments": 150000,
"consByteString-memory-arguments-intercept": 0,
"divideInteger-memory-arguments-slope": 1,
"divideInteger-cpu-arguments-model-arguments-slope": 118,
"listData-cpu-arguments": 150000,
"headList-cpu-arguments": 150000,
"chooseData-memory-arguments": 32,
"equalsInteger-cpu-arguments-intercept": 136542,
"sha3_256-cpu-arguments-slope": 82363,
"sliceByteString-cpu-arguments-slope": 5000,
"unMapData-cpu-arguments": 150000,
"lessThanInteger-cpu-arguments-intercept": 179690,
"mkCons-cpu-arguments": 150000,
"appendString-memory-arguments-intercept": 0,
"modInteger-cpu-arguments-model-arguments-slope": 118,
"ifThenElse-cpu-arguments": 1,
"mkNilPairData-cpu-arguments": 150000,
"lessThanEqualsInteger-cpu-arguments-intercept": 145276,
"addInteger-memory-arguments-slope": 1,
"chooseList-memory-arguments": 32,
"constrData-memory-arguments": 32,
"decodeUtf8-cpu-arguments-intercept": 150000,
"equalsData-memory-arguments": 1,
"subtractInteger-memory-arguments-slope": 1,
"appendByteString-memory-arguments-intercept": 0,
"lengthOfByteString-memory-arguments": 4,
"headList-memory-arguments": 32,
"listData-memory-arguments": 32,
"consByteString-cpu-arguments-intercept": 150000,
"unIData-memory-arguments": 32,
"remainderInteger-memory-arguments-minimum": 1,
"bData-memory-arguments": 32,
"lessThanByteString-cpu-arguments-slope": 248,
"encodeUtf8-memory-arguments-intercept": 0,
"cekStartupCost-exBudgetCPU": 100,
"multiplyInteger-memory-arguments-intercept": 0,
"unListData-memory-arguments": 32,
"remainderInteger-cpu-arguments-model-arguments-slope": 118,
"cekVarCost-exBudgetCPU": 29773,
"remainderInteger-memory-arguments-slope": 1,
"cekForceCost-exBudgetCPU": 29773,
"sha2_256-cpu-arguments-slope": 29175,
"equalsInteger-memory-arguments": 1,
"indexByteString-memory-arguments": 1,
"addInteger-memory-arguments-intercept": 1,
"chooseUnit-cpu-arguments": 150000,
"sndPair-cpu-arguments": 150000,
"cekLamCost-exBudgetCPU": 29773,
"fstPair-cpu-arguments": 150000,
"quotientInteger-memory-arguments-minimum": 1,
"decodeUtf8-cpu-arguments-slope": 1000,
"lessThanInteger-memory-arguments": 1,
"lessThanEqualsInteger-cpu-arguments-slope": 1366,
"fstPair-memory-arguments": 32,
"modInteger-memory-arguments-intercept": 0,
"unConstrData-cpu-arguments": 150000,
"lessThanEqualsInteger-memory-arguments": 1,
"chooseUnit-memory-arguments": 32,
"sndPair-memory-arguments": 32,
"addInteger-cpu-arguments-intercept": 197209,
"decodeUtf8-memory-arguments-slope": 8,
"equalsData-cpu-arguments-intercept": 150000,
"mapData-cpu-arguments": 150000,
"mkPairData-cpu-arguments": 150000,
"quotientInteger-cpu-arguments-constant": 148000,
"consByteString-memory-arguments-slope": 1,
"cekVarCost-exBudgetMemory": 100,
"indexByteString-cpu-arguments": 150000,
"unListData-cpu-arguments": 150000,
"equalsInteger-cpu-arguments-slope": 1326,
"cekStartupCost-exBudgetMemory": 100,
"subtractInteger-cpu-arguments-intercept": 197209,
"divideInteger-cpu-arguments-model-arguments-intercept": 425507,
"divideInteger-memory-arguments-intercept": 0,
"cekForceCost-exBudgetMemory": 100,
"blake2b-cpu-arguments-intercept": 2477736,
"remainderInteger-cpu-arguments-constant": 148000,
"tailList-cpu-arguments": 150000,
"encodeUtf8-cpu-arguments-intercept": 150000,
"equalsString-cpu-arguments-slope": 1000,
"lessThanByteString-memory-arguments": 1,
"multiplyInteger-cpu-arguments-slope": 11218,
"appendByteString-cpu-arguments-intercept": 396231,
"lessThanEqualsByteString-cpu-arguments-slope": 248,
"modInteger-memory-arguments-slope": 1,
"addInteger-cpu-arguments-slope": 0,
"equalsData-cpu-arguments-slope": 10000,
"decodeUtf8-memory-arguments-intercept": 0,
"chooseList-cpu-arguments": 150000,
"constrData-cpu-arguments": 150000,
"equalsByteString-memory-arguments": 1,
"cekApplyCost-exBudgetCPU": 29773,
"quotientInteger-memory-arguments-slope": 1,
"verifySignature-cpu-arguments-intercept": 3345831,
"unMapData-memory-arguments": 32,
"mkCons-memory-arguments": 32,
"sliceByteString-memory-arguments-slope": 1,
"sha3_256-memory-arguments": 4,
"ifThenElse-memory-arguments": 1,
"mkNilPairData-memory-arguments": 32,
"equalsByteString-cpu-arguments-slope": 247,
"appendString-cpu-arguments-intercept": 150000,
"quotientInteger-cpu-arguments-model-arguments-slope": 118,
"cekApplyCost-exBudgetMemory": 100,
"equalsString-memory-arguments": 1,
"multiplyInteger-memory-arguments-slope": 1,
"cekBuiltinCost-exBudgetMemory": 100,
"remainderInteger-memory-arguments-intercept": 0,
"sha2_256-cpu-arguments-intercept": 2477736,
"remainderInteger-cpu-arguments-model-arguments-intercept": 425507,
"lessThanEqualsByteString-memory-arguments": 1,
"tailList-memory-arguments": 32,
"mkNilData-cpu-arguments": 150000,
"chooseData-cpu-arguments": 150000,
"unBData-memory-arguments": 32,
"blake2b-memory-arguments": 4,
"iData-memory-arguments": 32,
"nullList-memory-arguments": 32,
"cekDelayCost-exBudgetCPU": 29773,
"subtractInteger-memory-arguments-intercept": 1,
"lessThanByteString-cpu-arguments-intercept": 103599,
"consByteString-cpu-arguments-slope": 1000,
"appendByteString-memory-arguments-slope": 1,
"trace-memory-arguments": 32,
"divideInteger-cpu-arguments-constant": 148000,
"cekConstCost-exBudgetCPU": 29773,
"encodeUtf8-memory-arguments-slope": 8,
"quotientInteger-cpu-arguments-model-arguments-intercept": 425507,
"mapData-memory-arguments": 32,
"appendString-cpu-arguments-slope": 1000,
"modInteger-cpu-arguments-constant": 148000,
"verifySignature-cpu-arguments-slope": 1,
"unConstrData-memory-arguments": 32,
"quotientInteger-memory-arguments-intercept": 0,
"equalsByteString-cpu-arguments-constant": 150000,
"sliceByteString-memory-arguments-intercept": 0,
"mkPairData-memory-arguments": 32,
"equalsByteString-cpu-arguments-intercept": 112536,
"appendString-memory-arguments-slope": 1,
"lessThanInteger-cpu-arguments-slope": 497,
"modInteger-cpu-arguments-model-arguments-intercept": 425507,
"modInteger-memory-arguments-minimum": 1,
"sha3_256-cpu-arguments-intercept": 0,
"verifySignature-memory-arguments": 1,
"cekLamCost-exBudgetMemory": 100,
"sliceByteString-cpu-arguments-intercept": 150000
}
}
}
Loading
Loading