|
1 | 1 | use assert_cmd::cargo_bin_cmd; |
2 | 2 | use insta::assert_snapshot; |
| 3 | +#[cfg(target_os = "linux")] |
| 4 | +use sqlx::PgPool; |
3 | 5 | use std::path::Path; |
| 6 | +#[cfg(target_os = "linux")] |
| 7 | +use std::path::PathBuf; |
4 | 8 | use std::process::ExitStatus; |
5 | 9 | const CONFIG_PATH: &str = "tests/fixtures/postgres-language-server.jsonc"; |
6 | 10 |
|
@@ -125,6 +129,75 @@ fn check_directory_traversal_snapshot() { |
125 | 129 | )); |
126 | 130 | } |
127 | 131 |
|
| 132 | +#[cfg(target_os = "linux")] |
| 133 | +fn get_database_url(pool: &PgPool) -> String { |
| 134 | + let opts = pool.connect_options(); |
| 135 | + format!( |
| 136 | + "postgres://postgres:postgres@{}:{}/{}", |
| 137 | + opts.get_host(), |
| 138 | + opts.get_port(), |
| 139 | + opts.get_database().unwrap_or("postgres") |
| 140 | + ) |
| 141 | +} |
| 142 | + |
| 143 | +#[cfg(target_os = "linux")] |
| 144 | +fn create_temp_sql_file(contents: &str) -> PathBuf { |
| 145 | + let path = std::env::temp_dir().join(format!( |
| 146 | + "pgls-tls-{}-{}.sql", |
| 147 | + std::process::id(), |
| 148 | + std::time::SystemTime::now() |
| 149 | + .duration_since(std::time::UNIX_EPOCH) |
| 150 | + .expect("system clock should be after unix epoch") |
| 151 | + .as_nanos() |
| 152 | + )); |
| 153 | + |
| 154 | + std::fs::write(&path, contents).expect("failed to write temporary SQL file"); |
| 155 | + path |
| 156 | +} |
| 157 | + |
| 158 | +#[cfg(target_os = "linux")] |
| 159 | +#[sqlx::test(migrator = "pgls_test_utils::MIGRATIONS")] |
| 160 | +async fn check_accepts_tls_connection_strings(test_db: PgPool) { |
| 161 | + let sql_file = create_temp_sql_file("select 1;\n"); |
| 162 | + let connection_string = format!( |
| 163 | + "{}?sslmode=require&channel_binding=require", |
| 164 | + get_database_url(&test_db) |
| 165 | + ); |
| 166 | + |
| 167 | + let mut cmd = cargo_bin_cmd!("postgres-language-server"); |
| 168 | + let output = cmd |
| 169 | + .args([ |
| 170 | + "check", |
| 171 | + sql_file |
| 172 | + .to_str() |
| 173 | + .expect("temporary SQL file path should be valid UTF-8"), |
| 174 | + "--connection-string", |
| 175 | + &connection_string, |
| 176 | + "--log-level", |
| 177 | + "none", |
| 178 | + ]) |
| 179 | + .output() |
| 180 | + .expect("failed to run CLI"); |
| 181 | + |
| 182 | + let stdout = String::from_utf8_lossy(&output.stdout); |
| 183 | + let stderr = String::from_utf8_lossy(&output.stderr); |
| 184 | + |
| 185 | + assert!( |
| 186 | + output.status.success(), |
| 187 | + "expected TLS-backed check to succeed\nstdout:\n{stdout}\nstderr:\n{stderr}" |
| 188 | + ); |
| 189 | + assert!( |
| 190 | + !stdout.contains("TLS upgrade required") && !stderr.contains("TLS upgrade required"), |
| 191 | + "TLS support error should not appear\nstdout:\n{stdout}\nstderr:\n{stderr}" |
| 192 | + ); |
| 193 | + assert!( |
| 194 | + stdout.contains("Checked 1 file"), |
| 195 | + "expected successful CLI output\nstdout:\n{stdout}\nstderr:\n{stderr}" |
| 196 | + ); |
| 197 | + |
| 198 | + std::fs::remove_file(sql_file).expect("failed to remove temporary SQL file"); |
| 199 | +} |
| 200 | + |
128 | 201 | fn run_check(args: &[&str]) -> String { |
129 | 202 | let mut full_args = vec!["--config-path", CONFIG_PATH, "--log-level", "none"]; |
130 | 203 | full_args.extend_from_slice(args); |
|
0 commit comments