Skip to content

Commit 866e68e

Browse files
committed
ccm: add support for updateconf
1 parent 8a29378 commit 866e68e

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

scylla/tests/ccm_integration/ccm/cluster.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,56 @@ impl Node {
263263
env
264264
}
265265

266+
/// Executes `ccm updateconf` and applies it for this node.
267+
/// It accepts the key-value pairs to update the configuration.
268+
///
269+
/// ### Example
270+
/// ```
271+
/// # use crate::ccm::cluster::Node;
272+
/// # async fn check_only_compiles(node: &Node) -> Result<(), Box<dyn Error>> {
273+
/// let args = [
274+
/// ("client_encryption_options.enabled", "true"),
275+
/// ("client_encryption_options.certificate", "db.cert"),
276+
/// ("client_encryption_options.keyfile", "db.key"),
277+
/// ];
278+
///
279+
/// node.updateconf(args).await?
280+
/// # Ok(())
281+
/// # }
282+
/// ```
283+
///
284+
/// The code above is equivalent to the following scylla.yaml:
285+
/// ```yaml
286+
/// client_encryption_options:
287+
/// enabled: true
288+
/// certificate: db.cert
289+
/// keyfile: db.key
290+
/// ```
291+
pub(crate) async fn updateconf<K, V>(
292+
&self,
293+
key_values: impl IntoIterator<Item = (K, V)>,
294+
) -> Result<(), Error>
295+
where
296+
K: AsRef<str>,
297+
V: AsRef<str>,
298+
{
299+
let config_dir = &self.config_dir;
300+
let mut args: Vec<String> = vec![
301+
self.opts.name(),
302+
"updateconf".to_string(),
303+
"--config-dir".to_string(),
304+
config_dir.to_string_lossy().into_owned(),
305+
];
306+
for (k, v) in key_values.into_iter() {
307+
args.push(format!("{}:{}", k.as_ref(), v.as_ref()));
308+
}
309+
310+
self.logged_cmd
311+
.run_command("ccm", &args, RunOptions::new())
312+
.await?;
313+
Ok(())
314+
}
315+
266316
/// This method starts the node. User can provide optional [`NodeStartOptions`] to control the behavior of the node start.
267317
/// If `None` is provided, the default options are used (see the implementation of Default for [`NodeStartOptions`]).
268318
pub(crate) async fn start(&mut self, opts: Option<NodeStartOptions>) -> Result<(), Error> {
@@ -580,6 +630,55 @@ impl Cluster {
580630
Ok(())
581631
}
582632

633+
/// Executes `ccm updateconf` and applies it for all nodes in the cluster.
634+
/// It accepts the key-value pairs to update the configuration.
635+
///
636+
/// ### Example
637+
/// ```
638+
/// # use crate::ccm::cluster::Cluster;
639+
/// # async fn check_only_compiles(cluster: &Cluster) -> Result<(), Box<dyn Error>> {
640+
/// let args = [
641+
/// ("client_encryption_options.enabled", "true"),
642+
/// ("client_encryption_options.certificate", "db.cert"),
643+
/// ("client_encryption_options.keyfile", "db.key"),
644+
/// ];
645+
///
646+
/// cluster.updateconf(args).await?
647+
/// # Ok(())
648+
/// # }
649+
/// ```
650+
///
651+
/// The code above is equivalent to the following scylla.yaml:
652+
/// ```yaml
653+
/// client_encryption_options:
654+
/// enabled: true
655+
/// certificate: db.cert
656+
/// keyfile: db.key
657+
/// ```
658+
pub(crate) async fn updateconf<K, V>(
659+
&self,
660+
key_values: impl IntoIterator<Item = (K, V)>,
661+
) -> Result<(), Error>
662+
where
663+
K: AsRef<str>,
664+
V: AsRef<str>,
665+
{
666+
let config_dir = self.config_dir();
667+
let mut args: Vec<String> = vec![
668+
"updateconf".to_string(),
669+
"--config-dir".to_string(),
670+
config_dir.to_string_lossy().into_owned(),
671+
];
672+
for (k, v) in key_values.into_iter() {
673+
args.push(format!("{}:{}", k.as_ref(), v.as_ref()));
674+
}
675+
676+
self.logged_cmd
677+
.run_command("ccm", &args, RunOptions::new())
678+
.await?;
679+
Ok(())
680+
}
681+
583682
fn get_ccm_env(&self) -> HashMap<String, String> {
584683
let mut env: HashMap<String, String> = HashMap::new();
585684
env.insert(

scylla/tests/ccm_integration/ccm/mod.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,58 @@ where
8181
test_body(Arc::clone(&wrapper.0)).await;
8282
std::mem::drop(wrapper);
8383
}
84+
85+
/// Run a CCM test with a custom configuration logic before the cluster starts.
86+
///
87+
/// ### Example
88+
/// ```
89+
/// # use crate::ccm::cluster::Cluster;
90+
/// # use crate::ccm::run_ccm_test_with_configuration;
91+
/// # use std::sync::{Arc, Mutex};
92+
/// async fn configure_cluster(cluster: Cluster) -> Cluster {
93+
/// // Do some configuration here
94+
/// cluster.updateconf([("foo", "bar")]).await.expect("failed to update conf");
95+
/// cluster
96+
/// }
97+
///
98+
/// async fn test(cluster: Arc<Mutex<Cluster>>) {
99+
/// let cluster = cluster.lock().await;
100+
/// let session = cluster.make_session_builder().await.build().await.unwrap();
101+
///
102+
/// println!("Succesfully connected to the cluster!");
103+
/// }
104+
///
105+
/// run_ccm_test_with_configuration(ClusterOptions::default, configure_cluster, test).await;
106+
/// ```
107+
pub(crate) async fn run_ccm_test_with_configuration<C, Conf, ConfFut, T, TFut>(
108+
make_cluster_options: C,
109+
configure: Conf,
110+
test_body: T,
111+
) where
112+
C: FnOnce() -> ClusterOptions,
113+
Conf: FnOnce(Cluster) -> ConfFut,
114+
ConfFut: Future<Output = Cluster>,
115+
T: FnOnce(Arc<tokio::sync::Mutex<Cluster>>) -> TFut,
116+
TFut: Future<Output = ()>,
117+
{
118+
let cluster_options = make_cluster_options();
119+
let mut cluster = Cluster::new(cluster_options)
120+
.await
121+
.expect("Failed to create cluster");
122+
cluster.init().await.expect("failed to initialize cluster");
123+
cluster = configure(cluster).await;
124+
cluster.start(None).await.expect("failed to start cluster");
125+
126+
struct ClusterWrapper(Arc<tokio::sync::Mutex<Cluster>>);
127+
impl Drop for ClusterWrapper {
128+
fn drop(&mut self) {
129+
if std::thread::panicking() && *TEST_KEEP_CLUSTER_ON_FAILURE {
130+
println!("Test failed, keep cluster alive, TEST_KEEP_CLUSTER_ON_FAILURE=true");
131+
self.0.blocking_lock().set_keep_on_drop(true);
132+
}
133+
}
134+
}
135+
let wrapper = ClusterWrapper(Arc::new(tokio::sync::Mutex::new(cluster)));
136+
test_body(Arc::clone(&wrapper.0)).await;
137+
std::mem::drop(wrapper);
138+
}

0 commit comments

Comments
 (0)