Skip to content

Commit

Permalink
Update coverage for error and config
Browse files Browse the repository at this point in the history
Update coverage rate to 80-100% for nativelink-error and nativelink-config
  • Loading branch information
leodziki committed Nov 10, 2024
1 parent 3fbc273 commit 29f7228
Show file tree
Hide file tree
Showing 5 changed files with 652 additions and 18 deletions.
2 changes: 1 addition & 1 deletion nativelink-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
byte-unit = { version = "5.1.4", default-features = false, features = ["byte"] }
humantime = "2.1.0"
serde = { version = "1.0.210", default-features = false }
serde = { version = "1.0.210", default-features = false, features = ["derive"] }
serde_json5 = "0.1.0"
shellexpand = { version = "3.1.0", default-features = false, features = ["base-0"] }

Expand Down
208 changes: 196 additions & 12 deletions nativelink-config/tests/deserialization_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,26 @@

use nativelink_config::serde_utils::{
convert_data_size_with_shellexpand, convert_duration_with_shellexpand,
convert_numeric_with_shellexpand, convert_optional_numeric_with_shellexpand,
convert_optional_string_with_shellexpand, convert_string_with_shellexpand,
convert_vec_string_with_shellexpand,
};
use pretty_assertions::assert_eq;
use serde::Deserialize;

const INVALID_ENV_VAR_ERROR: &str =
"error looking key 'INVALID_ENV_VAR' up: environment variable not found";
const MAP_TYPE_ERROR: &str = "invalid type: map, expected a string containing json data";

const DURATION_HUMAN_READABLE: &str = r#"{"duration": "1m 10s"}"#;
const DURATION_USIZE: &str = r#"{"duration": 10}"#;
const DATA_SIZE_KIB: &str = r#"{"data_size": "1KiB"}"#;
const DATA_SIZE_USIZE: &str = r#"{"data_size": 10}"#;
const STRING_ENV_VAR: &str = r#"{"expanded_string": "$INVALID_ENV_VAR"}"#;
const EMPTY_STRING_ENV_VAR: &str = r#"{"expanded_string": ""}"#;
const NULL_STRING_ENV_VAR: &str = r#"{"expanded_string": null}"#;
const VEC_STRING_EMPTY: &str = r#"{"expanded_strings": []}"#;

#[derive(Deserialize)]
struct DurationEntity {
#[serde(default, deserialize_with = "convert_duration_with_shellexpand")]
Expand All @@ -30,38 +46,206 @@ struct DataSizeEntity {
data_size: usize,
}

#[derive(Deserialize)]
struct NumericEntity {
#[serde(default, deserialize_with = "convert_numeric_with_shellexpand")]
value: usize,
}

#[derive(Deserialize)]
struct OptionalNumericEntity {
#[serde(
default,
deserialize_with = "convert_optional_numeric_with_shellexpand"
)]
optional_value: Option<usize>,
}

#[derive(Deserialize)]
struct VecStringEntity {
#[serde(deserialize_with = "convert_vec_string_with_shellexpand")]
expanded_strings: Vec<String>,
}

#[derive(Deserialize)]
struct OptionalStringEntity {
#[serde(deserialize_with = "convert_optional_string_with_shellexpand")]
expanded_string: Option<String>,
}

#[derive(Deserialize)]
struct StringEntity {
#[serde(deserialize_with = "convert_string_with_shellexpand")]
expanded_string: String,
}

#[test]
fn test_duration_human_readable_deserialize() {
let example = r#"
{"duration": "1m 10s"}
"#;
let example = DURATION_HUMAN_READABLE;
let deserialized: DurationEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.duration, 70);
}

#[test]
fn test_duration_usize_deserialize() {
let example = r#"
{"duration": 10}
"#;
let example = DURATION_USIZE;
let deserialized: DurationEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.duration, 10);
}

#[test]
fn test_duration_invalid_string() {
let example = r#"{"duration": {size:10, in:8}}"#;
let result: Result<DurationEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), MAP_TYPE_ERROR);
}
}

#[test]
fn test_data_size_unit_deserialize() {
let example = r#"
{"data_size": "1KiB"}
"#;
let example = DATA_SIZE_KIB;
let deserialized: DataSizeEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.data_size, 1024);
}

#[test]
fn test_data_size_usize_deserialize() {
let example = r#"
{"data_size": 10}
"#;
let example = DATA_SIZE_USIZE;
let deserialized: DataSizeEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.data_size, 10);
}

#[test]
fn test_data_size_invalid_string() {
let example = r#"{"data_size": {size:10, in:8}}"#;
let result: Result<DataSizeEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), MAP_TYPE_ERROR);
}
}

#[test]
fn test_numeric_with_shellexpand_integer() {
let example = r#"{ "value": 42 }"#;
let deserialized: NumericEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.value, 42);
}

#[test]
fn test_numeric_with_shellexpand_string() {
let example = r#"{ "value": "100" }"#;
let deserialized: NumericEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.value, 100);
}

#[test]
fn test_numeric_with_shellexpand_invalid_string() {
let example = r#"{ "value": {size:10, in:8} }"#;
let result: Result<NumericEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), MAP_TYPE_ERROR);
}
}

#[test]
fn test_optional_numeric_with_shellexpand_integer() {
let example = r#"{ "optional_value": 42 }"#;
let deserialized: OptionalNumericEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.optional_value, Some(42));
}

#[test]
fn test_optional_numeric_with_shellexpand_string() {
let example = r#"{ "optional_value": "100" }"#;
let deserialized: OptionalNumericEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.optional_value, Some(100));
}

#[test]
fn test_optional_numeric_with_shellexpand_empty_string() {
let example = r#"{"optional_value": ""}"#;
let deserialized: OptionalNumericEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.optional_value, None);
}

#[test]
fn test_optional_numeric_with_shellexpand_invalid_string() {
let example = r#"{ "optional_value": {size:10, in:8} }"#;
let result: Result<OptionalNumericEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), MAP_TYPE_ERROR);
}
}

#[test]
fn test_convert_string_with_shellexpand_invalid() {
let example = STRING_ENV_VAR;
let result: Result<StringEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), INVALID_ENV_VAR_ERROR);
}
}

#[test]
fn test_convert_string_with_shellexpand_empty() {
let example = EMPTY_STRING_ENV_VAR;
let deserialized: StringEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.expanded_string, "");
}

#[test]
fn test_convert_vec_string_with_shellexpand_empty() {
let example = VEC_STRING_EMPTY;
let deserialized: VecStringEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.expanded_strings, Vec::<String>::new());
}

#[test]
fn test_convert_vec_string_with_shellexpand_invalid() {
let example = r#"{"expanded_strings": ["$INVALID_ENV_VAR", "$ANOTHER_MISSING_VAR"]}"#;
let result: Result<VecStringEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), INVALID_ENV_VAR_ERROR);
}
}

#[test]
fn test_convert_vec_string_with_shellexpand_invalid_alternate() {
let example = r#"{"expanded_strings": ["config.json", "$INVALID_ENV_VAR"]}"#;
let result: Result<VecStringEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), INVALID_ENV_VAR_ERROR);
}
}

#[test]
fn test_convert_optional_string_with_shellexpand_none() {
let example = NULL_STRING_ENV_VAR;
let deserialized: OptionalStringEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.expanded_string, None);
}

#[test]
fn test_convert_optional_string_with_shellexpand_empty() {
let example = EMPTY_STRING_ENV_VAR;
let deserialized: OptionalStringEntity = serde_json5::from_str(example).unwrap();
assert_eq!(deserialized.expanded_string, Some(String::new()));
}

#[test]
fn test_convert_optional_string_with_shellexpand_invalid() {
let example = STRING_ENV_VAR;
let result: Result<OptionalStringEntity, _> = serde_json5::from_str(example);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.to_string(), INVALID_ENV_VAR_ERROR);
}
}
8 changes: 4 additions & 4 deletions nativelink-error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.5.3"
edition = "2021"
autobins = false
autoexamples = false
autotests = false
autotests = true
autobenches = false

[dependencies]
Expand All @@ -14,8 +14,8 @@ fred = { version = "9.2.1", default-features = false, features = [
"enable-rustls-ring",
] }
hex = { version = "0.4.3", default-features = false }
prost = { version = "0.13.3", default-features = false }
prost = { version = "0.13.3", features = ["std"], default-features = false }
prost-types = { version = "0.13.3", default-features = false }
serde = { version = "1.0.210", default-features = false }
serde = { version = "1.0.210", features = ["derive"], default-features = false }
tokio = { version = "1.40.0", features = ["fs", "rt-multi-thread", "signal", "io-util"], default-features = false }
tonic = { version = "0.12.3", features = ["transport", "tls"], default-features = false }
tonic = { version = "0.12.3", features = ["transport"], default-features = false }
Loading

0 comments on commit 29f7228

Please sign in to comment.