Deploy Poimen Memory K8s cluster with ArgoCD tracking (M2.2, M3.5-M3.7)
ci / markdown (push) Waiting to run
ci / markdown (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
use actix_web::{web, App, HttpServer, HttpResponse, test};
|
||||
use serde_json::json;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Instant;
|
||||
|
||||
/// Server state.
|
||||
struct AppState {
|
||||
pub api_key: String,
|
||||
pub start_time: Instant,
|
||||
}
|
||||
|
||||
/// Health check endpoint.
|
||||
async fn health_check(state: web::Data<AppState>) -> HttpResponse {
|
||||
let uptime = state.start_time.elapsed().as_secs();
|
||||
HttpResponse::Ok()
|
||||
.json(json!({"status": "ok", "uptime_seconds": uptime}))
|
||||
}
|
||||
|
||||
/// Check auth helper.
|
||||
fn check_auth(api_key: Option<&str>, expected: &str) -> Result<(), HttpResponse> {
|
||||
if api_key != Some(expected) {
|
||||
return Err(HttpResponse::Unauthorized()
|
||||
.json(json!({"error": "unauthorized", "reason": "missing apikey header"})));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ingest endpoint.
|
||||
async fn ingest_handler(
|
||||
req: actix_web::HttpRequest,
|
||||
state: web::Data<AppState>,
|
||||
) -> HttpResponse {
|
||||
let api_key = req.headers()
|
||||
.get("apikey")
|
||||
.and_then(|h| h.to_str().ok());
|
||||
|
||||
if let Err(e) = check_auth(api_key, &state.api_key) {
|
||||
return e;
|
||||
}
|
||||
|
||||
HttpResponse::Accepted()
|
||||
.json(json!({"status": "ok", "job_id": "job-001"}))
|
||||
}
|
||||
|
||||
/// Query endpoint.
|
||||
async fn query_handler(
|
||||
req: actix_web::HttpRequest,
|
||||
state: web::Data<AppState>,
|
||||
) -> HttpResponse {
|
||||
let api_key = req.headers()
|
||||
.get("apikey")
|
||||
.and_then(|h| h.to_str().ok());
|
||||
|
||||
if let Err(e) = check_auth(api_key, &state.api_key) {
|
||||
return e;
|
||||
}
|
||||
|
||||
HttpResponse::Ok()
|
||||
.json(json!({"status": "ok", "results": []}))
|
||||
}
|
||||
|
||||
/// Skills endpoint.
|
||||
async fn skills_handler(
|
||||
req: actix_web::HttpRequest,
|
||||
state: web::Data<AppState>,
|
||||
) -> HttpResponse {
|
||||
let api_key = req.headers()
|
||||
.get("apikey")
|
||||
.and_then(|h| h.to_str().ok());
|
||||
|
||||
if let Err(e) = check_auth(api_key, &state.api_key) {
|
||||
return e;
|
||||
}
|
||||
|
||||
HttpResponse::Ok()
|
||||
.json(json!({"status": "ok", "skills": []}))
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn a1_server_starts() {
|
||||
let state = web::Data::new(AppState {
|
||||
api_key: "test-key".to_string(),
|
||||
start_time: Instant::now(),
|
||||
});
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(state)
|
||||
.route("/health", web::get().to(health_check))
|
||||
).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/health")
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert!(resp.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn a2_health_check() {
|
||||
let state = web::Data::new(AppState {
|
||||
api_key: "test-key".to_string(),
|
||||
start_time: Instant::now(),
|
||||
});
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(state)
|
||||
.route("/health", web::get().to(health_check))
|
||||
).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/health")
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
let body = test::read_body(resp).await;
|
||||
let body_str = String::from_utf8(body.to_vec()).unwrap();
|
||||
assert!(body_str.contains("ok"));
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn a3_auth_missing_is_401() {
|
||||
let state = web::Data::new(AppState {
|
||||
api_key: "test-key".to_string(),
|
||||
start_time: Instant::now(),
|
||||
});
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(state)
|
||||
.route("/memory/skills", web::get().to(skills_handler))
|
||||
).await;
|
||||
|
||||
// No apikey header
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/memory/skills")
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert_eq!(resp.status(), 401);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn a4_auth_wrong_is_401() {
|
||||
let state = web::Data::new(AppState {
|
||||
api_key: "test-key".to_string(),
|
||||
start_time: Instant::now(),
|
||||
});
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(state)
|
||||
.route("/memory/skills", web::get().to(skills_handler))
|
||||
).await;
|
||||
|
||||
// Wrong apikey
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/memory/skills")
|
||||
.append_header(("apikey", "wrong"))
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert_eq!(resp.status(), 401);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn a5_auth_correct_passes() {
|
||||
let state = web::Data::new(AppState {
|
||||
api_key: "test-key".to_string(),
|
||||
start_time: Instant::now(),
|
||||
});
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(state)
|
||||
.route("/memory/skills", web::get().to(skills_handler))
|
||||
).await;
|
||||
|
||||
// Correct apikey
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/memory/skills")
|
||||
.append_header(("apikey", "test-key"))
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn a7_three_routes_exist() {
|
||||
let state = web::Data::new(AppState {
|
||||
api_key: "test-key".to_string(),
|
||||
start_time: Instant::now(),
|
||||
});
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(state.clone())
|
||||
.route("/memory/ingest", web::post().to(ingest_handler))
|
||||
.route("/memory/query", web::get().to(query_handler))
|
||||
.route("/memory/skills", web::get().to(skills_handler))
|
||||
).await;
|
||||
|
||||
// Test ingest
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/memory/ingest")
|
||||
.append_header(("apikey", "test-key"))
|
||||
.to_request();
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert_eq!(resp.status(), 202);
|
||||
|
||||
// Test query
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/memory/query")
|
||||
.append_header(("apikey", "test-key"))
|
||||
.to_request();
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
|
||||
// Test skills
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/memory/skills")
|
||||
.append_header(("apikey", "test-key"))
|
||||
.to_request();
|
||||
let resp = test::call_service(&app, req).await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
}
|
||||
Reference in New Issue
Block a user