krabka_bench_driver/soak/
client.rs1pub mod load;
19pub mod readback;
20pub mod windows;
21
22use {
23 krabka_client_core::{
24 sasl::SaslCredentials,
25 security::{ClientSecurity, TlsConnectorConfig, TrustStore},
26 },
27 krabka_security::{ListenerProtocol, SaslMechanism},
28 std::{
29 path::PathBuf,
30 time::{SystemTime, UNIX_EPOCH},
31 },
32};
33
34#[must_use]
37pub fn now_ms() -> i64 {
38 SystemTime::now()
39 .duration_since(UNIX_EPOCH)
40 .map_or(0, |since| {
41 i64::try_from(since.as_millis()).unwrap_or(i64::MAX)
42 })
43}
44
45#[derive(Debug, Clone)]
47pub struct Endpoint {
48 pub bootstrap: String,
49 pub security: Option<ClientSecurity>,
51}
52
53impl Endpoint {
54 #[must_use]
56 pub fn plaintext(bootstrap: impl Into<String>) -> Self {
57 Self {
58 bootstrap: bootstrap.into(),
59 security: None,
60 }
61 }
62
63 #[must_use]
68 pub fn sasl_ssl(bootstrap: impl Into<String>, scram: ScramLogin) -> Self {
69 let mut tls = TlsConnectorConfig::default();
70 tls.trust_store = TrustStore::PemFile(scram.ca);
71 tls.server_name = scram.server_name;
72 Self {
73 bootstrap: bootstrap.into(),
74 security: Some(ClientSecurity {
75 protocol: ListenerProtocol::SaslSsl,
76 tls: Some(tls),
77 sasl: Some(SaslCredentials::Scram {
78 mechanism: SaslMechanism::ScramSha512,
79 username: scram.username,
80 password: scram.password,
81 delegation_token: false,
82 }),
83 sasl_host: None,
84 }),
85 }
86 }
87}
88
89#[derive(Debug, Clone)]
91pub struct ScramLogin {
92 pub ca: PathBuf,
94 pub server_name: String,
96 pub username: String,
97 pub password: String,
98}
99
100#[cfg(test)]
101mod tests {
102 use {
103 super::{Endpoint, ScramLogin},
104 assert2::check,
105 krabka_client_core::{sasl::SaslCredentials, security::TrustStore},
106 krabka_security::{ListenerProtocol, SaslMechanism},
107 };
108
109 #[test]
110 fn a_sasl_ssl_endpoint_logs_in_with_scram_over_verified_tls() {
111 let endpoint = Endpoint::sasl_ssl("broker-1:9094", ScramLogin {
112 ca: "/work/tls/ca.pem".into(),
113 server_name: "broker-1".into(),
114 username: "soak".into(),
115 password: "secret".into(),
116 });
117 check!(endpoint.bootstrap == "broker-1:9094");
118 let security = endpoint.security.expect("a SASL_SSL endpoint is secured");
119 check!(security.protocol == ListenerProtocol::SaslSsl);
120 let tls = security.tls.expect("SASL_SSL carries a TLS config");
121 check!(tls.trust_store == TrustStore::PemFile("/work/tls/ca.pem".into()));
122 check!(tls.server_name == "broker-1");
123 let Some(SaslCredentials::Scram {
124 mechanism,
125 username,
126 password,
127 delegation_token,
128 }) = security.sasl
129 else {
130 panic!("a SASL_SSL endpoint logs in with SCRAM");
131 };
132 check!(
133 (
134 mechanism,
135 username.as_str(),
136 password.as_str(),
137 delegation_token
138 ) == (SaslMechanism::ScramSha512, "soak", "secret", false)
139 );
140 }
141
142 #[test]
143 fn a_plaintext_endpoint_is_anonymous() {
144 let endpoint = Endpoint::plaintext("localhost:9092");
145 check!(endpoint.security.is_none());
146 }
147}