use tensor_wasm_core::error::TensorWasmError;
use tensor_wasm_core::types::TenantId;
use tensor_wasm_tenant::{TenantContext, TenantRegistry};
#[test]
fn gpu_consume_accepts_owner_rejects_foreign() {
let (reg, _admin) = TenantRegistry::new();
let (ctx_a, cap_a) = reg
.register_with_capability(
TenantContext::builder(TenantId(1))
.with_gpu_memory_bytes_cap(1 << 20)
.build(),
)
.unwrap();
let (_ctx_b, cap_b) = reg
.register_with_capability(
TenantContext::builder(TenantId(2))
.with_gpu_memory_bytes_cap(1 << 20)
.build(),
)
.unwrap();
ctx_a
.consume_gpu_bytes_with_capability(&cap_a, 4096)
.unwrap();
assert_eq!(ctx_a.gpu_bytes_in_use(), 4096);
let err = ctx_a
.consume_gpu_bytes_with_capability(&cap_b, 1024)
.expect_err("foreign capability must be rejected");
match err {
TensorWasmError::TenantIsolationViolation { tenant_id, .. } => {
assert_eq!(tenant_id, TenantId(2));
}
other => panic!("expected TenantIsolationViolation, got {other:?}"),
}
assert_eq!(
ctx_a.gpu_bytes_in_use(),
4096,
"rejected foreign consume must not perturb the counter"
);
}
#[test]
fn gpu_release_accepts_owner_rejects_foreign() {
let (reg, _admin) = TenantRegistry::new();
let (ctx_a, cap_a) = reg
.register_with_capability(TenantContext::builder(TenantId(10)).build())
.unwrap();
let (_ctx_b, cap_b) = reg
.register_with_capability(TenantContext::builder(TenantId(11)).build())
.unwrap();
ctx_a
.consume_gpu_bytes_with_capability(&cap_a, 8192)
.unwrap();
assert_eq!(ctx_a.gpu_bytes_in_use(), 8192);
let err = ctx_a
.release_gpu_bytes_with_capability(&cap_b, 4096)
.expect_err("foreign capability must be rejected on release");
assert!(matches!(
err,
TensorWasmError::TenantIsolationViolation { .. }
));
assert_eq!(
ctx_a.gpu_bytes_in_use(),
8192,
"rejected foreign release must not move the counter"
);
ctx_a
.release_gpu_bytes_with_capability(&cap_a, 4096)
.unwrap();
assert_eq!(ctx_a.gpu_bytes_in_use(), 4096);
}
#[test]
fn gpu_consume_with_capability_still_enforces_cap() {
let (reg, _admin) = TenantRegistry::new();
let (ctx, cap) = reg
.register_with_capability(
TenantContext::builder(TenantId(20))
.with_gpu_memory_bytes_cap(1024)
.build(),
)
.unwrap();
let err = ctx
.consume_gpu_bytes_with_capability(&cap, 2048)
.expect_err("over-cap consume must be refused even with a valid capability");
assert!(matches!(err, TensorWasmError::GpuMemoryExhausted { .. }));
assert_eq!(ctx.gpu_bytes_in_use(), 0);
}