返回 DeepSeek-Reasonix
audit_forwarding_test.go
根目录 / internal / boot / audit_forwarding_test.go
1 package boot
2
3 import (
4 "reflect"
5 "testing"
6 "time"
7
8 "reasonix/internal/config"
9 "reasonix/internal/control"
10 "reasonix/internal/event"
11 "reasonix/internal/notify"
12 "reasonix/internal/stats"
13 "reasonix/internal/trajectory"
14 )
15
16 // The shared forwarder is why a new capability no longer has to be repeated at
17 // every layer, so it must itself be complete.
18 func TestAuditForwarderCoversEveryCapability(t *testing.T) {
19 fwd := reflect.TypeFor[event.AuditForwarder]()
20 required := reflect.TypeFor[event.OptionalSinkCapabilities]()
21 for i := range required.NumMethod() {
22 method := required.Method(i)
23 if _, ok := fwd.MethodByName(method.Name); !ok {
24 t.Errorf("event.AuditForwarder does not forward %s; every embedder loses it", method.Name)
25 }
26 }
27 }
28
29 // A wrapper that forwards one audit but forgets another drops its data
30 // silently, with the tests still green. Pure forwarders should embed
31 // event.AuditForwarder instead of repeating the capability methods.
32 func TestAuditCapabilitiesAreForwardedByEveryWrapper(t *testing.T) {
33 required := reflect.TypeFor[event.OptionalSinkCapabilities]()
34 wrappers := []event.Sink{
35 event.Sync(event.Discard),
36 event.Coalesce(event.Discard, time.Millisecond),
37 event.NewCostQuoteSink(event.Discard, nil),
38 control.NewGoalUsageTee(event.Discard),
39 notify.NewSink(event.Discard, nil, config.NotificationsConfig{}),
40 &trajectory.Recorder{},
41 &stats.Recorder{},
42 }
43 for _, w := range wrappers {
44 wt := reflect.TypeOf(w)
45 for i := range required.NumMethod() {
46 method := required.Method(i)
47 if _, ok := wt.MethodByName(method.Name); !ok {
48 t.Errorf("%s does not forward %s: the host signal dies at this wrapper", wt, method.Name)
49 }
50 }
51 }
52 }
53
53 lines GO