use scouter_server::api::schema::DriftRecordRequest;
use scouter_server::sql::schema::{
AlertRule, FeatureMonitorProfile, MonitorConfig, MonitorProfile, ProcessAlertRule, QueryResult,
};
use axum::{
body::Body,
http::{self, Request, StatusCode},
};
use http_body_util::BodyExt;
use serde_json::Value;
use std::collections::HashMap;
use tower::Service;
use tower::ServiceExt; mod test_utils;
#[tokio::test]
async fn test_api_drift() {
let mut app = test_utils::setup_api(true).await.unwrap();
for i in 0..3 {
let record = DriftRecordRequest {
created_at: None,
name: "test_app".to_string(),
repository: "test".to_string(),
feature: format!("feature{}", i),
value: i as f64,
version: "1.0.0".to_string(),
};
let body = serde_json::to_string(&record).unwrap();
let response = app
.call(
Request::builder()
.uri("/drift")
.header(http::header::CONTENT_TYPE, "application/json")
.method("POST")
.body(Body::from(body))
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
}
let response = app.call(
Request::builder()
.uri("/drift?name=test_app&repository=test&version=1.0.0&time_window=5minute&max_data_points=1000")
.method("GET")
.body(Body::empty())
.unwrap(),
).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
let body = response.into_body().collect().await.unwrap().to_bytes();
let body: Value = serde_json::from_slice(&body).unwrap();
let data = body.get("data");
let data: QueryResult = serde_json::from_value(data.unwrap().clone()).unwrap();
assert_eq!(data.features.len(), 3);
let record = DriftRecordRequest {
created_at: None,
name: "test_app".to_string(),
repository: "test".to_string(),
feature: "feature1".to_string(),
value: 2.5,
version: "2.0.0".to_string(),
};
let body = serde_json::to_string(&record).unwrap();
let response = app
.call(
Request::builder()
.uri("/drift")
.header(http::header::CONTENT_TYPE, "application/json")
.method("POST")
.body(Body::from(body))
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
let response = app.call(
Request::builder()
.uri("/drift?name=test_app&repository=test&version=2.0.0&time_window=5minute&max_data_points=1000")
.method("GET")
.body(Body::empty())
.unwrap(),
);
let response = response.await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
let body = response.into_body().collect().await.unwrap().to_bytes();
let body: Value = serde_json::from_slice(&body).unwrap();
let data = body.get("data");
let data: QueryResult = serde_json::from_value(data.unwrap().clone()).unwrap();
assert_eq!(data.features.len(), 1);
test_utils::teardown().await.unwrap();
}
#[tokio::test]
async fn test_api_profile() {
let app = test_utils::setup_api(true).await.unwrap();
let mut features = HashMap::new();
features.insert(
"feature1".to_string(),
FeatureMonitorProfile {
id: "feature1".to_string(),
center: 0.0,
one_ucl: 1.0,
one_lcl: -1.0,
two_ucl: 2.0,
two_lcl: -2.0,
three_ucl: 3.0,
three_lcl: -3.0,
timestamp: chrono::Utc::now().naive_utc().to_string(),
},
);
let monitor_profile = MonitorProfile {
features,
config: MonitorConfig {
sample_size: 100,
sample: true,
name: "test_app".to_string(),
repository: "test".to_string(),
version: "1.0.0".to_string(),
alert_rule: AlertRule {
control: Some(ProcessAlertRule {
rule: "test".to_string(),
}),
percentage: None,
},
cron: "0 0 * * * *".to_string(),
},
};
let body = serde_json::to_string(&monitor_profile).unwrap();
let response = app
.oneshot(
Request::builder()
.uri("/profile")
.header(http::header::CONTENT_TYPE, "application/json")
.method("POST")
.body(Body::from(body))
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
test_utils::teardown().await.unwrap();
}