Skip to content

Commit e22e78d

Browse files
committed
added diags and fixed tests
1 parent 0ab97a9 commit e22e78d

File tree

7 files changed

+952
-728
lines changed

7 files changed

+952
-728
lines changed

README.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,38 +158,45 @@ The tests provided can be performed with a [`stackql`](https://github.com/stackq
158158
> curl -L https://bit.ly/stackql-zip -O && unzip stackql-zip
159159
> ```
160160
161-
To run the examples and integration tests you will need to set invalid AWS credentials (to test an error condition), use this:
162-
163-
```bash
164-
export AWS_ACCESS_KEY_ID="DUMMYKEYID"
165-
export AWS_SECRET_ACCESS_KEY="DUMMYSECRETACCESSKEY"
166-
```
167-
168161
#### Without TLS
169162
170163
To test the library with a local server *without* tls, run the following:
171164
172165
```bash
173166
sh start-server.sh
174167
cargo test --test integration
168+
# or with verbose output
169+
RUST_LOG=debug cargo test --test integration -- --nocapture
175170
sh stop-server.sh
176171
```
177172
178-
To run the examples:
173+
To run the examples with a local server *without* tls, use the following:
179174

180175
```bash
181176
sh start-server.sh
182-
RUST_LOG=debug cargo run --example simple_query # debug mode
183177
cargo run --example simple_query
178+
# or with verbose output
179+
RUST_LOG=debug cargo run --example simple_query
184180
sh stop-server.sh
185181
```
186-
#### Without TLS
182+
#### With TLS
187183

188184
To test the library with a local server *with* tls, run the following:
189185

186+
```bash
187+
sh start-secure-server.sh
188+
cargo test --test integration_mtls
189+
# or with verbose output
190+
RUST_LOG=debug cargo test --test integration_mtls -- --nocapture
191+
sh stop-server.sh
192+
```
193+
To run the examples with a local server *with* tls, use the following:
194+
190195
```bash
191196
sh start-secure-server.sh
192197
cargo run --example simple_query_with_mtls
198+
# or with verbose output
199+
RUST_LOG=debug cargo run --example simple_query_with_mtls
193200
sh stop-server.sh
194201
```
195202

examples/simple_query.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
8888
//
8989
print_heading("REGISTRY PULL examples");
9090
execute_query(&conn, "REGISTRY PULL homebrew");
91-
execute_query(&conn, "REGISTRY PULL github");
9291

9392
//
9493
// simple select with one row
@@ -129,7 +128,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
129128
print_heading("StackQL SELECT example");
130129
execute_query(
131130
&conn,
132-
"SELECT id, name, description, stargazers_count FROM github.repos.repos WHERE org = 'stackql' AND name = 'stackql'",
131+
"SELECT * FROM homebrew.formula.vw_info WHERE formula_name = 'stackql'",
133132
);
134133

135134
Ok(())

examples/simple_query_with_mtls.rs

Lines changed: 147 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,81 @@
1-
// examples/simple_query_with_mtls.rs
1+
// example/simple_query_with_mtls.rs
2+
// Example demonstrating using PgwireLite with mutual TLS (mTLS)
23

3-
use pgwire_lite::PgwireLite;
4+
use colorize::AnsiColor;
5+
use pgwire_lite::{PgwireLite, Value};
46
use std::env;
57
use std::path::PathBuf;
68

7-
fn main() {
8-
// Get the home directory and properly construct paths
9+
fn print_heading(title: &str) {
10+
let title_owned = title.to_string(); // Convert &str to String
11+
println!("{}", title_owned.blue().bold());
12+
}
13+
14+
// Pretty print a row with formatting
15+
fn print_row(row: &std::collections::HashMap<String, Value>, index: usize) {
16+
if index == 0 {
17+
// Print header
18+
println!("Row {}: {{", index);
19+
} else {
20+
println!("\nRow {}: {{", index);
21+
}
22+
23+
for (key, value) in row {
24+
println!(
25+
" {}: {}",
26+
key.clone().green(),
27+
format!("{}", value).yellow()
28+
);
29+
}
30+
println!("}}");
31+
}
32+
33+
fn execute_query(conn: &PgwireLite, query: &str) {
34+
match conn.query(query) {
35+
Ok(result) => {
36+
println!();
37+
38+
println!("Elapsed time: {} ms", result.elapsed_time_ms);
39+
40+
println!("Result status: {:?}", result.status);
41+
42+
println!(
43+
"{} columns, {} rows, {} notices",
44+
result.col_count, result.row_count, result.notice_count
45+
);
46+
47+
if !result.column_names.is_empty() {
48+
println!("Column names: {:?}", result.column_names);
49+
}
50+
51+
if !result.rows.is_empty() {
52+
println!("Data:");
53+
for (i, row) in result.rows.iter().enumerate() {
54+
print_row(row, i);
55+
}
56+
}
57+
58+
if !result.notices.is_empty() {
59+
println!("Notices (detail):");
60+
for notice in result.notices.iter() {
61+
if let Some(detail) = notice.fields.get("detail") {
62+
println!("{}", detail);
63+
}
64+
}
65+
}
66+
println!();
67+
}
68+
Err(e) => eprintln!("Error: {}", e),
69+
}
70+
}
71+
72+
fn setup_tls() {
73+
// Set up environment variables for TLS
974
let home_dir = env::var("HOME").expect("Could not find HOME environment variable");
1075
let ssl_dir = PathBuf::from(&home_dir).join("ssl-test");
11-
12-
// Set environment variables with absolute paths
13-
env::set_var("PGSSLMODE", "verify-full");
76+
77+
// Configure TLS settings
78+
env::set_var("PGSSLMODE", "verify-ca"); // Use verify-ca instead of verify-full to bypass hostname check
1479
env::set_var(
1580
"PGSSLCERT",
1681
ssl_dir
@@ -29,14 +94,80 @@ fn main() {
2994
.to_string_lossy()
3095
.to_string(),
3196
);
97+
98+
// Disable hostname verification for testing purposes
99+
env::set_var("PGSSLSNI", "0");
100+
}
32101

33-
// Create the connection with SSL enabled
34-
let conn =
35-
PgwireLite::new("localhost", 5444, true, "verbose").expect("Failed to create connection");
102+
fn main() -> Result<(), Box<dyn std::error::Error>> {
103+
env_logger::init();
104+
105+
// Setup TLS environment variables
106+
setup_tls();
36107

37-
// Try to execute a simple query
38-
match conn.query("SELECT 1 as col_name") {
39-
Ok(result) => println!("Query result (TLS): {:?}", result),
40-
Err(e) => eprintln!("Error: {}", e),
41-
}
42-
}
108+
// Create a connection configuration with TLS enabled
109+
// Using IP address instead of hostname to avoid certificate validation issues
110+
let conn = PgwireLite::new("127.0.0.1", 5444, true, "verbose")?;
111+
112+
println!();
113+
println!("libpq version: {}", conn.libpq_version());
114+
println!("Verbosity set to: {}", conn.verbosity());
115+
println!("TLS connection: Enabled");
116+
println!();
117+
118+
//
119+
// registry list example
120+
//
121+
print_heading("REGISTRY LIST example");
122+
execute_query(&conn, "REGISTRY LIST aws");
123+
124+
//
125+
// registry pull examples
126+
//
127+
print_heading("REGISTRY PULL examples");
128+
execute_query(&conn, "REGISTRY PULL homebrew");
129+
130+
//
131+
// simple select with one row
132+
//
133+
print_heading("Literal SELECT example (one row)");
134+
execute_query(&conn, "SELECT 1 as col_name");
135+
136+
//
137+
// simple select with no rows
138+
//
139+
print_heading("Literal SELECT example (no rows)");
140+
execute_query(&conn, "SELECT 1 as col_name WHERE 1=0");
141+
142+
//
143+
// failed command - handle expected error
144+
//
145+
print_heading("Failed command example");
146+
execute_query(&conn, "NOTACOMMAND");
147+
148+
//
149+
// stackql provider select, multiple rows
150+
//
151+
print_heading("StackQL SELECT example (multiple rows)");
152+
execute_query(
153+
&conn,
154+
"SELECT * FROM homebrew.formula.vw_usage_metrics WHERE formula_name IN ('stackql','steampipe')",
155+
);
156+
157+
//
158+
// stackql provider select, provider error, no rows
159+
//
160+
print_heading("StackQL SELECT example with provider error and no rows");
161+
execute_query(&conn, "SELECT id, name, description, stargazers_count FROM github.repos.repos WHERE org = 'nonexistent-org'");
162+
163+
//
164+
// another stackql provider select, should succeed
165+
//
166+
print_heading("StackQL SELECT example");
167+
execute_query(
168+
&conn,
169+
"SELECT * FROM homebrew.formula.vw_info WHERE formula_name = 'stackql'",
170+
);
171+
172+
Ok(())
173+
}

src/connection.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,35 @@ impl PgwireLite {
216216
// Create a fresh connection for this query
217217
let conn = Connection::new(&conn_str)?;
218218

219+
// Connection diagnostics
220+
unsafe {
221+
222+
let ssl_in_use = libpq_sys::PQsslInUse((&conn).into()) != 0;
223+
let host_ptr = libpq_sys::PQhost((&conn).into());
224+
let port_ptr = libpq_sys::PQport((&conn).into());
225+
if !host_ptr.is_null() && !port_ptr.is_null() {
226+
let host = CStr::from_ptr(host_ptr).to_string_lossy();
227+
let port = CStr::from_ptr(port_ptr).to_string_lossy();
228+
debug!("Connected to: {}:{} (ssl: {})", host, port, ssl_in_use);
229+
}
230+
231+
// PQstatus output
232+
let status = libpq_sys::PQstatus((&conn).into());
233+
debug!("Connection status: {:?}", status);
234+
235+
// PQtransactionStatus output
236+
let tx_status = libpq_sys::PQtransactionStatus((&conn).into());
237+
debug!("Transaction status: {:?}", tx_status);
238+
239+
// PQserverVersion output
240+
let server_version = libpq_sys::PQserverVersion((&conn).into());
241+
let major = server_version / 10000;
242+
let minor = (server_version / 100) % 100;
243+
let revision = server_version % 100;
244+
debug!("Server version: {}.{}.{} ({})", major, minor, revision, server_version);
245+
246+
}
247+
219248
// Apply the desired verbosity level
220249
debug!("Setting error verbosity to: {:?}", self.verbosity);
221250
unsafe {

0 commit comments

Comments
 (0)