62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
// 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)
|
||
}
|
||
}
|