sonic ast visitor approach. now we're getting faster.

BenchmarkParseMessage/relay/jsonstdlib-4              206   8630635 ns/op
BenchmarkParseMessage/relay/easyjson-4                278   4311793 ns/op
BenchmarkParseMessage/relay/simdjson-4                422   2943387 ns/op
BenchmarkParseMessage/relay/sonic-4                   849   1576884 ns/op

BenchmarkParseMessage/client/jsonstdlib-4             196   6140585 ns/op
BenchmarkParseMessage/client/easyjson-4               385   2826706 ns/op
BenchmarkParseMessage/client/simdjson-4               405   2628675 ns/op
BenchmarkParseMessage/client/sonic-4                  552   2413731 ns/op
This commit is contained in:
fiatjaf
2025-03-07 09:43:42 -03:00
parent cb74908f5d
commit 39bde22639
3 changed files with 450 additions and 165 deletions

View File

@ -42,10 +42,9 @@ func BenchmarkParseMessage(b *testing.B) {
})
b.Run("sonic", func(b *testing.B) {
smp := SonicMessageParser{}
for i := 0; i < b.N; i++ {
for _, msg := range messages {
_, _ = smp.ParseMessage(msg)
_, _ = ParseMessageSonic(msg)
}
}
})

View File

@ -2,184 +2,472 @@ package nostr
import (
"encoding/hex"
stdlibjson "encoding/json"
"fmt"
"github.com/bytedance/sonic/ast"
)
type SonicMessageParser struct{}
type sonicParserPosition int
func (smp *SonicMessageParser) ParseMessage(message []byte) (Envelope, error) {
var err error
const (
inEnvelope sonicParserPosition = iota
tlarr, _ := ast.NewParser(string(message)).Parse()
label, _ := tlarr.Index(0).StrictString()
inEvent
inReq
inOk
inEose
inCount
inAuth
inClose
inClosed
inNotice
var v Envelope
switch label {
case "EVENT":
env := &EventEnvelope{}
sndN := tlarr.Index(1)
var evtN *ast.Node
switch sndN.TypeSafe() {
case ast.V_STRING:
subId, _ := sndN.StrictString()
env.SubscriptionID = &subId
evtN = tlarr.Index(2)
case ast.V_OBJECT:
evtN = sndN
}
err = eventFromSonicAst(&env.Event, evtN)
v = env
case "REQ":
env := &ReqEnvelope{}
nodes, _ := tlarr.ArrayUseNode()
env.SubscriptionID, _ = nodes[1].StrictString()
env.Filters = make(Filters, len(nodes)-2)
for i, node := range nodes[2:] {
err = filterFromSonicAst(&env.Filters[i], &node)
}
v = env
case "COUNT":
env := &CountEnvelope{}
env.SubscriptionID, _ = tlarr.Index(1).StrictString()
trdN := tlarr.Index(2)
if countN := trdN.Get("count"); countN.Exists() {
count, _ := countN.Int64()
env.Count = &count
hll, _ := trdN.Get("hll").StrictString()
if len(hll) == 512 {
env.HyperLogLog, _ = hex.DecodeString(hll)
}
} else {
err = filterFromSonicAst(&env.Filter, trdN)
}
v = env
case "NOTICE":
notice, _ := tlarr.Index(1).StrictString()
env := NoticeEnvelope(notice)
v = &env
case "EOSE":
subId, _ := tlarr.Index(1).StrictString()
env := EOSEEnvelope(subId)
v = &env
case "OK":
env := &OKEnvelope{}
env.EventID, _ = tlarr.Index(1).StrictString()
env.OK, _ = tlarr.Index(2).Bool()
env.Reason, _ = tlarr.Index(3).StrictString()
v = env
case "AUTH":
env := &AuthEnvelope{}
sndN := tlarr.Index(1)
switch sndN.TypeSafe() {
case ast.V_STRING:
challenge, _ := sndN.StrictString()
env.Challenge = &challenge
case ast.V_OBJECT:
err = eventFromSonicAst(&env.Event, sndN)
}
v = env
case "CLOSED":
env := &ClosedEnvelope{}
env.SubscriptionID, _ = tlarr.Index(1).StrictString()
env.Reason, _ = tlarr.Index(2).StrictString()
v = env
case "CLOSE":
reason, _ := tlarr.Index(1).StrictString()
env := CloseEnvelope(reason)
v = &env
inFilterObject
inEventObject
inCountObject
inSince
inLimit
inUntil
inIds
inAuthors
inKinds
inSearch
inAFilterTag
inId
inCreatedAt
inKind
inContent
inPubkey
inSig
inTags
inAnEventTag
)
func (spp sonicParserPosition) String() string {
switch spp {
case inEnvelope:
return "inEnvelope"
case inEvent:
return "inEvent"
case inReq:
return "inReq"
case inOk:
return "inOk"
case inEose:
return "inEose"
case inCount:
return "inCount"
case inAuth:
return "inAuth"
case inClose:
return "inClose"
case inClosed:
return "inClosed"
case inNotice:
return "inNotice"
case inFilterObject:
return "inFilterObject"
case inEventObject:
return "inEventObject"
case inCountObject:
return "inCountObject"
case inSince:
return "inSince"
case inLimit:
return "inLimit"
case inUntil:
return "inUntil"
case inIds:
return "inIds"
case inAuthors:
return "inAuthors"
case inKinds:
return "inKinds"
case inAFilterTag:
return "inAFilterTag"
case inId:
return "inId"
case inCreatedAt:
return "inCreatedAt"
case inKind:
return "inKind"
case inContent:
return "inContent"
case inPubkey:
return "inPubkey"
case inSig:
return "inSig"
case inTags:
return "inTags"
case inAnEventTag:
return "inAnEventTag"
default:
return nil, UnknownLabel
return "<unexpected-spp>"
}
}
return v, err
type SonicMessageParser struct {
event *EventEnvelope
req *ReqEnvelope
ok *OKEnvelope
eose *EOSEEnvelope
count *CountEnvelope
auth *AuthEnvelope
close *CloseEnvelope
closed *ClosedEnvelope
notice *NoticeEnvelope
whereWeAre sonicParserPosition
currentEvent *Event
currentEventTag Tag
currentFilter *Filter
currentFilterTagList []string
currentFilterTagName string
mainEnvelope Envelope
}
func eventFromSonicAst(evt *Event, node *ast.Node) error {
evt.ID, _ = node.Get("id").StrictString()
evt.PubKey, _ = node.Get("pubkey").StrictString()
evt.Content, _ = node.Get("content").StrictString()
evt.Sig, _ = node.Get("sig").StrictString()
kind, _ := node.Get("kind").Int64()
evt.Kind = int(kind)
createdAt, _ := node.Get("created_at").Int64()
evt.CreatedAt = Timestamp(createdAt)
tagsN, err := node.Get("tags").ArrayUseNode()
if err != nil {
return fmt.Errorf("invalid tags: %w", err)
}
evt.Tags = make(Tags, len(tagsN))
for i, tagN := range tagsN {
itemsN, err := tagN.ArrayUseNode()
if err != nil {
return fmt.Errorf("invalid tag: %w", err)
}
tag := make(Tag, len(itemsN))
func (smp *SonicMessageParser) OnArrayBegin(capacity int) error {
// fmt.Println("***", "OnArrayBegin", "==", smp.whereWeAre)
for j, itemN := range itemsN {
tag[j], _ = itemN.StrictString()
switch smp.whereWeAre {
case inTags:
if smp.currentEvent.Tags == nil {
smp.currentEvent.Tags = make(Tags, 0, 10)
smp.currentEventTag = make(Tag, 0, 20)
} else {
smp.whereWeAre = inAnEventTag
}
case inAFilterTag:
// we have already created this
}
evt.Tags[i] = tag
return nil
}
func (smp *SonicMessageParser) OnArrayEnd() error {
// fmt.Println("***", "OnArrayEnd", "==", smp.whereWeAre)
switch smp.whereWeAre {
// envelopes
case inEvent:
smp.mainEnvelope = smp.event
case inReq:
smp.mainEnvelope = smp.req
case inOk:
smp.mainEnvelope = smp.ok
case inEose:
smp.mainEnvelope = smp.eose
case inCount:
smp.mainEnvelope = smp.count
case inAuth:
smp.mainEnvelope = smp.auth
case inClose:
smp.mainEnvelope = smp.close
case inClosed:
smp.mainEnvelope = smp.closed
case inNotice:
smp.mainEnvelope = smp.notice
// filter object properties
case inIds, inAuthors, inKinds, inSearch:
smp.whereWeAre = inFilterObject
case inAFilterTag:
smp.currentFilter.Tags[smp.currentFilterTagName] = smp.currentFilterTagList
// reuse the same underlying slice because we know nothing else will be appended to it
smp.currentFilterTagList = smp.currentFilterTagList[len(smp.currentFilterTagList):]
smp.whereWeAre = inFilterObject
// event object properties
case inAnEventTag:
smp.currentEvent.Tags = append(smp.currentEvent.Tags, smp.currentEventTag)
// reuse the same underlying slice because we know nothing else will be appended to it
smp.currentEventTag = smp.currentEventTag[len(smp.currentEventTag):]
smp.whereWeAre = inTags
case inTags:
smp.whereWeAre = inEventObject
default:
return fmt.Errorf("unexpected array end at %v", smp.whereWeAre)
}
return nil
}
func filterFromSonicAst(filter *Filter, node *ast.Node) error {
var err error
func (smp *SonicMessageParser) OnObjectBegin(capacity int) error {
// fmt.Println("***", "OnObjectBegin", "==", smp.whereWeAre)
node.ForEach(func(path ast.Sequence, node *ast.Node) bool {
switch *path.Key {
case "limit":
limit, _ := node.Int64()
filter.Limit = int(limit)
filter.LimitZero = filter.Limit == 0
case "since":
since, _ := node.Int64()
filter.Since = (*Timestamp)(&since)
case "until":
until, _ := node.Int64()
filter.Until = (*Timestamp)(&until)
case "search":
filter.Search, _ = node.StrictString()
case "ids":
idsN, _ := node.ArrayUseNode()
filter.IDs = make([]string, len(idsN))
for i, idN := range idsN {
filter.IDs[i], _ = idN.StrictString()
}
case "authors":
authorsN, _ := node.ArrayUseNode()
filter.Authors = make([]string, len(authorsN))
for i, authorN := range authorsN {
filter.Authors[i], _ = authorN.StrictString()
}
case "kinds":
kindsN, _ := node.ArrayUseNode()
filter.Kinds = make([]int, len(kindsN))
for i, kindN := range kindsN {
kind, _ := kindN.Int64()
filter.Kinds[i] = int(kind)
}
switch smp.whereWeAre {
case inEvent:
smp.whereWeAre = inEventObject
smp.currentEvent = &Event{}
case inAuth:
smp.whereWeAre = inEventObject
smp.currentEvent = &Event{}
case inReq:
smp.whereWeAre = inFilterObject
smp.currentFilter = &Filter{}
case inCount:
// set this temporarily, we will switch to a filterObject if we see "count" or "hll"
smp.whereWeAre = inFilterObject
smp.currentFilter = &Filter{}
default:
if len(*path.Key) > 1 && (*path.Key)[0] == '#' {
if filter.Tags == nil {
filter.Tags = make(TagMap, 2)
return fmt.Errorf("unexpected object begin at %v", smp.whereWeAre)
}
tagsN, _ := node.ArrayUseNode()
tags := make([]string, len(tagsN))
for i, authorN := range tagsN {
tags[i], _ = authorN.StrictString()
}
filter.Tags[(*path.Key)[1:]] = tags
} else {
err = fmt.Errorf("unexpected field '%s'", *path.Key)
return false
}
}
return true
})
return err
return nil
}
func (smp *SonicMessageParser) OnObjectKey(key string) error {
// fmt.Println("***", "OnObjectKey", key, "==", smp.whereWeAre)
switch smp.whereWeAre {
case inEventObject:
switch key {
case "id":
smp.whereWeAre = inId
case "sig":
smp.whereWeAre = inSig
case "pubkey":
smp.whereWeAre = inPubkey
case "content":
smp.whereWeAre = inContent
case "created_at":
smp.whereWeAre = inCreatedAt
case "kind":
smp.whereWeAre = inKind
case "tags":
smp.whereWeAre = inTags
default:
return fmt.Errorf("unexpected event attr %s", key)
}
case inFilterObject:
switch key {
case "limit":
smp.whereWeAre = inLimit
case "since":
smp.whereWeAre = inSince
case "until":
smp.whereWeAre = inUntil
case "ids":
smp.whereWeAre = inIds
smp.currentFilter.IDs = make([]string, 0, 25)
case "authors":
smp.whereWeAre = inAuthors
smp.currentFilter.Authors = make([]string, 0, 25)
case "kinds":
smp.whereWeAre = inKinds
smp.currentFilter.IDs = make([]string, 0, 12)
case "search":
smp.whereWeAre = inSearch
case "count", "hll":
// oops, switch to a countObject
smp.whereWeAre = inCountObject
default:
if len(key) > 1 && key[0] == '#' {
if smp.currentFilter.Tags == nil {
smp.currentFilter.Tags = make(TagMap, 1)
smp.currentFilterTagList = make([]string, 0, 25)
}
smp.whereWeAre = inAFilterTag
smp.currentFilterTagName = key[1:]
} else {
return fmt.Errorf("unexpected filter attr %s", key)
}
}
case inCountObject:
// we'll judge by the shape of the value so ignore this
default:
return fmt.Errorf("unexpected object key %s at %s", key, smp.whereWeAre)
}
return nil
}
func (smp *SonicMessageParser) OnObjectEnd() error {
// fmt.Println("***", "OnObjectEnd", "==", smp.whereWeAre)
switch smp.whereWeAre {
case inEventObject:
if smp.event != nil {
smp.event.Event = *smp.currentEvent
smp.whereWeAre = inEvent
} else {
smp.auth.Event = *smp.currentEvent
smp.whereWeAre = inAuth
}
case inFilterObject:
if smp.req != nil {
smp.req.Filters = append(smp.req.Filters, *smp.currentFilter)
smp.whereWeAre = inReq
} else {
smp.count.Filter = *smp.currentFilter
smp.whereWeAre = inCount
}
case inCountObject:
smp.whereWeAre = inCount
default:
return fmt.Errorf("unexpected object end at %s", smp.whereWeAre)
}
return nil
}
func (smp *SonicMessageParser) OnString(v string) error {
// fmt.Println("***", "OnString", v, "==", smp.whereWeAre)
switch smp.whereWeAre {
case inEnvelope:
switch v {
case "EVENT":
smp.event = &EventEnvelope{}
smp.whereWeAre = inEvent
case "REQ":
smp.req = &ReqEnvelope{Filters: make(Filters, 0, 1)}
smp.whereWeAre = inReq
case "OK":
smp.ok = &OKEnvelope{}
smp.whereWeAre = inOk
case "EOSE":
smp.whereWeAre = inEose
case "COUNT":
smp.count = &CountEnvelope{}
smp.whereWeAre = inCount
case "AUTH":
smp.auth = &AuthEnvelope{}
smp.whereWeAre = inAuth
case "CLOSE":
smp.whereWeAre = inClose
case "CLOSED":
smp.closed = &ClosedEnvelope{}
smp.whereWeAre = inClosed
case "NOTICE":
smp.whereWeAre = inNotice
}
// in an envelope
case inEvent:
smp.event.SubscriptionID = &v
case inReq:
smp.req.SubscriptionID = v
case inOk:
if smp.ok.EventID == "" {
smp.ok.EventID = v
} else {
smp.ok.Reason = v
}
case inEose:
smp.eose = (*EOSEEnvelope)(&v)
case inCount:
smp.count.SubscriptionID = v
case inAuth:
smp.auth.Challenge = &v
case inClose:
smp.close = (*CloseEnvelope)(&v)
case inClosed:
if smp.closed.SubscriptionID == "" {
smp.closed.SubscriptionID = v
} else {
smp.closed.Reason = v
}
case inNotice:
smp.notice = (*NoticeEnvelope)(&v)
// filter object properties
case inIds:
smp.currentFilter.IDs = append(smp.currentFilter.IDs, v)
case inAuthors:
smp.currentFilter.Authors = append(smp.currentFilter.Authors, v)
case inSearch:
smp.currentFilter.Search = v
smp.whereWeAre = inFilterObject
case inAFilterTag:
smp.currentFilterTagList = append(smp.currentFilterTagList, v)
// id object properties
case inId:
smp.currentEvent.ID = v
smp.whereWeAre = inEventObject
case inContent:
smp.currentEvent.Content = v
smp.whereWeAre = inEventObject
case inPubkey:
smp.currentEvent.PubKey = v
smp.whereWeAre = inEventObject
case inSig:
smp.currentEvent.Sig = v
smp.whereWeAre = inEventObject
case inAnEventTag:
smp.currentEventTag = append(smp.currentEventTag, v)
// count object properties
case inCountObject:
smp.count.HyperLogLog, _ = hex.DecodeString(v)
default:
return fmt.Errorf("unexpected string %s at %v", v, smp.whereWeAre)
}
return nil
}
func (smp *SonicMessageParser) OnInt64(v int64, _ stdlibjson.Number) error {
// fmt.Println("***", "OnInt64", v, "==", smp.whereWeAre)
switch smp.whereWeAre {
// event object
case inCreatedAt:
smp.currentEvent.CreatedAt = Timestamp(v)
smp.whereWeAre = inEventObject
case inKind:
smp.currentEvent.Kind = int(v)
smp.whereWeAre = inEventObject
// filter object
case inLimit:
smp.currentFilter.Limit = int(v)
smp.currentFilter.LimitZero = v == 0
case inSince:
smp.currentFilter.Since = (*Timestamp)(&v)
case inUntil:
smp.currentFilter.Until = (*Timestamp)(&v)
case inKinds:
smp.currentFilter.Kinds = append(smp.currentFilter.Kinds, int(v))
// count object
case inCountObject:
smp.count.Count = &v
}
return nil
}
func (smp *SonicMessageParser) OnBool(v bool) error {
// fmt.Println("***", "OnBool", v, "==", smp.whereWeAre)
if smp.whereWeAre == inOk {
smp.ok.OK = v
return nil
} else {
return fmt.Errorf("unexpected boolean")
}
}
func (_ SonicMessageParser) OnNull() error {
return fmt.Errorf("null shouldn't be anywhere in a message")
}
func (_ SonicMessageParser) OnFloat64(v float64, n stdlibjson.Number) error {
return fmt.Errorf("float shouldn't be anywhere in a message")
}
func ParseMessageSonic(message []byte) (Envelope, error) {
smp := &SonicMessageParser{}
smp.whereWeAre = inEnvelope
err := ast.Preorder(string(message), smp, nil)
return smp.mainEnvelope, err
}

View File

@ -4,7 +4,6 @@ import (
"testing"
"github.com/minio/simdjson-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -41,8 +40,8 @@ func TestParseMessage(t *testing.T) {
},
{
Name: "EVENT envelope with tags",
Message: []byte(`["EVENT",{"kind":3,"id":"9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2","pubkey":"373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7","created_at":1644844224,"tags":[["p","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],["p","75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"],["p","46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"]],"content":"{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}","sig":"811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}]`),
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 3, ID: "9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2", PubKey: "373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7", CreatedAt: 1644844224, Tags: Tags{Tag{"p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"}, Tag{"p", "75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"}, Tag{"p", "46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"}}, Content: "{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}", Sig: "811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}},
Message: []byte(`["EVENT",{"kind":3,"id":"9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2","pubkey":"373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7","created_at":1644844224,"tags":[["p","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],["e","75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"],["p","46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"]],"content":"{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}","sig":"811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}]`),
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 3, ID: "9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2", PubKey: "373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7", CreatedAt: 1644844224, Tags: Tags{Tag{"p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"}, Tag{"e", "75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"}, Tag{"p", "46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"}}, Content: "{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}", Sig: "811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}},
},
{
Name: "NOTICE envelope",
@ -115,12 +114,12 @@ func TestParseMessage(t *testing.T) {
}
if testCase.ExpectedEnvelope == nil {
assert.Nil(t, envelope, "expected nil but got %v", envelope)
require.Nil(t, envelope, "expected nil but got %v", envelope)
return
}
assert.NotNil(t, envelope, "expected non-nil envelope but got nil")
assert.Equal(t, testCase.ExpectedEnvelope.String(), envelope.String())
require.NotNil(t, envelope, "expected non-nil envelope but got nil")
require.Equal(t, testCase.ExpectedEnvelope.String(), envelope.String())
})
}
})
@ -148,10 +147,9 @@ func TestParseMessage(t *testing.T) {
})
t.Run("sonic", func(t *testing.T) {
smp := SonicMessageParser{}
for _, testCase := range testCases {
t.Run(testCase.Name, func(t *testing.T) {
envelope, err := smp.ParseMessage(testCase.Message)
envelope, err := ParseMessageSonic(testCase.Message)
if testCase.ExpectedEnvelope == nil && envelope == nil {
return
@ -164,7 +162,7 @@ func TestParseMessage(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, envelope, "expected non-nil envelope but got nil")
require.Equal(t, testCase.ExpectedEnvelope.String(), envelope.String())
require.Equal(t, testCase.ExpectedEnvelope, envelope)
})
}
})