Line data Source code
1 : use axum::response::{IntoResponse, Response};
2 : use http::StatusCode;
3 : use serde::{Deserialize, Serialize};
4 : use tracing::info;
5 : use utils::failpoint_support::apply_failpoint;
6 :
7 : pub type ConfigureFailpointsRequest = Vec<FailpointConfig>;
8 :
9 : /// Information for configuring a single fail point
10 0 : #[derive(Debug, Serialize, Deserialize)]
11 : pub struct FailpointConfig {
12 : /// Name of the fail point
13 : pub name: String,
14 : /// List of actions to take, using the format described in `fail::cfg`
15 : ///
16 : /// We also support `actions = "exit"` to cause the fail point to immediately exit.
17 : pub actions: String,
18 : }
19 :
20 : use crate::http::{extract::Json, JsonResponse};
21 :
22 : /// Configure failpoints for testing purposes.
23 0 : pub(in crate::http) async fn configure_failpoints(
24 0 : failpoints: Json<ConfigureFailpointsRequest>,
25 0 : ) -> Response {
26 0 : if !fail::has_failpoints() {
27 0 : return JsonResponse::error(
28 0 : StatusCode::PRECONDITION_FAILED,
29 0 : "Cannot manage failpoints because neon was compiled without failpoints support",
30 0 : );
31 0 : }
32 :
33 0 : for fp in &*failpoints {
34 0 : info!("cfg failpoint: {} {}", fp.name, fp.actions);
35 :
36 : // We recognize one extra "action" that's not natively recognized
37 : // by the failpoints crate: exit, to immediately kill the process
38 0 : let cfg_result = apply_failpoint(&fp.name, &fp.actions);
39 :
40 0 : if let Err(e) = cfg_result {
41 0 : return JsonResponse::error(
42 0 : StatusCode::BAD_REQUEST,
43 0 : format!("failed to configure failpoints: {e}"),
44 0 : );
45 0 : }
46 : }
47 :
48 0 : StatusCode::OK.into_response()
49 0 : }
|