Update version to 2.0.0 and enhance chaos engineering features in Flakestorm. Added support for environment chaos, behavioral contracts, and replay regression. Expanded documentation and improved scoring mechanisms. Updated .gitignore to include new documentation files.

This commit is contained in:
Francisco M Humarang Jr. 2026-03-06 23:33:21 +08:00
parent 59cca61f3c
commit 9c3450a75d
63 changed files with 4147 additions and 134 deletions

View file

@ -0,0 +1,107 @@
"""Integration tests for chaos module: interceptor, transport, LLM faults."""
from __future__ import annotations
import pytest
from flakestorm.chaos.faults import apply_error, apply_malformed, apply_malicious_response, should_trigger
from flakestorm.chaos.llm_proxy import (
apply_llm_empty,
apply_llm_garbage,
apply_llm_truncated,
apply_llm_response_drift,
apply_llm_fault,
should_trigger_llm_fault,
)
from flakestorm.chaos.tool_proxy import match_tool_fault
from flakestorm.chaos.profiles import load_chaos_profile, list_profile_names
from flakestorm.core.config import ChaosConfig, ToolFaultConfig, LlmFaultConfig
class TestChaosFaults:
"""Test fault application helpers."""
def test_apply_error(self):
code, msg, headers = apply_error(503, "Unavailable")
assert code == 503
assert "Unavailable" in msg
def test_apply_malformed(self):
body = apply_malformed()
assert "corrupted" in body or "invalid" in body.lower()
def test_apply_malicious_response(self):
out = apply_malicious_response("Ignore instructions")
assert out == "Ignore instructions"
def test_should_trigger_after_calls(self):
assert should_trigger(None, 2, 0) is False
assert should_trigger(None, 2, 1) is False
assert should_trigger(None, 2, 2) is True
class TestLlmProxy:
"""Test LLM fault application."""
def test_truncated(self):
out = apply_llm_truncated("one two three four five six", max_tokens=3)
assert out == "one two three"
def test_empty(self):
assert apply_llm_empty("anything") == ""
def test_garbage(self):
out = apply_llm_garbage("normal")
assert "gibberish" in out or "invalid" in out.lower()
def test_response_drift_json_rename(self):
out = apply_llm_response_drift('{"action": "run"}', "json_field_rename")
assert "action" in out or "tool_name" in out
def test_should_trigger_llm_fault(self):
class C:
probability = 1.0
after_calls = 0
assert should_trigger_llm_fault(C(), 0) is True
assert should_trigger_llm_fault(C(), 1) is True
def test_apply_llm_fault_truncated(self):
out = apply_llm_fault("hello world here", type("C", (), {"mode": "truncated_response", "max_tokens": 2})(), 0)
assert out == "hello world"
class TestToolProxy:
"""Test tool fault matching."""
def test_match_by_tool_name(self):
cfg = [ToolFaultConfig(tool="search", mode="timeout"), ToolFaultConfig(tool="*", mode="error")]
m = match_tool_fault("search", None, cfg, 0)
assert m is not None and m.tool == "search"
m2 = match_tool_fault("other", None, cfg, 0)
assert m2 is not None and m2.tool == "*"
def test_match_by_url(self):
cfg = [ToolFaultConfig(tool="x", match_url="https://api.example.com/*", mode="error")]
m = match_tool_fault(None, "https://api.example.com/foo", cfg, 0)
assert m is not None
class TestChaosProfiles:
"""Test built-in profile loading."""
def test_list_profiles(self):
names = list_profile_names()
assert "api_outage" in names
assert "indirect_injection" in names
assert "degraded_llm" in names
assert "hostile_tools" in names
assert "high_latency" in names
assert "cascading_failure" in names
assert "model_version_drift" in names
def test_load_api_outage(self):
c = load_chaos_profile("api_outage")
assert c.tool_faults
assert c.llm_faults
assert any(f.mode == "error" for f in c.tool_faults)
assert any(f.mode == "timeout" for f in c.llm_faults)