From 748572046e2ee88c56463d20faa69f493713db14 Mon Sep 17 00:00:00 2001 From: lxl66566 Date: Wed, 25 Sep 2024 22:18:31 +0800 Subject: [PATCH] fix: checker types ser/de panic Signed-off-by: lxl66566 --- assets/check_result.edn | 39 +++++++++++++++++++++ assets/check_result.json | 74 ---------------------------------------- src/checker/elle_rw.rs | 4 +-- src/checker/mod.rs | 40 ++++++++++++++-------- src/clojure/serde.clj | 13 ++++--- 5 files changed, 74 insertions(+), 96 deletions(-) create mode 100644 assets/check_result.edn delete mode 100644 assets/check_result.json diff --git a/assets/check_result.edn b/assets/check_result.edn new file mode 100644 index 0000000..c64675f --- /dev/null +++ b/assets/check_result.edn @@ -0,0 +1,39 @@ +{:valid? false, + :anomaly-types [:G1c], + :anomalies + {:G1c + [{:cycle + [{:process 1, + :type :ok, + :f nil, + :value [[:append :x 2] [:append :y 1]], + :index 1, + :time -1} + {:process 0, + :type :ok, + :f nil, + :value [[:append :x 1] [:r :y [1]]], + :index 0, + :time -1} + {:process 1, + :type :ok, + :f nil, + :value [[:append :x 2] [:append :y 1]], + :index 1, + :time -1}], + :steps + ({:type :wr, :key :y, :value 1, :a-mop-index 1, :b-mop-index 1} + {:type :ww, + :key :x, + :value 1, + :value' 2, + :a-mop-index 0, + :b-mop-index 0}), + :type :G1c}]}, + :not #{:read-committed}, + :also-not + #{:consistent-view :cursor-stability :forward-consistent-view + :monotonic-atomic-view :monotonic-snapshot-read :monotonic-view + :repeatable-read :serializable :snapshot-isolation :strong-serializable + :strong-session-serializable :strong-session-snapshot-isolation + :strong-snapshot-isolation :update-serializable}} \ No newline at end of file diff --git a/assets/check_result.json b/assets/check_result.json deleted file mode 100644 index a2f1820..0000000 --- a/assets/check_result.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "valid?": false, - "anomaly-types": ["G1c"], - "anomalies": { - "G1c": [ - { - "cycle": [ - { - "index": 1, - "time": -1, - "type": "ok", - "process": 1, - "f": null, - "value": [ - ["append", "x", 2], - ["append", "y", 1] - ] - }, - { - "index": 0, - "time": -1, - "type": "ok", - "process": 0, - "f": null, - "value": [ - ["append", "x", 1], - [":r", "y", [1]] - ] - }, - { - "index": 1, - "time": -1, - "type": "ok", - "process": 1, - "f": null, - "value": [ - ["append", "x", 2], - ["append", "y", 1] - ] - } - ], - "steps": [ - { "type": "wr", "key": "y", "value": 1, "a-mop-index": 1, "b-mop-index": 1 }, - { "type": "ww", "key": "x", "value": 1, "value'": 2, "a-mop-index": 0, "b-mop-index": 0 } - ], - "type": "G1c" - } - ] - }, - "not": ["read-committed"], - "also-not": [ - "causal-cerone", - "consistent-view", - "cursor-stability", - "forward-consistent-view", - "monotonic-atomic-view", - "monotonic-snapshot-read", - "monotonic-view", - "parallel-snapshot-isolation", - "prefix", - "read-atomic", - "repeatable-read", - "serializable", - "snapshot-isolation", - "strong-read-committed", - "strong-serializable", - "strong-session-read-committed", - "strong-session-serializable", - "strong-session-snapshot-isolation", - "strong-snapshot-isolation", - "update-atomic", - "update-serializable" - ] -} diff --git a/src/checker/elle_rw.rs b/src/checker/elle_rw.rs index fb35758..e5a2c9a 100644 --- a/src/checker/elle_rw.rs +++ b/src/checker/elle_rw.rs @@ -33,7 +33,7 @@ impl super::Check for ElleRwChecker { with_jvm(|_| { let h = historify(Instance::from_ser(history)?)?; trace!("historify done"); - info!("check with option: {:?}", serde_json::to_string(&option)); + info!("check with option: {:?}", &option); let op_clj = Instance::from_ser(option)?; let res = nsinvoke!(self.ns, "check", op_clj, h)?; trace!("check done"); @@ -60,7 +60,7 @@ mod tests { let res = checker.check( &history, CheckOption::default() - .consistency_models(ConsistencyModel::Serializable) + .consistency_models([ConsistencyModel::Serializable]) .analyzer("wr-graph"), )?; println!("{:#?}", res); diff --git a/src/checker/mod.rs b/src/checker/mod.rs index 6ede890..db3434a 100644 --- a/src/checker/mod.rs +++ b/src/checker/mod.rs @@ -1,5 +1,5 @@ pub mod elle_rw; -use std::path::PathBuf; +use std::{collections::HashSet, path::PathBuf}; use anyhow::Result; use default_struct_builder::DefaultBuilder; @@ -17,14 +17,14 @@ fn default_out_dir() -> PathBuf { pub struct SerializableCheckResult { #[serde(rename = ":valid?")] valid: ValidType, - #[serde(rename = ":anomaly-types")] + #[serde(rename = ":anomaly-types", default)] anomaly_types: Vec, #[serde(rename = ":anomalies")] - anomalies: serde_json::Value, - #[serde(rename = ":not")] - not: Vec, - #[serde(rename = ":also-not")] - also_not: Vec, + anomalies: Option, + #[serde(rename = ":not", default)] + not: HashSet, + #[serde(rename = ":also-not", default)] + also_not: HashSet, } #[serde_with::skip_serializing_none] @@ -33,7 +33,7 @@ pub struct SerializableCheckResult { pub struct CheckOption { #[builder(into)] #[serde(rename = ":consistency-models")] - consistency_models: Option, + consistency_models: Option>, #[serde(default = "default_out_dir")] #[serde(rename = ":directory")] directory: PathBuf, @@ -73,7 +73,7 @@ impl<'de> Deserialize<'de> for ValidType { match value { Value::Bool(b) => Ok(if b { ValidType::True } else { ValidType::False }), Value::String(s) => { - if s == "unknown" { + if s == ":unknown" { Ok(ValidType::Unknown) } else { Err(serde::de::Error::custom("invalid string value")) @@ -92,7 +92,7 @@ impl Serialize for ValidType { match self { ValidType::True => serializer.serialize_bool(true), ValidType::False => serializer.serialize_bool(false), - ValidType::Unknown => serializer.serialize_str("unknown"), + ValidType::Unknown => serializer.serialize_str(":unknown"), } } } @@ -153,11 +153,13 @@ pub trait Check { #[cfg(test)] mod tests { use super::*; + use crate::ffi::{read_edn, ToDe}; #[test] - fn test_deser_from_json_result() -> anyhow::Result<()> { - let json = include_str!("../../assets/check_result.json"); - let _res: SerializableCheckResult = serde_json::from_str(json)?; + fn test_deser_from_json_result_should_be_ok() -> anyhow::Result<()> { + let edn = include_str!("../../assets/check_result.edn"); + let ins = read_edn(edn)?; + let _res: SerializableCheckResult = ins.to_de()?; Ok(()) } @@ -165,11 +167,19 @@ mod tests { fn test_check_option_serialization() { let option = CheckOption::default() .analyzer("wr-graph") - .consistency_models(ConsistencyModel::CursorStability); + .consistency_models([ConsistencyModel::CursorStability]); let json = serde_json::to_string(&option).unwrap(); assert_eq!( - r#"{":consistency-models":":cursor-stability",":directory":"./out",":analyzer":"wr-graph"}"#, + r#"{":consistency-models":[":cursor-stability"],":directory":"./out",":analyzer":"wr-graph"}"#, json ); } + + #[test] + fn test_check_result_deserialization() -> anyhow::Result<()> { + let result = r#"{":valid?":":unknown",":anomaly-types":[":empty-transaction-graph"],":anomalies":{":empty-transaction-graph":true},":not":[],":also-not":[]}"#; + let res: SerializableCheckResult = serde_json::from_str(result)?; + assert!(matches!(res.valid, ValidType::Unknown)); + Ok(()) + } } diff --git a/src/clojure/serde.clj b/src/clojure/serde.clj index e30c421..2b0e7ce 100644 --- a/src/clojure/serde.clj +++ b/src/clojure/serde.clj @@ -11,15 +11,18 @@ x)) data))) + (defn deserialize-with-key-type [json-str] (let [data (json/parse-string json-str)] (walk/postwalk (fn [x] - (if (string? x) - (if (.startsWith x ":") - (keyword (subs x 1)) - x) - x)) + (cond + (string? x) (if (.startsWith x ":") + (keyword (subs x 1)) + x) + (number? x) (long x) ;; if this line not there, it will deserialize to Integer, + ;; that causes problem in history. + :else x)) data))) (defn deserialize-list-to-vec [json-str]