From 1301d0548cdcfcdd8e4d186efe2da9b8f126f433 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Thu, 7 Nov 2024 17:08:03 -0800 Subject: [PATCH 01/11] fix clippy --- dsc_lib/src/dscresources/dscresource.rs | 103 +++++++++++++++++++++--- 1 file changed, 94 insertions(+), 9 deletions(-) diff --git a/dsc_lib/src/dscresources/dscresource.rs b/dsc_lib/src/dscresources/dscresource.rs index b72ab43d..29f46aa5 100644 --- a/dsc_lib/src/dscresources/dscresource.rs +++ b/dsc_lib/src/dscresources/dscresource.rs @@ -338,6 +338,16 @@ pub fn get_well_known_properties() -> HashMap { } #[must_use] +/// Performs a comparison of two JSON Values if the expected is a strict subset of the actual +/// +/// # Arguments +/// +/// * `expected` - The expected value +/// * `actual` - The actual value +/// +/// # Returns +/// +/// An array of top level properties that differ, if any pub fn get_diff(expected: &Value, actual: &Value) -> Vec { let mut diff_properties: Vec = Vec::new(); if expected.is_null() { @@ -367,20 +377,33 @@ pub fn get_diff(expected: &Value, actual: &Value) -> Vec { } } else { - match actual.as_object() { - Some(actual_object) => { - if actual_object.contains_key(key) { - if value != &actual[key] { + // skip `$schema` key as that is provided as input, but not output typically + if key == "$schema" { + continue; + } + + if let Some(actual_object) = actual.as_object() { + if actual_object.contains_key(key) { + if let Some(value_array) = value.as_array() { + if let Some(actual_array) = actual[key].as_array() { + if !is_same_array(value_array, actual_array) { + info!("diff: arrays differ for {key}"); + diff_properties.push(key.to_string()); + } + } else { + info!("diff: {} is not an array", actual[key]); diff_properties.push(key.to_string()); } - } - else { + } else if value != &actual[key] { diff_properties.push(key.to_string()); } - }, - None => { + } else { + info!("diff: {key} missing"); diff_properties.push(key.to_string()); - }, + } + } else { + info!("diff: {key} not object"); + diff_properties.push(key.to_string()); } } } @@ -388,3 +411,65 @@ pub fn get_diff(expected: &Value, actual: &Value) -> Vec { diff_properties } + +/// Compares two arrays independent of order +fn is_same_array(expected: &Vec, actual: &Vec) -> bool { + if expected.len() != actual.len() { + info!("diff: arrays are different lengths"); + return false; + } + + for item in expected { + if !array_contains(actual, item) { + info!("diff: actual array missing expected element"); + return false; + } + } + + true +} + +fn array_contains(array: &Vec, find: &Value) -> bool { + for item in array { + if find.is_boolean() && item.is_boolean() && find.as_bool().unwrap() == item.as_bool().unwrap() { + return true; + } + + if find.is_f64() && item.is_f64() && (find.as_f64().unwrap() - item.as_f64().unwrap()).abs() < 0.1 { + return true; + } + + if find.is_i64() && item.is_i64() && find.as_i64().unwrap() == item.as_i64().unwrap() { + return true; + } + + if find.is_null() && item.is_null() { + return true; + } + + if find.is_number() && item.is_number() && find.as_number().unwrap() == item.as_number().unwrap() { + return true; + } + + if find.is_string() && item.is_string() && find.as_str().unwrap() == item.as_str().unwrap() { + return true; + } + + if find.is_u64() && item.is_u64() && find.as_u64().unwrap() == item.as_u64().unwrap() { + return true; + } + + if find.is_object() && item.is_object() { + let obj_diff = get_diff(find, item); + if obj_diff.is_empty() { + return true; + } + } + + if find.is_array() && item.is_array() && array_contains(item.as_array().unwrap(), find) { + return true; + } + } + + false +} From f2b6086a1500f5da5f6a7a84fa683bef61b3d16d Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Thu, 7 Nov 2024 17:21:00 -0800 Subject: [PATCH 02/11] add test tracing --- resources/apt/test/apt.tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/apt/test/apt.tests.ps1 b/resources/apt/test/apt.tests.ps1 index 17338865..1962e644 100644 --- a/resources/apt/test/apt.tests.ps1 +++ b/resources/apt/test/apt.tests.ps1 @@ -27,8 +27,8 @@ Describe 'Apt resource tests' { if (-not $aptExists) { Set-ItResult -Skip -Because "Apt not found" } - $out = dsc config get -p $yamlPath | ConvertFrom-Json -Depth 10 - $LASTEXITCODE | Should -Be 0 + $out = dsc config get -p $yamlPath 2> "$TestDrive/stderr.txt" | ConvertFrom-Json -Depth 10 + $LASTEXITCODE | Should -Be 0 -Because (Get-Content "$TestDrive/stderr.txt") $exists = $null -ne (Get-Command $pkgName -CommandType Application -ErrorAction Ignore) $observed = $out.results[1].result.actualState._exist $observed | Should -Be $exists From 1a2d7a253002e1d923d2678a6e3a3e127cebad57 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Thu, 7 Nov 2024 17:33:18 -0800 Subject: [PATCH 03/11] set tracing level for test --- resources/apt/test/apt.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/apt/test/apt.tests.ps1 b/resources/apt/test/apt.tests.ps1 index 1962e644..0f88b4b8 100644 --- a/resources/apt/test/apt.tests.ps1 +++ b/resources/apt/test/apt.tests.ps1 @@ -27,7 +27,7 @@ Describe 'Apt resource tests' { if (-not $aptExists) { Set-ItResult -Skip -Because "Apt not found" } - $out = dsc config get -p $yamlPath 2> "$TestDrive/stderr.txt" | ConvertFrom-Json -Depth 10 + $out = dsc -l trace config get -p $yamlPath 2> "$TestDrive/stderr.txt" | ConvertFrom-Json -Depth 10 $LASTEXITCODE | Should -Be 0 -Because (Get-Content "$TestDrive/stderr.txt") $exists = $null -ne (Get-Command $pkgName -CommandType Application -ErrorAction Ignore) $observed = $out.results[1].result.actualState._exist From bb0ec61f9c0589c73b93ffe36513458c272d610e Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Thu, 7 Nov 2024 19:07:28 -0800 Subject: [PATCH 04/11] change writing of test trace --- resources/apt/test/apt.tests.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/apt/test/apt.tests.ps1 b/resources/apt/test/apt.tests.ps1 index 0f88b4b8..743232c1 100644 --- a/resources/apt/test/apt.tests.ps1 +++ b/resources/apt/test/apt.tests.ps1 @@ -28,7 +28,8 @@ Describe 'Apt resource tests' { Set-ItResult -Skip -Because "Apt not found" } $out = dsc -l trace config get -p $yamlPath 2> "$TestDrive/stderr.txt" | ConvertFrom-Json -Depth 10 - $LASTEXITCODE | Should -Be 0 -Because (Get-Content "$TestDrive/stderr.txt") + write-verbose -verbose (Get-Content "$TestDrive/stderr.txt" | Out-String) + $LASTEXITCODE | Should -Be 0 $exists = $null -ne (Get-Command $pkgName -CommandType Application -ErrorAction Ignore) $observed = $out.results[1].result.actualState._exist $observed | Should -Be $exists From baa4122d9f5b721a05eb9b4c59ff0ac730f5868b Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Thu, 7 Nov 2024 19:25:37 -0800 Subject: [PATCH 05/11] add back as_get --- dsc/src/args.rs | 2 ++ dsc/src/subcommand.rs | 40 +++++++++++++++++++++++++------- resources/apt/test/apt.tests.ps1 | 3 +-- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/dsc/src/args.rs b/dsc/src/args.rs index e572ca31..e9b92254 100644 --- a/dsc/src/args.rs +++ b/dsc/src/args.rs @@ -101,6 +101,8 @@ pub enum ConfigSubCommand { format: Option, #[clap(long, hide = true)] as_get: bool, + #[clap(long, hide = true)] + as_test: bool, }, #[clap(name = "validate", about = "Validate the current configuration", hide = true)] Validate { diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index 4b1783fe..21517b66 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -5,13 +5,24 @@ use crate::args::{ConfigSubCommand, DscType, OutputFormat, ResourceSubCommand}; use crate::resolve::{get_contents, Include}; use crate::resource_command::{get_resource, self}; use crate::tablewriter::Table; -use crate::util::{DSC_CONFIG_ROOT, EXIT_DSC_ERROR, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, get_schema, write_output, get_input, set_dscconfigroot, validate_json}; -use dsc_lib::configure::{Configurator, config_doc::{Configuration, ExecutionKind}, config_result::ResourceGetResult}; -use dsc_lib::dscerror::DscError; -use dsc_lib::dscresources::invoke_result::ResolveResult; +use crate::util::{DSC_CONFIG_ROOT, EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, get_schema, write_output, get_input, set_dscconfigroot, validate_json}; use dsc_lib::{ + configure::{ + config_doc::{ + Configuration, + ExecutionKind, + Resource, + }, + config_result::ResourceGetResult, + Configurator, + }, + dscerror::DscError, DscManager, - dscresources::invoke_result::ValidateResult, + dscresources::invoke_result::{ + ResolveResult, + TestResult, + ValidateResult, + }, dscresources::dscresource::{Capability, ImplementedAs, Invoke}, dscresources::resource_manifest::{import_manifest, ResourceManifest}, }; @@ -90,7 +101,7 @@ pub fn config_set(configurator: &mut Configurator, format: &Option } } -pub fn config_test(configurator: &mut Configurator, format: &Option, as_group: &bool, as_get: &bool) +pub fn config_test(configurator: &mut Configurator, format: &Option, as_group: &bool, as_get: &bool, as_test: &bool) { match configurator.invoke_test() { Ok(result) => { @@ -108,6 +119,19 @@ pub fn config_test(configurator: &mut Configurator, format: &Option::new(); + for test_result in result.results { + group_result.push(test_result.into()); + } + match serde_json::to_string(&group_result) { + Ok(json) => json, + Err(err) => { + error!("JSON Error: {err}"); + exit(EXIT_JSON_ERROR); + } + } + } else { match serde_json::to_string(&(result.results)) { Ok(json) => json, @@ -282,8 +306,8 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, stdin: ConfigSubCommand::Set { format, .. } => { config_set(&mut configurator, format, as_group); }, - ConfigSubCommand::Test { format, as_get, .. } => { - config_test(&mut configurator, format, as_group, as_get); + ConfigSubCommand::Test { format, as_get, as_test, .. } => { + config_test(&mut configurator, format, as_group, as_get, as_test); }, ConfigSubCommand::Validate { document, path, format} => { let mut result = ValidateResult { diff --git a/resources/apt/test/apt.tests.ps1 b/resources/apt/test/apt.tests.ps1 index 743232c1..af00e4ce 100644 --- a/resources/apt/test/apt.tests.ps1 +++ b/resources/apt/test/apt.tests.ps1 @@ -28,8 +28,7 @@ Describe 'Apt resource tests' { Set-ItResult -Skip -Because "Apt not found" } $out = dsc -l trace config get -p $yamlPath 2> "$TestDrive/stderr.txt" | ConvertFrom-Json -Depth 10 - write-verbose -verbose (Get-Content "$TestDrive/stderr.txt" | Out-String) - $LASTEXITCODE | Should -Be 0 + $LASTEXITCODE | Should -Be 0 -Because (Get-Content "$TestDrive/stderr.txt" | Out-String) $exists = $null -ne (Get-Command $pkgName -CommandType Application -ErrorAction Ignore) $observed = $out.results[1].result.actualState._exist $observed | Should -Be $exists From f86001ddb6f30174af05b9f28180746d4a7f4f5e Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Fri, 8 Nov 2024 10:56:36 -0800 Subject: [PATCH 06/11] rename `--as-test` to `--as-config` as it's more accurate, added unit tests, fixed nested array search --- dsc/src/args.rs | 2 +- dsc/src/subcommand.rs | 11 +++-- dsc_lib/src/dscresources/dscresource.rs | 66 ++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/dsc/src/args.rs b/dsc/src/args.rs index e9b92254..5ac8eebe 100644 --- a/dsc/src/args.rs +++ b/dsc/src/args.rs @@ -102,7 +102,7 @@ pub enum ConfigSubCommand { #[clap(long, hide = true)] as_get: bool, #[clap(long, hide = true)] - as_test: bool, + as_config: bool, }, #[clap(name = "validate", about = "Validate the current configuration", hide = true)] Validate { diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index 21517b66..e1bf657d 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -101,13 +101,14 @@ pub fn config_set(configurator: &mut Configurator, format: &Option } } -pub fn config_test(configurator: &mut Configurator, format: &Option, as_group: &bool, as_get: &bool, as_test: &bool) +pub fn config_test(configurator: &mut Configurator, format: &Option, as_group: &bool, as_get: &bool, as_config: &bool) { match configurator.invoke_test() { Ok(result) => { if *as_group { - let json = if *as_get { - let mut group_result = Vec::::new(); + let json = if *as_config { + let mut result_configuration = Configuration::new(); + result_configuration.resources = Vec::new(); for test_result in result.results { group_result.push(test_result.into()); } @@ -306,8 +307,8 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, stdin: ConfigSubCommand::Set { format, .. } => { config_set(&mut configurator, format, as_group); }, - ConfigSubCommand::Test { format, as_get, as_test, .. } => { - config_test(&mut configurator, format, as_group, as_get, as_test); + ConfigSubCommand::Test { format, as_get, as_config, .. } => { + config_test(&mut configurator, format, as_group, as_get, as_config); }, ConfigSubCommand::Validate { document, path, format} => { let mut result = ValidateResult { diff --git a/dsc_lib/src/dscresources/dscresource.rs b/dsc_lib/src/dscresources/dscresource.rs index 29f46aa5..d39db92f 100644 --- a/dsc_lib/src/dscresources/dscresource.rs +++ b/dsc_lib/src/dscresources/dscresource.rs @@ -466,10 +466,74 @@ fn array_contains(array: &Vec, find: &Value) -> bool { } } - if find.is_array() && item.is_array() && array_contains(item.as_array().unwrap(), find) { + if find.is_array() && item.is_array() && is_same_array(item.as_array().unwrap(), find.as_array().unwrap()) { return true; } } false } + +#[test] +fn same_array() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(null)]; + let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(null)]; + assert_eq!(is_same_array(&array_one, &array_two), true); +} + +#[test] +fn same_array_out_of_order() { + use serde_json::json; + let array_one = vec![json!("a"), json!(true), json!(r#"{"a":"b"}"#)]; + let array_two = vec![json!(r#"{"a":"b"}"#), json!("a"), json!(true)]; + assert_eq!(is_same_array(&array_one, &array_two), true); +} + +#[test] +fn different_array() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#)]; + let array_two = vec![json!(r#"{"a":"b"}"#), json!("a"), json!(2)]; + assert_eq!(is_same_array(&array_one, &array_two), false); +} + +#[test] +fn different_array_sizes() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#)]; + let array_two = vec![json!(r#"{"a":"b"}"#), json!("a")]; + assert_eq!(is_same_array(&array_one, &array_two), false); +} + +#[test] +fn array_with_multiple_objects_with_superset() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(r#"{"c":"d"}"#)]; + let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b", "c":"d"}"#), json!(r#"{"c":"d"}"#)]; + assert_eq!(is_same_array(&array_one, &array_two), false); +} + +#[test] +fn array_with_duplicates_out_of_order() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(r#"{"a":"b"}"#)]; + let array_two = vec![json!(r#"{"a":"b"}"#), json!("a"), json!(1), json!(r#"{"a":"b"}"#)]; + assert_eq!(is_same_array(&array_one, &array_two), true); +} + +#[test] +fn same_array_with_nested_array() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(1)])]; + let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(1)])]; + assert_eq!(is_same_array(&array_one, &array_two), true); +} + +#[test] +fn different_array_with_nested_array() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(1)])]; + let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(2)])]; + assert_eq!(is_same_array(&array_one, &array_two), false); +} From 5d775c2b028a4b8e0f776d8bf2e99965ea6cf04f Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Fri, 8 Nov 2024 11:06:13 -0800 Subject: [PATCH 07/11] fix resource manifest --- dsc/assertion.dsc.resource.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsc/assertion.dsc.resource.json b/dsc/assertion.dsc.resource.json index 8a4fc443..17142f8a 100644 --- a/dsc/assertion.dsc.resource.json +++ b/dsc/assertion.dsc.resource.json @@ -37,7 +37,7 @@ "config", "--as-group", "test", - "--as-get" + "--as-config" ], "input": "stdin", "return": "state" From adf406353360631144b024c5ad47b6faef7fa6e9 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 13 Nov 2024 14:16:40 -0800 Subject: [PATCH 08/11] address initial feedback --- dsc/src/args.rs | 2 ++ dsc_lib/src/dscresources/dscresource.rs | 42 +++++++++++++++---------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/dsc/src/args.rs b/dsc/src/args.rs index 5ac8eebe..4436e941 100644 --- a/dsc/src/args.rs +++ b/dsc/src/args.rs @@ -99,8 +99,10 @@ pub enum ConfigSubCommand { path: Option, #[clap(short = 'f', long, help = "The output format to use")] format: Option, + // Used by Assertion resource to return `test` result as a `get` result #[clap(long, hide = true)] as_get: bool, + // Used by Assertion resource to return `test` result as a configuration `test` result #[clap(long, hide = true)] as_config: bool, }, diff --git a/dsc_lib/src/dscresources/dscresource.rs b/dsc_lib/src/dscresources/dscresource.rs index d39db92f..7d9cb298 100644 --- a/dsc_lib/src/dscresources/dscresource.rs +++ b/dsc_lib/src/dscresources/dscresource.rs @@ -477,63 +477,71 @@ fn array_contains(array: &Vec, find: &Value) -> bool { #[test] fn same_array() { use serde_json::json; - let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(null)]; - let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(null)]; + let array_one = vec![json!("a"), json!(1), json!({"a":"b"}), json!(null)]; + let array_two = vec![json!("a"), json!(1), json!({"a":"b"}), json!(null)]; assert_eq!(is_same_array(&array_one, &array_two), true); } #[test] fn same_array_out_of_order() { use serde_json::json; - let array_one = vec![json!("a"), json!(true), json!(r#"{"a":"b"}"#)]; - let array_two = vec![json!(r#"{"a":"b"}"#), json!("a"), json!(true)]; + let array_one = vec![json!("a"), json!(true), json!({"a":"b"})]; + let array_two = vec![json!({"a":"b"}), json!("a"), json!(true)]; assert_eq!(is_same_array(&array_one, &array_two), true); } #[test] fn different_array() { use serde_json::json; - let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#)]; - let array_two = vec![json!(r#"{"a":"b"}"#), json!("a"), json!(2)]; + let array_one = vec![json!("a"), json!(1), json!({"a":"b"})]; + let array_two = vec![json!({"a":"b"}), json!("a"), json!(2)]; assert_eq!(is_same_array(&array_one, &array_two), false); } #[test] fn different_array_sizes() { use serde_json::json; - let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#)]; - let array_two = vec![json!(r#"{"a":"b"}"#), json!("a")]; + let array_one = vec![json!("a"), json!(1), json!({"a":"b"})]; + let array_two = vec![json!({"a":"b"}), json!("a")]; assert_eq!(is_same_array(&array_one, &array_two), false); } #[test] -fn array_with_multiple_objects_with_superset() { +fn array_with_multiple_objects_with_actual_superset() { use serde_json::json; - let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(r#"{"c":"d"}"#)]; - let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b", "c":"d"}"#), json!(r#"{"c":"d"}"#)]; + let array_one = vec![json!("a"), json!(1), json!({"a":"b"}), json!({"c":"d"})]; + let array_two = vec![json!("a"), json!(1), json!({"c":"d", "a":"b"}), json!({"c":"d"})]; + assert_eq!(is_same_array(&array_one, &array_two), true); +} + +#[test] +fn array_with_multiple_objects_with_expected_superset() { + use serde_json::json; + let array_one = vec![json!("a"), json!(1), json!({"a":"b", "c":"d"}), json!({"c":"d"})]; + let array_two = vec![json!("a"), json!(1), json!({"a":"b"}), json!({"c":"d"})]; assert_eq!(is_same_array(&array_one, &array_two), false); } #[test] fn array_with_duplicates_out_of_order() { use serde_json::json; - let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(r#"{"a":"b"}"#)]; - let array_two = vec![json!(r#"{"a":"b"}"#), json!("a"), json!(1), json!(r#"{"a":"b"}"#)]; + let array_one = vec![json!("a"), json!(1), json!({"a":"b"}), json!({"a":"b"})]; + let array_two = vec![json!({"a":"b"}), json!("a"), json!(1), json!({"a":"b"})]; assert_eq!(is_same_array(&array_one, &array_two), true); } #[test] fn same_array_with_nested_array() { use serde_json::json; - let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(1)])]; - let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(1)])]; + let array_one = vec![json!("a"), json!(1), json!({"a":"b"}), json!(vec![json!("a"), json!(1)])]; + let array_two = vec![json!("a"), json!(1), json!({"a":"b"}), json!(vec![json!("a"), json!(1)])]; assert_eq!(is_same_array(&array_one, &array_two), true); } #[test] fn different_array_with_nested_array() { use serde_json::json; - let array_one = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(1)])]; - let array_two = vec![json!("a"), json!(1), json!(r#"{"a":"b"}"#), json!(vec![json!("a"), json!(2)])]; + let array_one = vec![json!("a"), json!(1), json!({"a":"b"}), json!(vec![json!("a"), json!(1)])]; + let array_two = vec![json!("a"), json!(1), json!({"a":"b"}), json!(vec![json!("a"), json!(2)])]; assert_eq!(is_same_array(&array_one, &array_two), false); } From 6b030e9b5f664cf77e14c2502204c10a4acc38e8 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Sat, 16 Nov 2024 17:29:39 -0800 Subject: [PATCH 09/11] fix clippy --- dsc_lib/src/discovery/command_discovery.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/dsc_lib/src/discovery/command_discovery.rs b/dsc_lib/src/discovery/command_discovery.rs index c94abb7d..c6a31e70 100644 --- a/dsc_lib/src/discovery/command_discovery.rs +++ b/dsc_lib/src/discovery/command_discovery.rs @@ -39,6 +39,17 @@ impl CommandDiscovery { fn get_resource_paths() -> Result, DscError> { + let mut resource_path_setting = ResourcePathSetting::default(); + + match Self::get_resource_path_setting() { + Ok(v) => { + resource_path_setting = v; + }, + Err(e) => { + debug!("{e}"); + } + } + let mut using_custom_path = false; // try DSC_RESOURCE_PATH env var first otherwise use PATH @@ -75,8 +86,7 @@ impl CommandDiscovery { paths.push(exe_home_pb); if let Ok(new_path) = env::join_paths(paths.clone()) { - debug!("Using PATH: {:?}", new_path.to_string_lossy()); - env::set_var("PATH", &new_path); + env::set_var("PATH", new_path); } } } @@ -297,7 +307,7 @@ impl ResourceDiscovery for CommandDiscovery { } else { self.discover_resources("*")?; self.discover_adapted_resources(type_name_filter, adapter_name_filter)?; - + // add/update found adapted resources to the lookup_table add_resources_to_lookup_table(&self.adapted_resources); @@ -580,7 +590,7 @@ fn save_adapted_resources_lookup_table(lookup_table: &HashMap) fn load_adapted_resources_lookup_table() -> HashMap { let file_path = get_lookup_table_file_path(); - + let lookup_table: HashMap = match fs::read(file_path.clone()){ Ok(data) => { serde_json::from_slice(&data).unwrap_or_default() }, Err(_) => { HashMap::new() } From 6655db7b73e32f4bf373373830d98b10e80ceda7 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Sat, 16 Nov 2024 19:14:55 -0800 Subject: [PATCH 10/11] fix cherry-pick of assertion fix --- dsc/src/subcommand.rs | 28 +++++++++++++++++++--- dsc_lib/src/discovery/command_discovery.rs | 11 --------- dsc_lib/src/dscresources/dscresource.rs | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index e1bf657d..66f0ad7a 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -5,7 +5,7 @@ use crate::args::{ConfigSubCommand, DscType, OutputFormat, ResourceSubCommand}; use crate::resolve::{get_contents, Include}; use crate::resource_command::{get_resource, self}; use crate::tablewriter::Table; -use crate::util::{DSC_CONFIG_ROOT, EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, get_schema, write_output, get_input, set_dscconfigroot, validate_json}; +use crate::util::{DSC_CONFIG_ROOT, EXIT_DSC_ERROR, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, get_schema, write_output, get_input, set_dscconfigroot, validate_json}; use dsc_lib::{ configure::{ config_doc::{ @@ -110,9 +110,31 @@ pub fn config_test(configurator: &mut Configurator, format: &Option { + if test_response.actual_state.is_object() { + test_response.actual_state.as_object().cloned() + } else { + debug!("actual_state is not an object"); + None + } + }, + TestResult::Group(_) => { + // not expected + debug!("Unexpected Group TestResult"); + None + } + }; + let resource = Resource { + name: test_result.name, + resource_type: test_result.resource_type, + properties, + depends_on: None, + metadata: None, + }; + result_configuration.resources.push(resource); } - match serde_json::to_string(&group_result) { + match serde_json::to_string(&result_configuration) { Ok(json) => json, Err(err) => { error!("JSON Error: {err}"); diff --git a/dsc_lib/src/discovery/command_discovery.rs b/dsc_lib/src/discovery/command_discovery.rs index c6a31e70..45644c7d 100644 --- a/dsc_lib/src/discovery/command_discovery.rs +++ b/dsc_lib/src/discovery/command_discovery.rs @@ -39,17 +39,6 @@ impl CommandDiscovery { fn get_resource_paths() -> Result, DscError> { - let mut resource_path_setting = ResourcePathSetting::default(); - - match Self::get_resource_path_setting() { - Ok(v) => { - resource_path_setting = v; - }, - Err(e) => { - debug!("{e}"); - } - } - let mut using_custom_path = false; // try DSC_RESOURCE_PATH env var first otherwise use PATH diff --git a/dsc_lib/src/dscresources/dscresource.rs b/dsc_lib/src/dscresources/dscresource.rs index 7d9cb298..502131a9 100644 --- a/dsc_lib/src/dscresources/dscresource.rs +++ b/dsc_lib/src/dscresources/dscresource.rs @@ -7,7 +7,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; -use tracing::debug; +use tracing::{debug, info}; use super::{command_resource, dscerror, invoke_result::{ExportResult, GetResult, ResolveResult, ResourceTestResponse, SetResult, TestResult, ValidateResult}, resource_manifest::import_manifest}; From b889a2ac1123746217e67d2564879f975531efad Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Sat, 16 Nov 2024 19:18:02 -0800 Subject: [PATCH 11/11] enable CI on rc1 branch --- .github/workflows/rust.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 620fdcde..c6b06c6a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: [ "main" ] + branches: [ "main", "3.0.0-rc1" ] pull_request: - branches: [ "main" ] + branches: [ "main", "3.0.0-rc1" ] paths-ignore: - "docs/**" - "*.md"