Skip to content

Commit 8ebc662

Browse files
authored
Merge pull request #20 from cuteolaf/test/platform-server
test(platform-server): add comprehensive unit tests
2 parents 7cb4a33 + a9243f9 commit 8ebc662

File tree

7 files changed

+851
-0
lines changed

7 files changed

+851
-0
lines changed

crates/platform-server/src/data_api.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,78 @@ pub async fn get_snapshot(
266266
total_stake,
267267
}))
268268
}
269+
270+
#[cfg(test)]
271+
mod tests {
272+
use super::*;
273+
274+
#[test]
275+
fn test_now_returns_timestamp() {
276+
let timestamp = now();
277+
// Should be a reasonable Unix timestamp (after 2020)
278+
assert!(timestamp > 1577836800); // Jan 1, 2020
279+
// Should be less than far future (year 2100)
280+
assert!(timestamp < 4102444800); // Jan 1, 2100
281+
}
282+
283+
#[test]
284+
fn test_now_increases() {
285+
let t1 = now();
286+
std::thread::sleep(std::time::Duration::from_millis(10));
287+
let t2 = now();
288+
assert!(t2 >= t1);
289+
}
290+
291+
#[test]
292+
fn test_list_tasks_query_default_limit() {
293+
let query = ListTasksQuery { limit: None };
294+
assert_eq!(query.limit, None);
295+
}
296+
297+
#[test]
298+
fn test_list_tasks_query_with_limit() {
299+
let query = ListTasksQuery { limit: Some(50) };
300+
assert_eq!(query.limit, Some(50));
301+
}
302+
303+
#[test]
304+
fn test_snapshot_query_default_epoch() {
305+
let query = SnapshotQuery { epoch: None };
306+
assert_eq!(query.epoch, None);
307+
}
308+
309+
#[test]
310+
fn test_snapshot_query_with_epoch() {
311+
let query = SnapshotQuery { epoch: Some(100) };
312+
assert_eq!(query.epoch, Some(100));
313+
}
314+
315+
#[test]
316+
fn test_snapshot_response_serialization() {
317+
let response = SnapshotResponse {
318+
epoch: 10,
319+
snapshot_time: 1234567890,
320+
leaderboard: vec![],
321+
validators: vec![],
322+
total_stake: 1000,
323+
};
324+
325+
let json = serde_json::to_string(&response).unwrap();
326+
assert!(json.contains("\"epoch\":10"));
327+
assert!(json.contains("\"total_stake\":1000"));
328+
}
329+
330+
#[test]
331+
fn test_renew_request_deserialization() {
332+
let json = r#"{
333+
"validator_hotkey": "test_validator",
334+
"signature": "test_sig",
335+
"ttl_seconds": 300
336+
}"#;
337+
338+
let request: RenewRequest = serde_json::from_str(json).unwrap();
339+
assert_eq!(request.validator_hotkey, "test_validator");
340+
assert_eq!(request.signature, "test_sig");
341+
assert_eq!(request.ttl_seconds, 300);
342+
}
343+
}

crates/platform-server/src/db/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,21 @@ async fn create_pool(database_url: &str) -> Result<DbPool> {
5454
let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls)?;
5555
Ok(pool)
5656
}
57+
58+
#[cfg(test)]
59+
mod tests {
60+
use super::*;
61+
62+
#[test]
63+
fn test_db_pool_type() {
64+
// Test that DbPool is correctly aliased to Pool
65+
let rt = tokio::runtime::Runtime::new().unwrap();
66+
rt.block_on(async {
67+
let pool_result = create_pool("postgresql://localhost/test").await;
68+
if let Ok(_pool) = pool_result {
69+
// Pool type should match DbPool
70+
let _typed: DbPool = _pool;
71+
}
72+
});
73+
}
74+
}

crates/platform-server/src/db/schema.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,91 @@ INSERT INTO network_state (key, value) VALUES
218218
('challenge_id', '')
219219
ON CONFLICT (key) DO NOTHING;
220220
"#;
221+
222+
#[cfg(test)]
223+
mod tests {
224+
use super::*;
225+
226+
#[test]
227+
fn test_schema_sql_contains_tables() {
228+
// Verify that the schema SQL contains all expected table definitions
229+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS validators"));
230+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS challenge_config"));
231+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS submissions"));
232+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS evaluations"));
233+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS leaderboard"));
234+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS task_leases"));
235+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS events"));
236+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS network_state"));
237+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS challenges"));
238+
assert!(SCHEMA_SQL.contains("CREATE TABLE IF NOT EXISTS evaluation_jobs"));
239+
}
240+
241+
#[test]
242+
fn test_schema_sql_contains_indexes() {
243+
// Verify that the schema SQL contains index definitions
244+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_submissions_miner"));
245+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_submissions_epoch"));
246+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_evaluations_agent"));
247+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_leaderboard_rank"));
248+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_task_leases_validator"));
249+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_events_type"));
250+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_challenges_status"));
251+
assert!(SCHEMA_SQL.contains("CREATE INDEX IF NOT EXISTS idx_jobs_status"));
252+
}
253+
254+
#[test]
255+
fn test_schema_sql_contains_initial_data() {
256+
// Verify initial network state data
257+
assert!(SCHEMA_SQL.contains("INSERT INTO network_state"));
258+
assert!(SCHEMA_SQL.contains("current_epoch"));
259+
assert!(SCHEMA_SQL.contains("current_block"));
260+
assert!(SCHEMA_SQL.contains("total_stake"));
261+
assert!(SCHEMA_SQL.contains("challenge_id"));
262+
}
263+
264+
#[test]
265+
fn test_schema_sql_contains_foreign_keys() {
266+
// Verify foreign key relationships
267+
assert!(SCHEMA_SQL.contains("REFERENCES submissions(id)"));
268+
}
269+
270+
#[test]
271+
fn test_schema_sql_contains_unique_constraints() {
272+
// Verify unique constraints
273+
assert!(SCHEMA_SQL.contains("UNIQUE(submission_id, validator_hotkey)"));
274+
assert!(SCHEMA_SQL.contains("agent_hash VARCHAR(128) NOT NULL UNIQUE"));
275+
}
276+
277+
#[test]
278+
fn test_schema_sql_default_values() {
279+
// Verify default values are set correctly with specific column checks
280+
assert!(SCHEMA_SQL.contains("status VARCHAR(32) DEFAULT 'pending'"));
281+
assert!(SCHEMA_SQL.contains("status VARCHAR(32) DEFAULT 'active'"));
282+
assert!(SCHEMA_SQL.contains("is_active BOOLEAN DEFAULT TRUE"));
283+
assert!(SCHEMA_SQL.contains("stake BIGINT NOT NULL DEFAULT 0"));
284+
assert!(SCHEMA_SQL.contains("gpu_required BOOLEAN DEFAULT FALSE"));
285+
assert!(SCHEMA_SQL.contains("is_healthy BOOLEAN DEFAULT FALSE"));
286+
assert!(SCHEMA_SQL.contains("DEFAULT NOW()"));
287+
}
288+
289+
#[test]
290+
fn test_schema_sql_jsonb_fields() {
291+
// Verify JSONB columns exist for flexible data
292+
assert!(SCHEMA_SQL.contains("module_whitelist JSONB"));
293+
assert!(SCHEMA_SQL.contains("model_whitelist JSONB"));
294+
assert!(SCHEMA_SQL.contains("pricing_config JSONB"));
295+
assert!(SCHEMA_SQL.contains("evaluation_config JSONB"));
296+
assert!(SCHEMA_SQL.contains("task_results JSONB"));
297+
assert!(SCHEMA_SQL.contains("payload JSONB"));
298+
}
299+
300+
#[test]
301+
fn test_schema_sql_timestamp_fields() {
302+
// Verify timestamp fields are properly defined
303+
assert!(SCHEMA_SQL.contains("created_at TIMESTAMPTZ"));
304+
assert!(SCHEMA_SQL.contains("updated_at TIMESTAMPTZ"));
305+
assert!(SCHEMA_SQL.contains("expires_at TIMESTAMPTZ"));
306+
assert!(SCHEMA_SQL.contains("last_seen TIMESTAMPTZ"));
307+
}
308+
}

0 commit comments

Comments
 (0)