@@ -249,9 +249,13 @@ impl BackgroundTask for BlueprintPlanner {
249
249
#[ cfg( test) ]
250
250
mod test {
251
251
use super :: * ;
252
+ use crate :: app:: background:: Activator ;
253
+ use crate :: app:: background:: tasks:: blueprint_execution:: BlueprintExecutor ;
252
254
use crate :: app:: background:: tasks:: blueprint_load:: TargetBlueprintLoader ;
253
255
use crate :: app:: background:: tasks:: inventory_collection:: InventoryCollector ;
254
256
use nexus_test_utils_macros:: nexus_test;
257
+ use nexus_types:: deployment:: PendingMgsUpdates ;
258
+ use omicron_uuid_kinds:: OmicronZoneUuid ;
255
259
256
260
type ControlPlaneTestContext =
257
261
nexus_test_utils:: ControlPlaneTestContext < crate :: Server > ;
@@ -280,7 +284,7 @@ mod test {
280
284
cptestctx. logctx . log . clone ( ) ,
281
285
& [ cptestctx. internal_dns . dns_server . local_address ( ) ] ,
282
286
)
283
- . unwrap ( ) ;
287
+ . expect ( "can't start resolver" ) ;
284
288
let mut collector = InventoryCollector :: new (
285
289
datastore. clone ( ) ,
286
290
resolver. clone ( ) ,
@@ -305,7 +309,7 @@ mod test {
305
309
let status = serde_json:: from_value :: < BlueprintPlannerStatus > (
306
310
planner. activate ( & opctx) . await ,
307
311
)
308
- . unwrap ( ) ;
312
+ . expect ( "can't activate planner" ) ;
309
313
let blueprint_id = match status {
310
314
BlueprintPlannerStatus :: Targeted {
311
315
parent_blueprint_id,
@@ -330,11 +334,73 @@ mod test {
330
334
blueprint. diff_since_blueprint( initial_blueprint) . has_changes( )
331
335
) ;
332
336
333
- // Planning again should not change the plan.
337
+ // Planning again should not change the plan, because nothing has changed .
334
338
let status = serde_json:: from_value :: < BlueprintPlannerStatus > (
335
339
planner. activate ( & opctx) . await ,
336
340
)
337
- . unwrap ( ) ;
341
+ . expect ( "can't re-activate planner" ) ;
342
+ assert_eq ! (
343
+ status,
344
+ BlueprintPlannerStatus :: Unchanged {
345
+ parent_blueprint_id: blueprint_id,
346
+ }
347
+ ) ;
348
+
349
+ // Enable execution.
350
+ let mut target = * target;
351
+ target. enabled = true ;
352
+ datastore
353
+ . blueprint_target_set_current_enabled ( & opctx, target)
354
+ . await
355
+ . expect ( "can't enable execution" ) ;
356
+
357
+ // Ping the loader again so it gets the updated target.
358
+ loader. activate ( & opctx) . await ;
359
+ let ( target, blueprint) = & * rx_loader
360
+ . borrow_and_update ( )
361
+ . clone ( )
362
+ . expect ( "failed to re-load blueprint" ) ;
363
+ assert_eq ! ( target. target_id, blueprint. id) ;
364
+ assert_eq ! ( target. target_id, blueprint_id) ;
365
+ assert ! (
366
+ blueprint. diff_since_blueprint( initial_blueprint) . has_changes( )
367
+ ) ;
368
+
369
+ // Trigger an inventory collection.
370
+ collector. activate ( & opctx) . await ;
371
+
372
+ // Execute the plan.
373
+ let ( dummy_tx, _dummy_rx) = watch:: channel ( PendingMgsUpdates :: new ( ) ) ;
374
+ let mut executor = BlueprintExecutor :: new (
375
+ datastore. clone ( ) ,
376
+ resolver. clone ( ) ,
377
+ rx_loader. clone ( ) ,
378
+ OmicronZoneUuid :: new_v4 ( ) ,
379
+ Activator :: new ( ) ,
380
+ dummy_tx,
381
+ ) ;
382
+ let value = executor. activate ( & opctx) . await ;
383
+ let value = value. as_object ( ) . expect ( "response is not a JSON object" ) ;
384
+ assert_eq ! ( value[ "target_id" ] , blueprint. id. to_string( ) ) ;
385
+ assert ! ( value[ "enabled" ] . as_bool( ) . expect( "enabled should be boolean" ) ) ;
386
+ assert ! ( value[ "execution_error" ] . is_null( ) ) ;
387
+ assert ! (
388
+ !value[ "event_report" ]
389
+ . as_object( )
390
+ . expect( "event report should be an object" ) [ "Ok" ]
391
+ . as_object( )
392
+ . expect( "event report is not Ok" ) [ "step_events" ]
393
+ . as_array( )
394
+ . expect( "steps should be an array" )
395
+ . is_empty( )
396
+ ) ;
397
+
398
+ // Planning again should not change the plan, because the execution
399
+ // is all fake.
400
+ let status = serde_json:: from_value :: < BlueprintPlannerStatus > (
401
+ planner. activate ( & opctx) . await ,
402
+ )
403
+ . expect ( "can't re-activate planner" ) ;
338
404
assert_eq ! (
339
405
status,
340
406
BlueprintPlannerStatus :: Unchanged {
0 commit comments