postgresql_commands/
pg_test_fsync.rs

1use crate::Settings;
2use crate::traits::CommandBuilder;
3use std::convert::AsRef;
4use std::ffi::{OsStr, OsString};
5use std::path::PathBuf;
6
7/// `pg_test_fsync` command to determine fastest `wal_sync_method` for `PostgreSQL`
8#[derive(Clone, Debug, Default)]
9pub struct PgTestFsyncBuilder {
10    program_dir: Option<PathBuf>,
11    envs: Vec<(OsString, OsString)>,
12    filename: Option<OsString>,
13    secs_per_test: Option<usize>,
14}
15
16impl PgTestFsyncBuilder {
17    /// Create a new [`PgTestFsyncBuilder`]
18    #[must_use]
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    /// Create a new [`PgTestFsyncBuilder`] from [Settings]
24    pub fn from(settings: &dyn Settings) -> Self {
25        Self::new().program_dir(settings.get_binary_dir())
26    }
27
28    /// Location of the program binary
29    #[must_use]
30    pub fn program_dir<P: Into<PathBuf>>(mut self, path: P) -> Self {
31        self.program_dir = Some(path.into());
32        self
33    }
34
35    /// Set the filename
36    #[must_use]
37    pub fn filename<S: AsRef<OsStr>>(mut self, filename: S) -> Self {
38        self.filename = Some(filename.as_ref().to_os_string());
39        self
40    }
41
42    /// Set the seconds per test
43    #[must_use]
44    pub fn secs_per_test(mut self, secs: usize) -> Self {
45        self.secs_per_test = Some(secs);
46        self
47    }
48}
49
50impl CommandBuilder for PgTestFsyncBuilder {
51    /// Get the program name
52    fn get_program(&self) -> &'static OsStr {
53        "pg_test_fsync".as_ref()
54    }
55
56    /// Location of the program binary
57    fn get_program_dir(&self) -> &Option<PathBuf> {
58        &self.program_dir
59    }
60
61    /// Get the arguments for the command
62    fn get_args(&self) -> Vec<OsString> {
63        let mut args: Vec<OsString> = Vec::new();
64
65        if let Some(filename) = &self.filename {
66            args.push("-f".into());
67            args.push(filename.into());
68        }
69
70        if let Some(secs) = &self.secs_per_test {
71            args.push("-s".into());
72            args.push(secs.to_string().into());
73        }
74
75        args
76    }
77
78    /// Get the environment variables for the command
79    fn get_envs(&self) -> Vec<(OsString, OsString)> {
80        self.envs.clone()
81    }
82
83    /// Set an environment variable for the command
84    fn env<S: AsRef<OsStr>>(mut self, key: S, value: S) -> Self {
85        self.envs
86            .push((key.as_ref().to_os_string(), value.as_ref().to_os_string()));
87        self
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94    use crate::TestSettings;
95    use crate::traits::CommandToString;
96    use test_log::test;
97
98    #[test]
99    fn test_builder_new() {
100        let command = PgTestFsyncBuilder::new().program_dir(".").build();
101        assert_eq!(
102            PathBuf::from(".").join("pg_test_fsync"),
103            PathBuf::from(command.to_command_string().replace('"', ""))
104        );
105    }
106
107    #[test]
108    fn test_builder_from() {
109        let command = PgTestFsyncBuilder::from(&TestSettings).build();
110        #[cfg(not(target_os = "windows"))]
111        let command_prefix = r#""./pg_test_fsync""#;
112        #[cfg(target_os = "windows")]
113        let command_prefix = r#"".\\pg_test_fsync""#;
114
115        assert_eq!(format!("{command_prefix}"), command.to_command_string());
116    }
117
118    #[test]
119    fn test_builder() {
120        let command = PgTestFsyncBuilder::new()
121            .env("PGDATABASE", "database")
122            .filename("filename")
123            .secs_per_test(10)
124            .build();
125        #[cfg(not(target_os = "windows"))]
126        let command_prefix = r#"PGDATABASE="database" "#;
127        #[cfg(target_os = "windows")]
128        let command_prefix = String::new();
129
130        assert_eq!(
131            format!(r#"{command_prefix}"pg_test_fsync" "-f" "filename" "-s" "10""#),
132            command.to_command_string()
133        );
134    }
135}