@@ -175,5 +175,144 @@ impl SitrepLoader {
175175
176176#[ cfg( test) ]  
177177mod  test { 
178-     // TODO 
178+     use  super :: * ; 
179+     use  crate :: app:: background:: BackgroundTask ; 
180+     use  nexus_db_queries:: db:: pub_test_utils:: TestDatabase ; 
181+     use  nexus_types:: fm:: SitrepMetadata ; 
182+     use  omicron_test_utils:: dev; 
183+     use  omicron_uuid_kinds:: CollectionUuid ; 
184+     use  omicron_uuid_kinds:: OmicronZoneUuid ; 
185+     use  omicron_uuid_kinds:: SitrepUuid ; 
186+ 
187+     #[ tokio:: test]  
188+     async  fn  test_load_sitreps ( )  { 
189+         let  logctx = dev:: test_setup_log ( "test_inventory_loader" ) ; 
190+         let  db = TestDatabase :: new_with_datastore ( & logctx. log ) . await ; 
191+         let  ( opctx,  datastore)  = ( db. opctx ( ) ,  db. datastore ( ) ) ; 
192+ 
193+         let  ( tx,  mut  sitrep_rx)  = watch:: channel ( None ) ; 
194+         let  mut  task = SitrepLoader :: new ( datastore. clone ( ) ,  tx) ; 
195+ 
196+         // Initially, there should be no sitrep. 
197+         let  status = task. activate ( & opctx) . await ; 
198+         assert_eq ! ( * sitrep_rx. borrow_and_update( ) ,  None ) ; 
199+         let  status = serde_json:: from_value :: < Status > ( status) . unwrap ( ) ; 
200+         assert_eq ! ( status,  Status :: NoSitrep ) ; 
201+ 
202+         // Now, create an initial sitrep. 
203+         let  sitrep1_id = SitrepUuid :: new_v4 ( ) ; 
204+         let  sitrep1 = Sitrep  { 
205+             metadata :  SitrepMetadata  { 
206+                 id :  sitrep1_id, 
207+                 inv_collection_id :  CollectionUuid :: new_v4 ( ) , 
208+                 parent_sitrep_id :  None , 
209+                 creator_id :  OmicronZoneUuid :: new_v4 ( ) , 
210+                 comment :  "test sitrep 1" . to_string ( ) , 
211+                 time_created :  Utc :: now ( ) , 
212+             } , 
213+         } ; 
214+         datastore
215+             . fm_sitrep_insert ( & opctx,  & sitrep1) 
216+             . await 
217+             . expect ( "sitrep should be inserted successfully" ) ; 
218+ 
219+         // It should be loaded. 
220+         let  status = task. activate ( & opctx) . await ; 
221+         assert_eq ! ( 
222+             true , 
223+             sitrep_rx. has_changed( ) . unwrap( ) , 
224+             "sitrep watch should have changed when a sitrep was loaded" 
225+         ) ; 
226+         let  snapshot = sitrep_rx
227+             . borrow_and_update ( ) 
228+             . clone ( ) 
229+             . expect ( "the new sitrep should have been loaded" ) ; 
230+         let  ( ref  loaded_version1,  ref  loaded_sitrep)  = * snapshot; 
231+         // N.B.: we just compare the IDs here as comparing the whole struct may 
232+         // not be equal, since the `time_created` field may have been rounded in 
233+         // CRDB. Which is a shame, but whatever. :/ 
234+         assert_eq ! ( loaded_sitrep. metadata. id,  sitrep1. metadata. id) ; 
235+         dbg ! ( loaded_version1) ; 
236+         let  status = serde_json:: from_value :: < Status > ( status) . unwrap ( ) ; 
237+         match  status { 
238+             Status :: Loaded  {  version,  .. }  => { 
239+                 assert_eq ! ( & version,  loaded_version1) ; 
240+             } 
241+             status => panic ! ( "expected Status::Loaded, got {status:?}" , ) , 
242+         } ; 
243+ 
244+         // A subsequent activation should see the same sitrep. 
245+         let  status = task. activate ( & opctx) . await ; 
246+         assert_eq ! ( 
247+             false , 
248+             sitrep_rx. has_changed( ) . unwrap( ) , 
249+             "sitrep watch should not change if the same sitrep was loaded" 
250+         ) ; 
251+         let  snapshot = sitrep_rx
252+             . borrow_and_update ( ) 
253+             . clone ( ) 
254+             . expect ( "the same should have been loaded" ) ; 
255+         let  ( ref  loaded_version2,  ref  loaded_sitrep)  = * snapshot; 
256+         assert_eq ! ( loaded_sitrep. metadata. id,  sitrep1. metadata. id) ; 
257+         dbg ! ( loaded_version1,  loaded_version2) ; 
258+         let  status = serde_json:: from_value :: < Status > ( status) . unwrap ( ) ; 
259+         match  status { 
260+             Status :: Loaded  {  version,  .. }  => { 
261+                 assert_eq ! ( & version,  loaded_version2) ; 
262+             } 
263+             status => panic ! ( "expected Status::Loaded, got {status:?}" , ) , 
264+         } ; 
265+ 
266+         // Now, create a new sitrep. 
267+         let  sitrep2_id = SitrepUuid :: new_v4 ( ) ; 
268+         let  sitrep2 = Sitrep  { 
269+             metadata :  SitrepMetadata  { 
270+                 id :  sitrep2_id, 
271+                 inv_collection_id :  CollectionUuid :: new_v4 ( ) , 
272+                 parent_sitrep_id :  Some ( sitrep1_id) , 
273+                 creator_id :  OmicronZoneUuid :: new_v4 ( ) , 
274+                 comment :  "test sitrep 2" . to_string ( ) , 
275+                 time_created :  Utc :: now ( ) , 
276+             } , 
277+         } ; 
278+         datastore
279+             . fm_sitrep_insert ( & opctx,  & sitrep2) 
280+             . await 
281+             . expect ( "sitrep2 should be inserted successfully" ) ; 
282+ 
283+         // It should be loaded. 
284+         let  status = task. activate ( & opctx) . await ; 
285+         assert_eq ! ( 
286+             true , 
287+             sitrep_rx. has_changed( ) . unwrap( ) , 
288+             "loading a new sitrep should update the watch" 
289+         ) ; 
290+         let  snapshot = sitrep_rx
291+             . borrow_and_update ( ) 
292+             . clone ( ) 
293+             . expect ( "the new sitrep should have been loaded" ) ; 
294+         let  ( ref  loaded_version3,  ref  loaded_sitrep)  = * snapshot; 
295+         assert_eq ! ( loaded_sitrep. metadata. id,  sitrep2. metadata. id) ; 
296+         dbg ! ( loaded_version3) ; 
297+         assert_ne ! ( loaded_version3,  loaded_version2) ; 
298+         let  status = serde_json:: from_value :: < Status > ( status) . unwrap ( ) ; 
299+         match  status { 
300+             Status :: Loaded  {  version,  .. }  => { 
301+                 assert_eq ! ( & version,  loaded_version3) ; 
302+             } 
303+             status => panic ! ( "expected Status::Loaded, got {status:?}" , ) , 
304+         } ; 
305+ 
306+         // XXX(eliza): It would be nice to also be able to test that an orphaned 
307+         // sitrep (which has not been linked into the sitrep history chain) is 
308+         // *not* loaded even if it exists. However, that would require 
309+         // `nexus-db-queries` to expose separate interfaces for creating a 
310+         // sitrep and inserting it into the history, which I have intentionally 
311+         // chosen *not* to do to make it harder to do it by mistake. 
312+         // So, ¯\_(ツ)_/¯ 
313+ 
314+         // Cleanup 
315+         db. terminate ( ) . await ; 
316+         logctx. cleanup_successful ( ) ; 
317+     } 
179318} 
0 commit comments