mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-04-26 21:06:21 +02:00
135 lines
3.3 KiB
Go
135 lines
3.3 KiB
Go
package formalspec
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestVerifyPipeline_ValidTrace(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
history := []Transition{
|
|
{From: StateInit, To: StateScanning, Guard: "event_received"},
|
|
{From: StateScanning, To: StateDedup, Guard: "no_secrets_found"},
|
|
{From: StateDedup, To: StateCorrelate, Guard: "not_duplicate"},
|
|
{From: StateCorrelate, To: StatePersist, Guard: "correlation_done"},
|
|
{From: StatePersist, To: StateDecisionLog, Guard: "persisted"},
|
|
{From: StateDecisionLog, To: StateComplete, Guard: "logged"},
|
|
}
|
|
|
|
results := v.VerifyPipeline(StateComplete, history)
|
|
for _, r := range results {
|
|
if !r.Passed {
|
|
t.Errorf("invariant %s failed: %s", r.Name, r.Details)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVerifyPipeline_SecretDetected(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
history := []Transition{
|
|
{From: StateInit, To: StateScanning, Guard: "event_received"},
|
|
{From: StateScanning, To: StateError, Guard: "secret_detected"},
|
|
}
|
|
|
|
results := v.VerifyPipeline(StateError, history)
|
|
for _, r := range results {
|
|
if !r.Passed {
|
|
t.Errorf("invariant %s failed for secret path", r.Name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVerifyPipeline_DedupSkip(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
history := []Transition{
|
|
{From: StateInit, To: StateScanning, Guard: "event_received"},
|
|
{From: StateScanning, To: StateDedup, Guard: "no_secrets_found"},
|
|
{From: StateDedup, To: StateComplete, Guard: "is_duplicate"},
|
|
}
|
|
|
|
results := v.VerifyPipeline(StateComplete, history)
|
|
for _, r := range results {
|
|
if !r.Passed {
|
|
t.Errorf("invariant %s failed for dedup skip", r.Name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVerifyPipeline_SkipScanner_Violation(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
// Invalid: skips secret scanner.
|
|
history := []Transition{
|
|
{From: StateInit, To: StateDedup, Guard: "event_received"},
|
|
}
|
|
|
|
results := v.VerifyPipeline(StateDedup, history)
|
|
scannerInvariant := results[0] // SecretScannerAlwaysFirst
|
|
if scannerInvariant.Passed {
|
|
t.Error("should fail when scanner is skipped")
|
|
}
|
|
}
|
|
|
|
func TestVerifyChain_Valid(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
chain := []ChainEntry{
|
|
{Index: 0, Hash: "aaa", PreviousHash: "genesis"},
|
|
{Index: 1, Hash: "bbb", PreviousHash: "aaa"},
|
|
{Index: 2, Hash: "ccc", PreviousHash: "bbb"},
|
|
}
|
|
|
|
results := v.VerifyChain(chain)
|
|
for _, r := range results {
|
|
if !r.Passed {
|
|
t.Errorf("chain invariant %s failed: %s", r.Name, r.Details)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVerifyChain_BrokenLink(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
chain := []ChainEntry{
|
|
{Index: 0, Hash: "aaa", PreviousHash: "genesis"},
|
|
{Index: 1, Hash: "bbb", PreviousHash: "WRONG"},
|
|
}
|
|
|
|
results := v.VerifyChain(chain)
|
|
continuity := results[1] // ChainContinuity
|
|
if continuity.Passed {
|
|
t.Error("should fail on broken chain link")
|
|
}
|
|
}
|
|
|
|
func TestVerifyChain_BadGenesis(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
chain := []ChainEntry{
|
|
{Index: 0, Hash: "aaa", PreviousHash: "not-genesis"},
|
|
}
|
|
|
|
results := v.VerifyChain(chain)
|
|
genesis := results[0]
|
|
if genesis.Passed {
|
|
t.Error("should fail on bad genesis")
|
|
}
|
|
}
|
|
|
|
func TestStats(t *testing.T) {
|
|
v := NewSpecVerifier()
|
|
|
|
v.VerifyPipeline(StateComplete, []Transition{
|
|
{From: StateInit, To: StateScanning, Guard: "event_received"},
|
|
})
|
|
v.VerifyChain([]ChainEntry{
|
|
{Index: 0, Hash: "a", PreviousHash: "genesis"},
|
|
})
|
|
|
|
stats := v.Stats()
|
|
if stats.TotalChecks != 7 { // 3 pipeline + 4 chain
|
|
t.Errorf("total = %d, want 7", stats.TotalChecks)
|
|
}
|
|
}
|