diff --git a/bench/cardano-recon-framework/CHANGELOG.md b/bench/cardano-recon-framework/CHANGELOG.md index 46f13a04553..e5cc1fabf84 100644 --- a/bench/cardano-recon-framework/CHANGELOG.md +++ b/bench/cardano-recon-framework/CHANGELOG.md @@ -1,5 +1,9 @@ # Revision history for cardano-trace-ltl +## 1.1.1 -- April 2026 +* Support atoms that refer to property keys at arbitrary depth +* Set build flag `crash-on-missing-key` to true by default + ## 1.1.0 -- April 2026 * Support configurable timeunits in formulas via a CLI option. diff --git a/bench/cardano-recon-framework/README.md b/bench/cardano-recon-framework/README.md index c6808977f46..66ea4b87dc5 100644 --- a/bench/cardano-recon-framework/README.md +++ b/bench/cardano-recon-framework/README.md @@ -17,8 +17,8 @@ If negative, reports as such and lists the events that have been relevant to the ## CLI Syntax ``` -Usage: cardano-recon FILE --mode --duration INT FILES - [--retention INT] [--trace-dispatcher-cfg FILE] +Usage: cardano-recon FILE --mode --duration INT FILES + [--retention INT] [--trace-dispatcher-cfg FILE] [--context FILE] [--dump-metrics BOOL] [--seek-to-end BOOL] Check formula satisfiability against a log of trace messages @@ -39,5 +39,5 @@ Available options: ## Build flags - _debug_ for enabling verbose tracing of formulas as they evolve (multiple traces per each temporal event). - - _crash_on_missing_key_ for making the application crash if a formula atom is evaluated on an event which is missing + - _crash-on-missing-key_ for making the application crash if a formula atom is evaluated on an event which is missing a key the atom is referencing. diff --git a/bench/cardano-recon-framework/cardano-recon-framework.cabal b/bench/cardano-recon-framework/cardano-recon-framework.cabal index 314d33b5a0c..f20e9998a5d 100644 --- a/bench/cardano-recon-framework/cardano-recon-framework.cabal +++ b/bench/cardano-recon-framework/cardano-recon-framework.cabal @@ -4,7 +4,7 @@ description: Cardano Re(altime) Con(formance) Framework based on Linear T category: Cardano Testing copyright: 2026 Intersect. -version: 1.1.0 +version: 1.1.1 license: Apache-2.0 license-files: LICENSE NOTICE @@ -38,7 +38,7 @@ flag debug flag crash-on-missing-key description: If enabled throw an exception when a formula atom expects a missing key, otherwise evaluate the atom to ⊥. - default: False + default: True manual: True diff --git a/bench/cardano-recon-framework/src/Cardano/ReCon/Trace/Event.hs b/bench/cardano-recon-framework/src/Cardano/ReCon/Trace/Event.hs index dff0880691d..053fb4d5732 100644 --- a/bench/cardano-recon-framework/src/Cardano/ReCon/Trace/Event.hs +++ b/bench/cardano-recon-framework/src/Cardano/ReCon/Trace/Event.hs @@ -1,4 +1,5 @@ {-# OPTIONS_GHC -Wno-orphans #-} +{-# LANGUAGE TypeSynonymInstances #-} module Cardano.ReCon.Trace.Event where import Cardano.Logging.Types.TraceMessage (TraceMessage (..)) @@ -14,28 +15,37 @@ import Data.Map.Strict (Map) import Data.Maybe (isJust) import Data.Text (Text, unpack) -extractIntProps :: Object -> Map VariableIdentifier IntValue -extractIntProps = Map.delete "kind" . Map.mapMaybe f . Map.mapKeysMonotonic toText . KeyMap.toMap - where - f (Number v) = Just (truncate v) - f _ = Nothing +class Extractable a where + extract :: Value -> Maybe a + +instance Extractable IntValue where + extract (Number n) = Just (truncate n) + extract _ = Nothing + +instance Extractable Text where + extract (String s) = Just s + extract _ = Nothing -extractTextProps :: Object -> Map VariableIdentifier Text -extractTextProps = Map.delete "kind" . Map.mapMaybe f . Map.mapKeysMonotonic toText . KeyMap.toMap +extractProps :: Extractable a => Object -> Map VariableIdentifier a +extractProps = Map.delete "kind" . go "" where - f (String v) = Just v - f _ = Nothing + go prefix = Map.foldlWithKey' (\acc k v -> + let key = prefix <> k + in case v of + Object nested -> Map.union acc (go (key <> ".") nested) + _ -> maybe acc (\val -> Map.insert key val acc) (extract v) + ) Map.empty . Map.mapKeysMonotonic toText . KeyMap.toMap instance Event TemporalEvent Text where ofTy (TemporalEvent _ msgs) c = isJust $ find (\msg -> msg.tmsgNS == c) msgs intProps (TemporalEvent _ msgs) c = case find (\msg -> msg.tmsgNS == c) msgs of - Just x -> extractIntProps x.tmsgData + Just x -> extractProps x.tmsgData Nothing -> error ("Not an event of type " <> unpack c) textProps (TemporalEvent _ msgs) c = case find (\msg -> msg.tmsgNS == c) msgs of Just x -> Map.insert "host" x.tmsgHost $ Map.insert "thread" x.tmsgThread $ - extractTextProps x.tmsgData + extractProps x.tmsgData Nothing -> error ("Not an event of type " <> unpack c) beg (TemporalEvent t _) = t