Skip to content

Commit 30cc107

Browse files
yancoutofacebook-github-bot
authored andcommitted
Add snapshot test for 2 wire objects
Summary: This diff adds a way to do snapshot tests in SC, by simply calling a macro. It uses that as an example on two wire objects to show it works. Motivation: - Using snapshot testing in wire object will make it super clear what changes are happening on the wire format, which is useful to prevent breakages. (see quip) - I'm going with approach #3 from proposal, but both #2 and #3 would need snapshot testing. How? - I'm using [insta](https://docs.rs/insta/1.8.0/insta/), a rust crate for snapshot testing. Unfortunately it depends on some cargo-specific stuff that doesn't work with buck, but I was able to get it working without patching the package by bypassing the Cargo dependent stuff. - Insta also provides some cargo exensions on top of it to compare snapshots, which we can't have, so I made it clear on the test errors (see test plan) how to update the snapshots (via flag). Future - On future diffs I'll add a snapshot test for all the wire objects, this just adds to a first few to show it works and set up the plumbing. - Writing objects manually for snapshot tests for **every** wire object would be a large amount of code, and troublesome when adding new (specially big) wire objects. We already have wire objects implementing `Arbitrary`, so I think it should be possible to use this to generate simple snapshot tests on automatically generated objects. (It will need some extra work to make sure they are created consistently.) Reviewed By: markbt Differential Revision: D30958077 fbshipit-source-id: 3d8663e7897e5f6eb4b97c24f47b37ef2f138e5a
1 parent a95661f commit 30cc107

File tree

7 files changed

+96
-1
lines changed

7 files changed

+96
-1
lines changed

eden/scm/lib/edenapi/types/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ bytes = { version = "1.0", features = ["serde"] }
1010
dag-types = { path = "../../dag/dag-types", features = ["for-tests"] }
1111
faster-hex = "0.4"
1212
quickcheck = "1.0"
13-
rand = { version = "0.8", features = ["small_rng"] }
1413
revisionstore_types = { path = "../../revisionstore/types" }
1514
serde = { version = "1.0.126", features = ["derive", "rc"] }
1615
serde_bytes = "0.11"
@@ -20,6 +19,7 @@ thiserror = "1.0.29"
2019
types = { path = "../../types" }
2120

2221
[dev-dependencies]
22+
insta_ext = { path = "../../insta_ext" }
2323
paste = "1.0"
2424
quickcheck_macros = "1.0"
2525
serde_cbor = "0.11"

eden/scm/lib/edenapi/types/src/wire/commit.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,14 @@ mod tests {
994994

995995
use quickcheck::quickcheck;
996996

997+
#[test]
998+
fn test_snapshot() {
999+
insta_ext::assert_json!(WireSnapshotState {});
1000+
insta_ext::assert_json!(WireEphemeralPrepareResponse {
1001+
bubble_id: NonZeroU64::new(12)
1002+
});
1003+
}
1004+
9971005
quickcheck! {
9981006
fn test_roundtrip_serialize_location(v: WireCommitLocation) -> bool {
9991007
check_serialize_roundtrip(v)

eden/scm/lib/insta_ext/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# @generated by autocargo from //eden/scm/lib/insta_ext:insta_ext
2+
[package]
3+
name = "insta_ext"
4+
version = "0.1.0"
5+
edition = "2018"
6+
7+
[dependencies]
8+
insta = "1"

eden/scm/lib/insta_ext/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This crate allows using the insta crate, for snapshot tests, without needing to use Cargo.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
source: commit.rs
3+
expression: "WireEphemeralPrepareResponse{bubble_id: NonZeroU64::new(12),}"
4+
5+
---
6+
{"1":12}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
source: commit.rs
3+
expression: "WireSnapshotState{}"
4+
5+
---
6+
{}

eden/scm/lib/insta_ext/src/lib.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This software may be used and distributed according to the terms of the
5+
* GNU General Public License version 2.
6+
*/
7+
8+
pub fn setup() {
9+
const WORKSPACE: &str = "INSTA_WORKSPACE_ROOT";
10+
const UPDATE: &str = "INSTA_UPDATE";
11+
if std::env::var(WORKSPACE).is_err() {
12+
let mut root = std::path::PathBuf::from(file!());
13+
root.pop();
14+
root.pop();
15+
std::env::set_var(WORKSPACE, root);
16+
}
17+
if std::env::var(UPDATE).is_err() {
18+
std::env::set_var(UPDATE, "no");
19+
}
20+
}
21+
22+
pub fn run(is_cargo: bool, snapshot: &str, file: &str, module: &str, line: u32, expr: &str) {
23+
let command = if is_cargo {
24+
"INSTA_UPDATE=1 cargo test ..."
25+
} else {
26+
"buck test ... -- --env INSTA_UPDATE=1"
27+
};
28+
println!(
29+
"{:=^80}\n",
30+
format!(" Run `{}` to update snapshots ", command)
31+
);
32+
let file_name = std::path::Path::new(file)
33+
.file_name()
34+
.and_then(|p| p.to_str())
35+
.unwrap();
36+
insta::_macro_support::assert_snapshot(
37+
insta::_macro_support::AutoName.into(),
38+
snapshot,
39+
"unused",
40+
// buck builds have a _unittest module suffix which cargo doesn't
41+
// this makes the snapshot location consistent on both
42+
&module.replacen("_unittest", "", 1),
43+
file_name,
44+
line,
45+
expr,
46+
)
47+
.unwrap();
48+
}
49+
50+
/// Assert that the serde json representation of given expression matches the snapshot
51+
/// stored on disk.
52+
#[macro_export]
53+
macro_rules! assert_json {
54+
($value: expr) => {{
55+
$crate::setup();
56+
57+
$crate::run(
58+
option_env!("CARGO_MANIFEST_DIR").is_some(),
59+
&serde_json::to_string(&$value).unwrap(),
60+
file!(),
61+
module_path!(),
62+
line!(),
63+
stringify!($value),
64+
);
65+
}};
66+
}

0 commit comments

Comments
 (0)