наблюдаемость: завершить базовый контур Community
Добавить структурированные журналы, метрики, трассировку и безопасный канал критических ошибок. Усилить границы рантайма, тесты, проверку зависимостей и сценарии развёртывания.
This commit is contained in:
@@ -23,6 +23,7 @@ use crank_schema::{Schema, SchemaKind};
|
||||
use serde_json::{Value, json};
|
||||
use serial_test::serial;
|
||||
use tokio::net::TcpListener;
|
||||
use uuid::Version;
|
||||
|
||||
use admin_api::{
|
||||
app::build_app,
|
||||
@@ -40,6 +41,8 @@ const TEST_PASSWORD_PEPPER: &str = "test-password-pepper";
|
||||
const TEST_SESSION_SECRET: &str = "test-session-secret";
|
||||
const TEST_MASTER_KEY: &str = "test-master-key";
|
||||
|
||||
mod history_loss;
|
||||
|
||||
struct TestServer {
|
||||
base_url: String,
|
||||
shutdown: Option<tokio::sync::oneshot::Sender<()>>,
|
||||
@@ -385,6 +388,30 @@ async fn exports_single_workspace_but_rejects_access_lifecycle() {
|
||||
exported["workspace"]["workspace"]["id"],
|
||||
DEFAULT_WORKSPACE_ID
|
||||
);
|
||||
assert_eq!(exported["kind"], "workspace_catalog_snapshot");
|
||||
assert_eq!(exported["format_version"], "1");
|
||||
assert_eq!(exported["restorable"], false);
|
||||
assert_eq!(
|
||||
exported["included"],
|
||||
json!([
|
||||
"workspace_settings",
|
||||
"operation_summaries",
|
||||
"agent_summaries",
|
||||
"platform_api_key_metadata"
|
||||
])
|
||||
);
|
||||
assert!(
|
||||
exported["excluded"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.contains(&json!("secret_values"))
|
||||
);
|
||||
assert!(
|
||||
exported["excluded"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.contains(&json!("invocation_logs_and_usage"))
|
||||
);
|
||||
assert!(exported.get("memberships").is_none());
|
||||
assert!(exported.get("invitations").is_none());
|
||||
|
||||
@@ -574,6 +601,25 @@ async fn updates_profile_and_changes_password() {
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
let client = authorized_client(&base_url).await;
|
||||
let second_client = reqwest::Client::builder()
|
||||
.cookie_store(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
let second_login = second_client
|
||||
.post(format!("{root_url}/api/auth/login"))
|
||||
.json(&json!({
|
||||
"email": TEST_AUTH_EMAIL,
|
||||
"password": TEST_AUTH_PASSWORD,
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
let second_login_status = second_login.status();
|
||||
let second_login_body = second_login.text().await.unwrap();
|
||||
assert!(
|
||||
second_login_status.is_success(),
|
||||
"second login failed with {second_login_status}: {second_login_body}"
|
||||
);
|
||||
|
||||
let profile = assert_success_json(
|
||||
client
|
||||
@@ -615,6 +661,21 @@ async fn updates_profile_and_changes_password() {
|
||||
.status();
|
||||
assert_eq!(password_status, reqwest::StatusCode::NO_CONTENT);
|
||||
|
||||
let current_session_status = client
|
||||
.get(format!("{root_url}/api/auth/profile"))
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.status();
|
||||
let other_session_status = second_client
|
||||
.get(format!("{root_url}/api/auth/profile"))
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.status();
|
||||
assert_eq!(current_session_status, reqwest::StatusCode::OK);
|
||||
assert_eq!(other_session_status, reqwest::StatusCode::UNAUTHORIZED);
|
||||
|
||||
let relogin_client = reqwest::Client::builder()
|
||||
.cookie_store(true)
|
||||
.build()
|
||||
@@ -855,7 +916,10 @@ async fn generates_request_id_for_test_run_invocations() {
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
assert!(!request_id.is_empty());
|
||||
assert_eq!(
|
||||
uuid::Uuid::parse_str(&request_id).unwrap().get_version(),
|
||||
Some(Version::SortRand)
|
||||
);
|
||||
response.error_for_status().unwrap();
|
||||
|
||||
let logs = client
|
||||
|
||||
Reference in New Issue
Block a user