oxedyne/fe2o3/fe2o3_steel/tests/server.rs
6.7 KiB, 66 runs
created by r1870400018:1015, 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 | use oxedyne_fe2o3_steel::{ |
| 2 | app::https::AppWebHandler, |
| 3 | srv::{ |
| 4 | api::ApiHandlerRegistry, |
| 5 | cfg::{ |
| 6 | ServerConfig, |
| 7 | VhostConfig, |
| 8 | }, |
| 9 | constant, |
| 10 | context::{ |
| 11 | self, |
| 12 | Protocol, |
| 13 | ServerContext, |
| 14 | VhostRuntime, |
| 15 | }, |
| 16 | id, |
| 17 | server::Server, |
| 18 | webhook::WebhookRegistry, |
| 19 | ws::{ |
| 20 | handler::AppWebSocketHandler, |
| 21 | syntax::WebSocketSyntax, |
| 22 | }, |
| 23 | }, |
| 24 | }; |
| 25 | |
| 26 | use oxedyne_fe2o3_core::{ |
| 27 | file::OsPath, |
| 28 | prelude::*, |
| 29 | path::NormalPath, |
| 30 | }; |
| 31 | use oxedyne_fe2o3_jdat::version::SemVer; |
| 32 | |
| 33 | use std::{ |
| 34 | collections::HashMap, |
| 35 | path::{ |
| 36 | Path, |
| 37 | PathBuf, |
| 38 | }, |
| 39 | sync::Arc, |
| 40 | thread, |
| 41 | time::Duration, |
| 42 | }; |
| 43 | |
| 44 | |
| 45 | pub async fn test_server(filter: &'static str) -> Outcome<()> { |
| 46 | |
| 47 | match filter { |
| 48 | "all" | "server" => { |
| 49 | let cfg = ServerConfig::default(); |
| 50 | let home = res!(std::env::var("HOME")); |
| 51 | let app_root = Path::new(&home) |
| 52 | .join("usr/code/web/apps/test") |
| 53 | .normalise() |
| 54 | .absolute(); |
| 55 | info!("App root path is {:?}", app_root); |
| 56 | |
| 57 | let db_root = app_root |
| 58 | .clone() |
| 59 | .join(Path::new(constant::DB_DIR).normalise()) |
| 60 | .normalise() |
| 61 | .absolute(); |
| 62 | |
| 63 | let db_enc_key: [u8; 32] = [ |
| 64 | 0x68, 0xee, 0x9a, 0xd0, 0x6a, 0x77, 0x91, 0x4b, |
| 65 | 0xef, 0x52, 0x2c, 0x28, 0x55, 0x5b, 0xe2, 0x8e, |
| 66 | 0xe8, 0xa5, 0xeb, 0xa2, 0xef, 0xe0, 0xe7, 0x74, |
| 67 | 0x82, 0x61, 0x0f, 0x17, 0x24, 0xc4, 0x0d, 0xd2, |
| 68 | ]; |
| 69 | |
| 70 | let mut db = res!(context::new_db(&db_root, &db_enc_key)); |
| 71 | |
| 72 | // Since we are testing, delete all existing data and index files. |
| 73 | let files = res!(db.find_all_data_files()); |
| 74 | test!("Found {} files", files.len()); |
| 75 | for file in files { |
| 76 | test!(" Deleting {:?}", file); |
| 77 | res!(std::fs::remove_file(file)); |
| 78 | } |
| 79 | |
| 80 | test!("Starting db..."); |
| 81 | res!(db.start("steel_test_db")); |
| 82 | thread::sleep(Duration::from_secs(1)); |
| 83 | |
| 84 | let gc_on = false; |
| 85 | res!(ok!(db.updated_api()).activate_gc(gc_on)); |
| 86 | |
| 87 | thread::sleep(Duration::from_secs(1)); |
| 88 | |
| 89 | // Ping all database bots. |
| 90 | let (start, msgs) = res!(db.api().ping_bots(constant::GET_DATA_WAIT)); |
| 91 | test!("{} ping replies received in {:?}.", msgs.len(), start.elapsed()); |
| 92 | |
| 93 | let uid = id::Uid::new(0); |
| 94 | |
| 95 | let ws_syntax = res!(WebSocketSyntax::new( |
| 96 | "steel_ws", |
| 97 | &SemVer::new(0, 1, 0), |
| 98 | "Steel Websocket Test Syntax", |
| 99 | )); |
| 100 | |
| 101 | // Single test vhost with an empty webroot and no routes. |
| 102 | let vhost_cfg = VhostConfig { |
| 103 | hostnames: vec![fmt!("localhost")], |
| 104 | public_dir_rel: None, |
| 105 | static_route_paths_rel: Default::default(), |
| 106 | default_index_files: vec![fmt!("index.html")], |
| 107 | redirects: Vec::new(), |
| 108 | db_dir_rel: None, |
| 109 | api_routes: Vec::new(), |
| 110 | webhook_routes: Vec::new(), |
| 111 | egress_allowed: Vec::new(), |
| 112 | admin_keys: Vec::new(), |
| 113 | head_injection_url: None, |
| 114 | proxy_routes: Vec::new(), |
| 115 | ws_routes: Vec::new(), |
| 116 | term_config: None, |
| 117 | publish: None, |
| 118 | site_admins: Vec::new(), |
| 119 | tiles: None, |
| 120 | access_log: true, |
| 121 | permissions_policy: None, |
| 122 | }; |
| 123 | |
| 124 | let web_handler: AppWebHandler<HashMap<String, OsPath>> = AppWebHandler::new( |
| 125 | cfg.clone(), |
| 126 | PathBuf::new(), |
| 127 | HashMap::new(), |
| 128 | vhost_cfg.default_index_files.clone(), |
| 129 | true, |
| 130 | Vec::new(), // api_routes |
| 131 | Vec::new(), // webhook_routes |
| 132 | Arc::new(WebhookRegistry::new()), |
| 133 | Arc::new(ApiHandlerRegistry::new()), |
| 134 | None, // tls_client |
| 135 | None, // admin_state |
| 136 | None, // traffic |
| 137 | None, // publish |
| 138 | None, // mail |
| 139 | Arc::new(Vec::new()), // site_admins |
| 140 | ); |
| 141 | |
| 142 | let ws_handler = AppWebSocketHandler::new(None); |
| 143 | |
| 144 | let runtime = Arc::new(VhostRuntime { |
| 145 | hostnames: vhost_cfg.hostnames.clone(), |
| 146 | web_handler, |
| 147 | ws_handler, |
| 148 | ws_syntax, |
| 149 | redirects: vhost_cfg.redirects.clone(), |
| 150 | proxy_routes: vhost_cfg.proxy_routes.clone(), |
| 151 | ws_routes: vhost_cfg.ws_routes.clone(), |
| 152 | term_manager: None, |
| 153 | uses_sessions: vhost_cfg.uses_sessions(), |
| 154 | permissions_policy: vhost_cfg.permissions_policy.clone(), |
| 155 | tiles: None, |
| 156 | access_log: vhost_cfg.access_log, |
| 157 | }); |
| 158 | |
| 159 | let mut vhosts = HashMap::new(); |
| 160 | for h in &vhost_cfg.hostnames { |
| 161 | vhosts.insert(h.to_lowercase(), runtime.clone()); |
| 162 | } |
| 163 | |
| 164 | let protocol = Protocol::Web { |
| 165 | vhosts: Arc::new(vhosts), |
| 166 | default_vhost: vhost_cfg.primary_hostname().to_lowercase(), |
| 167 | dev_mode: true, |
| 168 | }; |
| 169 | |
| 170 | // An already-open database, as the server holds after an |
| 171 | // unseal. The map is shared because databases are normally |
| 172 | // attached to it after the listeners bind. |
| 173 | let mut vhost_dbs = HashMap::new(); |
| 174 | vhost_dbs.insert( |
| 175 | vhost_cfg.primary_hostname().to_lowercase(), |
| 176 | (Arc::new(std::sync::RwLock::new(db)), uid), |
| 177 | ); |
| 178 | let context = ServerContext::new( |
| 179 | cfg, |
| 180 | app_root, |
| 181 | Arc::new(std::sync::RwLock::new(vhost_dbs)), |
| 182 | Vec::new(), // db specs: nothing left to open |
| 183 | protocol, |
| 184 | None, // traffic recorder |
| 185 | None, // admin state |
| 186 | ); |
| 187 | |
| 188 | let server = Server::new(context); |
| 189 | // Do not await forever: this test only proves the bring-up path |
| 190 | // compiles and reaches the accept loop under the current API. |
| 191 | let _ = tokio::time::timeout(Duration::from_millis(250), server.start()).await; |
| 192 | } |
| 193 | _ => (), |
| 194 | } |
| 195 | |
| 196 | Ok(()) |
| 197 | } |