1use std::time::Duration;
2
3use e2e_test_model::{
4 CreateExecutionRequest, CreateStepRequest, Execution, GetExecutionsRequest, Step,
5};
6pub use reqwest::header::HeaderValue;
7use uuid::Uuid;
8
9pub mod model {
10 pub use e2e_test_model::*;
11}
12
13pub struct Config {
14 pub base_url: String,
15 pub api_header: Option<(String, HeaderValue)>,
16}
17
18pub struct Client {
19 inner: reqwest_middleware::ClientWithMiddleware,
20 config: Config,
21}
22
23impl Client {
24 pub fn new(config: Config) -> reqwest::Result<Self> {
25 let inner = reqwest::Client::builder()
26 .timeout(Duration::from_secs(15))
27 .connect_timeout(Duration::from_secs(30))
28 .build()?;
29 let retry_policy = reqwest_retry::policies::ExponentialBackoff {
30 max_n_retries: 5,
31 min_retry_interval: Duration::from_millis(100),
32 max_retry_interval: Duration::from_secs(5),
33 backoff_exponent: 2,
34 };
35 let retry_transient_middleware =
36 reqwest_retry::RetryTransientMiddleware::new_with_policy(retry_policy);
37 let inner = reqwest_middleware::ClientBuilder::new(inner)
38 .with(retry_transient_middleware)
39 .build();
40
41 let mut config = config;
42 if let Some((_, ref mut api_key)) = config.api_header {
43 api_key.set_sensitive(true);
44 }
45
46 Ok(Self { inner, config })
47 }
48
49 pub async fn get_executions(
50 &self,
51 params: &GetExecutionsRequest,
52 ) -> reqwest_middleware::Result<Vec<Execution>> {
53 let resp = self
54 .inner
55 .get(self.url("/test-warehouse/executions"))
56 .base_headers(&self.config)
57 .query(¶ms)
58 .send()
59 .await?
60 .json()
61 .await?;
62
63 Ok(resp)
64 }
65
66 pub async fn post_execution(
67 &self,
68 body: &CreateExecutionRequest,
69 ) -> reqwest_middleware::Result<Execution> {
70 let resp = self
71 .inner
72 .post(self.url("/test-warehouse/executions"))
73 .base_headers(&self.config)
74 .json(body)
75 .send()
76 .await?
77 .json()
78 .await?;
79
80 Ok(resp)
81 }
82
83 pub async fn post_step(
84 &self,
85 uuid: &Uuid,
86 body: &CreateStepRequest,
87 ) -> reqwest_middleware::Result<Step> {
88 let url = format!("/test-warehouse/executions/{}/steps", uuid);
89 let resp = self
90 .inner
91 .post(self.url(&url))
92 .base_headers(&self.config)
93 .json(body)
94 .send()
95 .await?
96 .json()
97 .await?;
98
99 Ok(resp)
100 }
101
102 fn url(&self, uri: &str) -> String {
103 format!("{}{}", self.config.base_url, uri)
104 }
105}
106
107trait BaseHeaders {
108 fn base_headers(self, config: &Config) -> Self;
109}
110
111impl BaseHeaders for reqwest_middleware::RequestBuilder {
112 fn base_headers(self, config: &Config) -> Self {
113 if let Some((ref header, ref api_key)) = config.api_header {
114 self.header(header, api_key)
115 } else {
116 self
117 }
118 }
119}