// Package testcontract 在回归中校验实际报文与公开 Schema,服务二进制不依赖此包。 package testcontract import ( "strings" "sync" "testing" "git.yuntuo.hk/k2safe/orbit/protocol/eventsv1" "github.com/santhosh-tekuri/jsonschema/v6" ) var eventOnce sync.Once var eventSchemas map[string]*jsonschema.Schema var eventError error // EventSchema 编译并缓存两个方向的 Schema;开启 date-time 等格式断言。 func EventSchema(t testing.TB, direction string) *jsonschema.Schema { t.Helper() eventOnce.Do(func() { compiler := jsonschema.NewCompiler() compiler.AssertFormat() doc, err := jsonschema.UnmarshalJSON(strings.NewReader(eventsv1.Schema)) if err != nil { eventError = err return } const resource = "https://git.yuntuo.hk/k2safe/orbit/schema/events.v1.json" if err := compiler.AddResource(resource, doc); err != nil { eventError = err return } eventSchemas = make(map[string]*jsonschema.Schema) for _, side := range []string{"client", "server"} { eventSchemas[side], eventError = compiler.Compile(resource + "#/$defs/" + side + "Frame") if eventError != nil { return } } }) if eventError != nil { t.Fatal(eventError) } schema := eventSchemas[direction] if schema == nil { t.Fatal("unknown Event protocol direction") } return schema } // EventFrame 验证真实传输的 JSON,不在错误中输出可能包含秘密的报文正文。 func EventFrame(t testing.TB, direction string, raw []byte) { t.Helper() value, err := jsonschema.UnmarshalJSON(strings.NewReader(string(raw))) if err != nil { t.Fatal("Event frame is not valid JSON") } if EventSchema(t, direction).Validate(value) != nil { t.Fatalf("%s Event frame violates published Schema", direction) } }