mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
88 lines
3.0 KiB
Rust
88 lines
3.0 KiB
Rust
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
use super::TEST_ADMIN_SECRET;
|
|
use fluxer_admin::{
|
|
build_router,
|
|
config::{AdminConfig, ProxyConfig, RuntimeEnv},
|
|
};
|
|
use std::time::{Duration, Instant};
|
|
use tokio::{net::TcpListener, task::JoinHandle, time::sleep};
|
|
|
|
pub struct RunningRustAdmin {
|
|
base_url: String,
|
|
handle: JoinHandle<()>,
|
|
}
|
|
|
|
impl RunningRustAdmin {
|
|
pub fn base_url(&self) -> &str {
|
|
&self.base_url
|
|
}
|
|
}
|
|
|
|
impl Drop for RunningRustAdmin {
|
|
fn drop(&mut self) {
|
|
self.handle.abort();
|
|
}
|
|
}
|
|
|
|
pub async fn start(api_endpoint: &str) -> Result<RunningRustAdmin, String> {
|
|
let listener = TcpListener::bind("127.0.0.1:0")
|
|
.await
|
|
.map_err(|error| format!("failed to bind Rust admin server: {error}"))?;
|
|
let port = listener
|
|
.local_addr()
|
|
.map_err(|error| format!("failed to read Rust admin address: {error}"))?
|
|
.port();
|
|
let base_url = format!("http://127.0.0.1:{port}");
|
|
let config = admin_config(port, api_endpoint, &base_url);
|
|
let router = build_router(config);
|
|
let handle = tokio::spawn(async move {
|
|
let _ = axum::serve(listener, router).await;
|
|
});
|
|
wait_for_health(&base_url).await?;
|
|
Ok(RunningRustAdmin { base_url, handle })
|
|
}
|
|
|
|
fn admin_config(port: u16, api_endpoint: &str, admin_endpoint: &str) -> AdminConfig {
|
|
AdminConfig {
|
|
env: RuntimeEnv::Test,
|
|
host: "127.0.0.1".to_owned(),
|
|
port,
|
|
secret_key_base: TEST_ADMIN_SECRET.to_owned(),
|
|
base_path: String::new(),
|
|
api_endpoint: api_endpoint.to_owned(),
|
|
media_endpoint: format!("{api_endpoint}/media"),
|
|
static_cdn_endpoint: "https://static.example.test".to_owned(),
|
|
admin_endpoint: admin_endpoint.to_owned(),
|
|
web_app_endpoint: "http://127.0.0.1:8088".to_owned(),
|
|
oauth_client_id: "1234567890123456789".to_owned(),
|
|
oauth_client_secret: "test-admin-oauth-secret".to_owned(),
|
|
oauth_redirect_uri: format!("{admin_endpoint}/oauth2_callback"),
|
|
build_version: "parity".to_owned(),
|
|
self_hosted: false,
|
|
proxy: ProxyConfig {
|
|
trust_client_ip_header: false,
|
|
client_ip_header_name: "x-forwarded-for".to_owned(),
|
|
},
|
|
}
|
|
}
|
|
|
|
async fn wait_for_health(base_url: &str) -> Result<(), String> {
|
|
let client = reqwest::Client::builder()
|
|
.redirect(reqwest::redirect::Policy::none())
|
|
.build()
|
|
.map_err(|error| format!("failed to build health client: {error}"))?;
|
|
let deadline = Instant::now() + Duration::from_secs(30);
|
|
let url = format!("{}/_health", base_url.trim_end_matches('/'));
|
|
let mut last_error = String::new();
|
|
while Instant::now() < deadline {
|
|
match client.get(&url).send().await {
|
|
Ok(response) if response.status().is_success() => return Ok(()),
|
|
Ok(response) => last_error = format!("health returned {}", response.status()),
|
|
Err(error) => last_error = error.to_string(),
|
|
}
|
|
sleep(Duration::from_millis(200)).await;
|
|
}
|
|
Err(format!("timed out waiting for {url}: {last_error}"))
|
|
}
|