oxedyne/fe2o3/fe2o3_steel/tests/common/mod.rs
2.5 KiB, 18 runs
created by r1870400018:14427, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! Shared test scaffolding. |
| 2 | //! |
| 3 | //! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\ |
| 4 | //! Anthropic Claude |
| 5 | |
| 6 | use oxedyne_fe2o3_core::prelude::*; |
| 7 | use oxedyne_fe2o3_crypto::enc::EncryptionScheme; |
| 8 | use oxedyne_fe2o3_hash::{ |
| 9 | csum::ChecksumScheme, |
| 10 | hash::HashScheme, |
| 11 | }; |
| 12 | use oxedyne_fe2o3_o3db_sync::O3db; |
| 13 | use oxedyne_fe2o3_steel::{ |
| 14 | app::constant as app_const, |
| 15 | srv::{ |
| 16 | context::new_db, |
| 17 | id, |
| 18 | }, |
| 19 | }; |
| 20 | |
| 21 | use std::{ |
| 22 | path::PathBuf, |
| 23 | sync::{ |
| 24 | atomic::{ |
| 25 | AtomicU64, |
| 26 | Ordering, |
| 27 | }, |
| 28 | Arc, |
| 29 | RwLock, |
| 30 | }, |
| 31 | time::Duration, |
| 32 | }; |
| 33 | |
| 34 | pub type TestDb = O3db< |
| 35 | { id::UID_LEN }, |
| 36 | id::Uid, |
| 37 | EncryptionScheme, |
| 38 | HashScheme, |
| 39 | HashScheme, |
| 40 | ChecksumScheme, |
| 41 | >; |
| 42 | |
| 43 | /// A directory that removes itself. |
| 44 | pub struct TmpDir(pub PathBuf); |
| 45 | |
| 46 | impl Drop for TmpDir { |
| 47 | fn drop(&mut self) { |
| 48 | let _ = std::fs::remove_dir_all(&self.0); |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | static DB_SEQ: AtomicU64 = AtomicU64::new(0); |
| 53 | |
| 54 | /// A started Ozone database in a temporary directory, and the user id to write under. |
| 55 | /// |
| 56 | /// The directory goes when the returned `TmpDir` does, so a test leaves nothing behind and two |
| 57 | /// runs of the same test do not see each other's posts. The name carries a per-call counter as |
| 58 | /// well as the process id, because two tests in one binary run in parallel by default: keyed on |
| 59 | /// the process alone they would share a directory, and each call's `remove_dir_all` would wipe |
| 60 | /// the other's database mid-test. |
| 61 | pub fn test_db() -> Outcome<(Arc<RwLock<TestDb>>, id::Uid, TmpDir)> { |
| 62 | let seq = DB_SEQ.fetch_add(1, Ordering::Relaxed); |
| 63 | let root = std::env::temp_dir() |
| 64 | .join(fmt!("steel-publish-test-{}-{}", std::process::id(), seq)); |
| 65 | let _ = std::fs::remove_dir_all(&root); |
| 66 | res!(std::fs::create_dir_all(&root), IO, File); |
| 67 | let tmp = TmpDir(root.clone()); |
| 68 | |
| 69 | // Any key will do: the test is about what comes back out, not about what it looks like at rest. |
| 70 | let enc_key = [0u8; 32]; |
| 71 | let mut db = res!(new_db(&root, &enc_key)); |
| 72 | // The same sequence the server runs. Starting without the rest of it leaves the bots up but not |
| 73 | // answering, and every read then fails on a five-second responder timeout rather than saying the |
| 74 | // database is not ready -- so mirror it exactly rather than guess which parts matter. |
| 75 | res!(db.start("db_test")); |
| 76 | res!(ok!(db.updated_api()).activate_gc(true)); |
| 77 | std::thread::sleep(Duration::from_millis(200)); |
| 78 | res!(db.api().ping_bots(app_const::GET_DATA_WAIT)); |
| 79 | |
| 80 | Ok((Arc::new(RwLock::new(db)), id::Uid::default(), tmp)) |
| 81 | } |