1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
//! Wire-Backend Feature Tests for FraiseQL Server
//!
//! These tests verify the wire-backend feature implementation:
//! - Feature flag compilation (with and without wire-backend)
//! - Adapter initialization for both PostgreSQL and Wire adapters
//! - Arrow Flight service compatibility with both adapters
//! - Query execution with both adapters
//! - Memory efficiency characteristics of Wire adapter
//!
//! Run with:
//! - Default (PostgreSQL): `cargo test --test wire_backend_feature_test`
//! - Wire-backend: `cargo test --test wire_backend_feature_test --features wire-backend`
//!
//! **Execution engine:** none
//! **Infrastructure:** none
//! **Parallelism:** safe
#![allow(clippy::unwrap_used, clippy::print_stdout, clippy::print_stderr)] // Reason: test code, panics acceptable
#![allow(clippy::cast_precision_loss)] // Reason: test metrics reporting
#![allow(clippy::cast_sign_loss)] // Reason: test data uses small positive integers
#![allow(clippy::cast_possible_truncation)] // Reason: test data values are bounded
#![allow(clippy::cast_possible_wrap)] // Reason: test data values are bounded
#![allow(clippy::cast_lossless)] // Reason: test code readability
#![allow(clippy::missing_panics_doc)] // Reason: test helper functions
#![allow(clippy::missing_errors_doc)] // Reason: test helper functions
#![allow(missing_docs)] // Reason: test code
#![allow(clippy::items_after_statements)] // Reason: test helpers near use site
#![allow(clippy::used_underscore_binding)] // Reason: test variables use _ prefix
#![allow(clippy::needless_pass_by_value)] // Reason: test helper signatures
#![allow(clippy::match_same_arms)] // Reason: test data clarity
#![allow(clippy::branches_sharing_code)] // Reason: test assertion clarity
#![allow(clippy::undocumented_unsafe_blocks)] // Reason: test exercises unsafe paths
mod common;
// ============================================================================
// Feature-Gated Adapter Tests
// ============================================================================
/// Test that the correct adapter type is selected based on feature flags.
/// This test documents the compilation contract of the feature.
#[test]
fn test_adapter_selection_compile_time() {
// This test verifies at compile time that:
// - Without wire-backend feature: PostgreSQL adapter is selected
// - With wire-backend feature: Wire adapter is selected
//
// If this compiles, the feature gates are correctly configured.
#[cfg(not(feature = "wire-backend"))]
{
// PostgreSQL adapter should be available
use fraiseql_core::db::PostgresAdapter;
let _ = std::marker::PhantomData::<PostgresAdapter>;
}
#[cfg(feature = "wire-backend")]
{
// Wire adapter should be available
use fraiseql_core::db::FraiseWireAdapter;
let _ = std::marker::PhantomData::<FraiseWireAdapter>;
}
}
// ============================================================================
// PostgreSQL Adapter Tests (Default Feature)
// ============================================================================
#[cfg(not(feature = "wire-backend"))]
mod postgres_adapter_tests {
use fraiseql_core::db::PostgresAdapter;
/// Test PostgreSQL adapter initialization without wire-backend feature.
#[tokio::test]
async fn test_postgres_adapter_initialization_default() {
let Ok(db_url) = std::env::var("DATABASE_URL") else {
eprintln!("Skipping: DATABASE_URL not set");
return;
};
let adapter = PostgresAdapter::new(&db_url).await;
assert!(adapter.is_ok(), "PostgresAdapter initialization failed: {:?}", adapter.err());
}
/// Test PostgreSQL adapter with pool configuration (default feature).
#[tokio::test]
async fn test_postgres_adapter_with_pool_config_default() {
let Ok(db_url) = std::env::var("DATABASE_URL") else {
eprintln!("Skipping: DATABASE_URL not set");
return;
};
let adapter = PostgresAdapter::with_pool_config(
&db_url,
fraiseql_core::db::postgres::PoolPrewarmConfig {
min_size: 5,
max_size: 20,
timeout_secs: None,
},
)
.await;
assert!(adapter.is_ok(), "PostgresAdapter with pool config failed: {:?}", adapter.err());
// Verify adapter can be cloned for use in server
let adapter = adapter.unwrap();
drop(adapter);
}
}
// ============================================================================
// Wire Adapter Tests (wire-backend Feature)
// ============================================================================
#[cfg(feature = "wire-backend")]
mod wire_adapter_tests {
use fraiseql_core::db::FraiseWireAdapter;
/// Test Wire adapter initialization with wire-backend feature.
#[test]
fn test_wire_adapter_initialization() {
let db_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| {
"postgresql://fraiseql:fraiseql_password@localhost:5432/fraiseql_test".to_string()
});
// FraiseWireAdapter constructor is synchronous
let adapter = FraiseWireAdapter::new(&db_url);
// Verify we got a valid adapter
drop(adapter);
}
/// Test Wire adapter with custom chunk size configuration.
#[test]
fn test_wire_adapter_with_chunk_size() {
let db_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| {
"postgresql://fraiseql:fraiseql_password@localhost:5432/fraiseql_test".to_string()
});
let adapter = FraiseWireAdapter::new(&db_url).with_chunk_size(512);
// Verify configuration was applied
drop(adapter);
}
/// Test that Wire adapter is truly a different type from PostgreSQL adapter.
/// This verifies the feature gate correctly swaps the implementation.
#[test]
fn test_wire_adapter_is_correct_type() {
use std::any::type_name;
use fraiseql_core::db::FraiseWireAdapter;
let db_url = "postgresql://localhost/test";
let adapter = FraiseWireAdapter::new(db_url);
// Verify runtime type name contains "FraiseWireAdapter"
let type_str = type_name::<FraiseWireAdapter>();
assert!(
type_str.contains("FraiseWire"),
"Expected FraiseWireAdapter type, got: {}",
type_str
);
let adapter_type = type_name_of(&adapter);
assert!(
adapter_type.contains("FraiseWire"),
"Expected FraiseWireAdapter instance, got: {}",
adapter_type
);
}
fn type_name_of<T>(_: &T) -> &'static str {
std::any::type_name::<T>()
}
}
// ============================================================================
// Feature Compilation Tests
// ============================================================================
/// Test that server can be initialized with the feature-gated adapter.
/// This is a smoke test to ensure initialization code compiles and runs.
#[cfg(not(feature = "wire-backend"))]
#[tokio::test]
async fn test_feature_gated_main_initialization_postgres() {
// This test verifies the main.rs feature gates work correctly for PostgreSQL.
// We test the adapter initialization logic that's gated in main.rs.
let Ok(db_url) = std::env::var("DATABASE_URL") else {
eprintln!("Skipping: DATABASE_URL not set");
return;
};
// Verify PostgreSQL initialization code path
use fraiseql_core::db::{PostgresAdapter, postgres::PoolPrewarmConfig};
let adapter = PostgresAdapter::with_pool_config(
&db_url,
PoolPrewarmConfig {
min_size: 5,
max_size: 20,
timeout_secs: None,
},
)
.await;
assert!(adapter.is_ok(), "PostgreSQL adapter initialization failed");
}
/// Test that server can be initialized with Wire adapter when feature is enabled.
#[cfg(feature = "wire-backend")]
#[test]
fn test_feature_gated_main_initialization_wire() {
// This test verifies the main.rs feature gates work correctly for Wire adapter.
let db_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| {
"postgresql://fraiseql:fraiseql_password@localhost:5432/fraiseql_test".to_string()
});
// Verify Wire adapter initialization code path
use fraiseql_core::db::FraiseWireAdapter;
let _adapter = FraiseWireAdapter::new(&db_url);
// No async needed, Wire adapter is sync
}
// ============================================================================
// Arrow Flight Integration Tests
// ============================================================================
// Arrow Flight tests - only available when arrow feature is enabled
#[cfg(feature = "arrow")]
mod arrow_flight_tests {
#[cfg(not(feature = "wire-backend"))]
#[test]
fn test_flight_service_postgres_adapter_wrapping() {
use fraiseql_core::db::PostgresAdapter;
let _db_url = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgresql://localhost/test".to_string());
// Marker to show test exists
let _ = std::marker::PhantomData::<PostgresAdapter>;
}
#[cfg(feature = "wire-backend")]
#[test]
fn test_flight_service_wire_adapter_wrapping() {
use std::sync::Arc;
use fraiseql_core::db::FraiseWireAdapter;
let db_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| {
"postgresql://fraiseql:fraiseql_password@localhost:5432/fraiseql_test".to_string()
});
let adapter = Arc::new(FraiseWireAdapter::new(&db_url));
let _flight_adapter = fraiseql_server::arrow::FlightDatabaseAdapter::from_arc(adapter);
}
}
// ============================================================================
// Documentation and Contract Tests
// ============================================================================
/// Documents the expected memory characteristics of the wire-backend feature.
/// These are informational tests that document the design contract.
#[test]
fn test_wire_backend_design_contract() {
// Wire backend is designed for:
// 1. Large result sets (100K+ rows)
// 2. Memory-constrained environments
// 3. Streaming queries
//
// Memory usage expectation: ~1.3 KB regardless of result set size
// vs PostgreSQL: ~260 MB for 1M rows
//
// This test documents that expectation for VelocityBench benchmarking.
#[cfg(feature = "wire-backend")]
{
// When wire-backend is enabled, this is the recommended adapter
println!("wire-backend feature: ENABLED");
println!("Recommended use: Large result sets, memory-constrained environments");
println!("Expected memory: ~1.3 KB");
}
#[cfg(not(feature = "wire-backend"))]
{
// When wire-backend is not enabled, PostgreSQL is used
println!("wire-backend feature: DISABLED");
println!("Using: PostgresAdapter with connection pooling");
println!("Memory scales with result set size");
}
}
/// Documents the compilation contract for this feature.
#[test]
fn test_feature_compilation_contract() {
// This crate must compile cleanly with:
// 1. No features (default = PostgreSQL)
// 2. --features wire-backend (Wire adapter)
// 3. --features arrow (Arrow Flight with PostgreSQL)
// 4. --features arrow,wire-backend (Arrow Flight with Wire adapter)
//
// If all four compile, the feature gates are correctly configured.
println!("Feature compilation contract verified:");
println!("✓ Base configuration (PostgreSQL)");
#[cfg(feature = "wire-backend")]
println!("✓ wire-backend feature");
#[cfg(feature = "arrow")]
println!("✓ arrow feature");
#[cfg(all(feature = "arrow", feature = "wire-backend"))]
println!("✓ arrow + wire-backend features");
}