@@ -120,7 +120,7 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
120
120
verify_json ( resource, cwd, desired) ?;
121
121
122
122
// if resource doesn't implement a pre-test, we execute test first to see if a set is needed
123
- if !skip_test && ! set. pre_test . unwrap_or_default ( ) {
123
+ if !skip_test && set. pre_test != Some ( true ) {
124
124
info ! ( "No pretest, invoking test {}" , & resource. resource_type) ;
125
125
let ( in_desired_state, actual_state) = match invoke_test ( resource, cwd, desired) ? {
126
126
TestResult :: Group ( group_response) => {
@@ -282,7 +282,8 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
282
282
/// Error is returned if the underlying command returns a non-zero exit code.
283
283
pub fn invoke_test ( resource : & ResourceManifest , cwd : & str , expected : & str ) -> Result < TestResult , DscError > {
284
284
let Some ( test) = & resource. test else {
285
- return Err ( DscError :: NotImplemented ( "test" . to_string ( ) ) ) ;
285
+ info ! ( "Resource '{}' does not implement test, performing synthetic test" , & resource. resource_type) ;
286
+ return invoke_synthetic_test ( resource, cwd, expected) ;
286
287
} ;
287
288
288
289
verify_json ( resource, cwd, expected) ?;
@@ -375,6 +376,30 @@ pub fn invoke_test(resource: &ResourceManifest, cwd: &str, expected: &str) -> Re
375
376
}
376
377
}
377
378
379
+ fn invoke_synthetic_test ( resource : & ResourceManifest , cwd : & str , expected : & str ) -> Result < TestResult , DscError > {
380
+ let get_result = invoke_get ( resource, cwd, expected) ?;
381
+ let actual_state = match get_result {
382
+ GetResult :: Group ( results) => {
383
+ let mut result_array: Vec < Value > = Vec :: new ( ) ;
384
+ for result in results {
385
+ result_array. push ( serde_json:: to_value ( & result) ?) ;
386
+ }
387
+ Value :: from ( result_array)
388
+ } ,
389
+ GetResult :: Resource ( response) => {
390
+ response. actual_state
391
+ }
392
+ } ;
393
+ let expected_value: Value = serde_json:: from_str ( expected) ?;
394
+ let diff_properties = get_diff ( & expected_value, & actual_state) ;
395
+ Ok ( TestResult :: Resource ( ResourceTestResponse {
396
+ desired_state : expected_value,
397
+ actual_state,
398
+ in_desired_state : diff_properties. is_empty ( ) ,
399
+ diff_properties,
400
+ } ) )
401
+ }
402
+
378
403
/// Invoke the delete operation against a command resource.
379
404
///
380
405
/// # Arguments
@@ -393,7 +418,7 @@ pub fn invoke_delete(resource: &ResourceManifest, cwd: &str, filter: &str) -> Re
393
418
394
419
let mut env: Option < HashMap < String , String > > = None ;
395
420
let mut input_filter: Option < & str > = None ;
396
- let mut get_args = resource . get . args . clone ( ) ;
421
+ let mut delete_args = delete . args . clone ( ) ;
397
422
verify_json ( resource, cwd, filter) ?;
398
423
match & delete. input {
399
424
InputKind :: Env => {
@@ -403,12 +428,12 @@ pub fn invoke_delete(resource: &ResourceManifest, cwd: &str, filter: &str) -> Re
403
428
input_filter = Some ( filter) ;
404
429
} ,
405
430
InputKind :: Arg ( arg_name) => {
406
- replace_token ( & mut get_args , arg_name, filter) ?;
431
+ replace_token ( & mut delete_args , arg_name, filter) ?;
407
432
} ,
408
433
}
409
434
410
435
info ! ( "Invoking delete '{}' using '{}'" , & resource. resource_type, & delete. executable) ;
411
- let ( exit_code, _stdout, stderr) = invoke_command ( & delete. executable , get_args , input_filter, Some ( cwd) , env) ?;
436
+ let ( exit_code, _stdout, stderr) = invoke_command ( & delete. executable , delete_args , input_filter, Some ( cwd) , env) ?;
412
437
log_resource_traces ( & stderr) ;
413
438
if exit_code != 0 {
414
439
return Err ( DscError :: Command ( resource. resource_type . clone ( ) , exit_code, stderr) ) ;
0 commit comments