update grid4 & heroledger models

This commit is contained in:
Timur Gordon
2025-09-16 14:18:08 +02:00
parent cb1fb0f0ec
commit 53e9a2d4f0
31 changed files with 3216 additions and 399 deletions

View File

@@ -0,0 +1,125 @@
use heromodels::db::postgres::{Config, Postgres};
use heromodels::db::{Collection, Db};
use heromodels::models::grid4::node::node_index::{country, nodegroupid, pubkey};
use heromodels::models::grid4::node::{ComputeSlice, DeviceInfo, Node};
use heromodels_core::Model;
// Requires local Postgres (user=postgres password=test123 host=localhost port=5432)
// Run with: cargo test -p heromodels --test grid4_postgres -- --ignored
#[test]
#[ignore]
fn grid4_node_postgres_roundtrip_like_example() {
let db = Postgres::new(
Config::new()
.user(Some("postgres".into()))
.password(Some("test123".into()))
.host(Some("localhost".into()))
.port(Some(5432)),
)
.expect("can connect to Postgres");
let nodes = db.collection::<Node>().expect("open node collection");
// Clean existing
if let Ok(existing) = nodes.get_all() {
for n in existing {
let _ = nodes.delete_by_id(n.get_id());
}
}
// Build and store multiple nodes via builder and then persist via collection.set(), like examples
let cs1 = ComputeSlice::new()
.nodeid(10)
.slice_id(1)
.mem_gb(32.0)
.storage_gb(512.0)
.passmark(5000)
.vcores(16)
.gpus(1)
.price_cc(0.25);
let cs2 = ComputeSlice::new()
.nodeid(10)
.slice_id(2)
.mem_gb(64.0)
.storage_gb(2048.0)
.passmark(7000)
.vcores(24)
.gpus(2)
.price_cc(0.50);
let cs3 = ComputeSlice::new()
.nodeid(11)
.slice_id(1)
.mem_gb(16.0)
.storage_gb(256.0)
.passmark(3000)
.vcores(8)
.gpus(0)
.price_cc(0.10);
let dev = DeviceInfo { vendor: "ACME".into(), ..Default::default() };
let n1 = Node::new()
.nodegroupid(99)
.uptime(97)
.add_compute_slice(cs1)
.devices(dev.clone())
.country("BE")
.pubkey("PG_NODE_1")
.build();
let n2 = Node::new()
.nodegroupid(99)
.uptime(96)
.add_compute_slice(cs2)
.devices(dev.clone())
.country("NL")
.pubkey("PG_NODE_2")
.build();
let n3 = Node::new()
.nodegroupid(7)
.uptime(95)
.add_compute_slice(cs3)
.devices(dev)
.country("BE")
.pubkey("PG_NODE_3")
.build();
let (id1, s1) = nodes.set(&n1).expect("store n1");
let (id2, s2) = nodes.set(&n2).expect("store n2");
let (id3, s3) = nodes.set(&n3).expect("store n3");
assert!(id1 > 0 && id2 > 0 && id3 > 0);
// Query by top-level indexes similar to the example style
let be_nodes = nodes.get::<country, _>("BE").expect("by country");
assert_eq!(be_nodes.len(), 2);
let grp_99 = nodes.get::<nodegroupid, _>(&99).expect("by group");
assert_eq!(grp_99.len(), 2);
let by_key = nodes.get::<pubkey, _>("PG_NODE_2").expect("by pubkey");
assert_eq!(by_key.len(), 1);
assert_eq!(by_key[0].get_id(), id2);
// Update: change country of n1
let updated = s1.clone().country("DE");
let (_, back) = nodes.set(&updated).expect("update n1");
assert_eq!(back.country, "DE");
// Cardinality after update
let de_nodes = nodes.get::<country, _>("DE").expect("by country DE");
assert_eq!(de_nodes.len(), 1);
// Delete by id and by index
nodes.delete_by_id(id2).expect("delete n2 by id");
assert!(nodes.get_by_id(id2).unwrap().is_none());
nodes.delete::<pubkey, _>("PG_NODE_3").expect("delete n3 by pubkey");
assert!(nodes.get_by_id(id3).unwrap().is_none());
// Remaining should be updated n1 only; verify via targeted queries
let de_nodes = nodes.get::<country, _>("DE").expect("country DE after deletes");
assert_eq!(de_nodes.len(), 1);
assert_eq!(de_nodes[0].get_id(), id1);
let by_key = nodes.get::<pubkey, _>("PG_NODE_1").expect("by pubkey PG_NODE_1");
assert_eq!(by_key.len(), 1);
assert_eq!(by_key[0].get_id(), id1);
}