@@ -257,10 +257,14 @@ impl BackgroundTask for BlueprintPlanner {
257
257
#[ cfg( test) ]
258
258
mod test {
259
259
use super :: * ;
260
+ use crate :: app:: background:: Activator ;
261
+ use crate :: app:: background:: tasks:: blueprint_execution:: BlueprintExecutor ;
260
262
use crate :: app:: background:: tasks:: blueprint_load:: TargetBlueprintLoader ;
261
263
use crate :: app:: background:: tasks:: inventory_collection:: InventoryCollector ;
262
264
use nexus_inventory:: now_db_precision;
263
265
use nexus_test_utils_macros:: nexus_test;
266
+ use nexus_types:: deployment:: PendingMgsUpdates ;
267
+ use omicron_uuid_kinds:: OmicronZoneUuid ;
264
268
265
269
type ControlPlaneTestContext =
266
270
nexus_test_utils:: ControlPlaneTestContext < crate :: Server > ;
@@ -289,7 +293,7 @@ mod test {
289
293
cptestctx. logctx . log . clone ( ) ,
290
294
& [ cptestctx. internal_dns . dns_server . local_address ( ) ] ,
291
295
)
292
- . unwrap ( ) ;
296
+ . expect ( "can't start resolver" ) ;
293
297
let mut collector = InventoryCollector :: new (
294
298
datastore. clone ( ) ,
295
299
resolver. clone ( ) ,
@@ -322,7 +326,7 @@ mod test {
322
326
let status = serde_json:: from_value :: < BlueprintPlannerStatus > (
323
327
planner. activate ( & opctx) . await ,
324
328
)
325
- . unwrap ( ) ;
329
+ . expect ( "can't activate planner" ) ;
326
330
let blueprint_id = match status {
327
331
BlueprintPlannerStatus :: Targeted {
328
332
parent_blueprint_id,
@@ -347,11 +351,73 @@ mod test {
347
351
blueprint. diff_since_blueprint( initial_blueprint) . has_changes( )
348
352
) ;
349
353
350
- // Planning again should not change the plan.
354
+ // Planning again should not change the plan, because nothing has changed .
351
355
let status = serde_json:: from_value :: < BlueprintPlannerStatus > (
352
356
planner. activate ( & opctx) . await ,
353
357
)
354
- . unwrap ( ) ;
358
+ . expect ( "can't re-activate planner" ) ;
359
+ assert_eq ! (
360
+ status,
361
+ BlueprintPlannerStatus :: Unchanged {
362
+ parent_blueprint_id: blueprint_id,
363
+ }
364
+ ) ;
365
+
366
+ // Enable execution.
367
+ let mut target = * target;
368
+ target. enabled = true ;
369
+ datastore
370
+ . blueprint_target_set_current_enabled ( & opctx, target)
371
+ . await
372
+ . expect ( "can't enable execution" ) ;
373
+
374
+ // Ping the loader again so it gets the updated target.
375
+ loader. activate ( & opctx) . await ;
376
+ let ( target, blueprint) = & * rx_loader
377
+ . borrow_and_update ( )
378
+ . clone ( )
379
+ . expect ( "failed to re-load blueprint" ) ;
380
+ assert_eq ! ( target. target_id, blueprint. id) ;
381
+ assert_eq ! ( target. target_id, blueprint_id) ;
382
+ assert ! (
383
+ blueprint. diff_since_blueprint( initial_blueprint) . has_changes( )
384
+ ) ;
385
+
386
+ // Trigger an inventory collection.
387
+ collector. activate ( & opctx) . await ;
388
+
389
+ // Execute the plan.
390
+ let ( dummy_tx, _dummy_rx) = watch:: channel ( PendingMgsUpdates :: new ( ) ) ;
391
+ let mut executor = BlueprintExecutor :: new (
392
+ datastore. clone ( ) ,
393
+ resolver. clone ( ) ,
394
+ rx_loader. clone ( ) ,
395
+ OmicronZoneUuid :: new_v4 ( ) ,
396
+ Activator :: new ( ) ,
397
+ dummy_tx,
398
+ ) ;
399
+ let value = executor. activate ( & opctx) . await ;
400
+ let value = value. as_object ( ) . expect ( "response is not a JSON object" ) ;
401
+ assert_eq ! ( value[ "target_id" ] , blueprint. id. to_string( ) ) ;
402
+ assert ! ( value[ "enabled" ] . as_bool( ) . expect( "enabled should be boolean" ) ) ;
403
+ assert ! ( value[ "execution_error" ] . is_null( ) ) ;
404
+ assert ! (
405
+ !value[ "event_report" ]
406
+ . as_object( )
407
+ . expect( "event report should be an object" ) [ "Ok" ]
408
+ . as_object( )
409
+ . expect( "event report is not Ok" ) [ "step_events" ]
410
+ . as_array( )
411
+ . expect( "steps should be an array" )
412
+ . is_empty( )
413
+ ) ;
414
+
415
+ // Planning again should not change the plan, because the execution
416
+ // is all fake.
417
+ let status = serde_json:: from_value :: < BlueprintPlannerStatus > (
418
+ planner. activate ( & opctx) . await ,
419
+ )
420
+ . expect ( "can't re-activate planner" ) ;
355
421
assert_eq ! (
356
422
status,
357
423
BlueprintPlannerStatus :: Unchanged {
0 commit comments