1 Star 0 Fork 0

muicx / quickfix

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
validation_test.go 18.68 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
package quickfix
import (
"bytes"
"testing"
"time"
"github.com/quickfixgo/quickfix/datadictionary"
"github.com/stretchr/testify/assert"
)
type validateTest struct {
TestName string
Validator Validator
MessageBytes []byte
ExpectedRejectReason int
ExpectedRefTagID *Tag
DoNotExpectReject bool
}
func TestValidate(t *testing.T) {
var tests = []validateTest{
tcInvalidTagNumberHeader(),
tcInvalidTagNumberBody(),
tcInvalidTagNumberTrailer(),
tcTagSpecifiedWithoutAValue(),
tcInvalidMsgType(),
tcValueIsIncorrect(),
tcIncorrectDataFormatForValue(),
tcTagSpecifiedOutOfRequiredOrderHeader(),
tcTagSpecifiedOutOfRequiredOrderTrailer(),
tcTagSpecifiedOutOfRequiredOrderDisabledHeader(),
tcTagSpecifiedOutOfRequiredOrderDisabledTrailer(),
tcTagAppearsMoreThanOnce(),
tcFloatValidation(),
tcTagNotDefinedForMessage(),
tcTagIsDefinedForMessage(),
tcFieldNotFoundBody(),
tcFieldNotFoundHeader(),
tcInvalidTagCheckDisabled(),
tcInvalidTagCheckEnabled(),
}
msg := NewMessage()
for _, test := range tests {
assert.Nil(t, ParseMessage(msg, bytes.NewBuffer(test.MessageBytes)))
reject := test.Validator.Validate(msg)
switch {
case reject == nil && test.DoNotExpectReject:
continue
case reject != nil && test.DoNotExpectReject:
t.Errorf("%v: Unexpected reject: %v", test.TestName, reject)
continue
case reject == nil:
t.Errorf("%v: Expected reject", test.TestName)
continue
}
if reject.RejectReason() != test.ExpectedRejectReason {
t.Errorf("%v: Expected reason %v got %v", test.TestName, test.ExpectedRejectReason, reject.RejectReason())
}
switch {
case reject.RefTagID() == nil && test.ExpectedRefTagID == nil:
//ok, expected and actual ref tag not set
case reject.RefTagID() != nil && test.ExpectedRefTagID == nil:
t.Errorf("%v: Unexpected RefTag '%v'", test.TestName, *reject.RefTagID())
case reject.RefTagID() == nil && test.ExpectedRefTagID != nil:
t.Errorf("%v: Expected RefTag '%v'", test.TestName, *test.ExpectedRefTagID)
case *reject.RefTagID() == *test.ExpectedRefTagID:
//ok, tags equal
default:
t.Errorf("%v: Expected RefTag '%v' got '%v'", test.TestName, *test.ExpectedRefTagID, *reject.RefTagID())
}
}
}
func createFIX40NewOrderSingle() *Message {
msg := NewMessage()
msg.Header.SetField(tagMsgType, FIXString("D"))
msg.Header.SetField(tagBeginString, FIXString("FIX.4.0"))
msg.Header.SetField(tagBodyLength, FIXString("0"))
msg.Header.SetField(tagSenderCompID, FIXString("0"))
msg.Header.SetField(tagTargetCompID, FIXString("0"))
msg.Header.SetField(tagMsgSeqNum, FIXString("0"))
msg.Header.SetField(tagSendingTime, FIXUTCTimestamp{Time: time.Now()})
msg.Body.SetField(Tag(11), FIXString("A"))
msg.Body.SetField(Tag(21), FIXString("1"))
msg.Body.SetField(Tag(55), FIXString("A"))
msg.Body.SetField(Tag(54), FIXString("1"))
msg.Body.SetField(Tag(40), FIXString("1"))
msg.Body.SetField(Tag(38), FIXInt(5))
msg.Body.SetField(Tag(100), FIXString("0"))
msg.Trailer.SetField(tagCheckSum, FIXString("000"))
return msg
}
func createFIX43NewOrderSingle() *Message {
msg := NewMessage()
msg.Header.SetField(tagMsgType, FIXString("D"))
msg.Header.SetField(tagBeginString, FIXString("FIX.4.3"))
msg.Header.SetField(tagBodyLength, FIXString("0"))
msg.Header.SetField(tagSenderCompID, FIXString("0"))
msg.Header.SetField(tagTargetCompID, FIXString("0"))
msg.Header.SetField(tagMsgSeqNum, FIXString("0"))
msg.Header.SetField(tagSendingTime, FIXUTCTimestamp{Time: time.Now()})
msg.Body.SetField(Tag(11), FIXString("A"))
msg.Body.SetField(Tag(21), FIXString("1"))
msg.Body.SetField(Tag(55), FIXString("A"))
msg.Body.SetField(Tag(54), FIXString("1"))
msg.Body.SetField(Tag(38), FIXInt(5))
msg.Body.SetField(Tag(40), FIXString("1"))
msg.Body.SetField(Tag(60), FIXUTCTimestamp{Time: time.Now()})
msg.Trailer.SetField(tagCheckSum, FIXString("000"))
return msg
}
func tcInvalidTagNumberHeader() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
invalidHeaderFieldMessage := createFIX40NewOrderSingle()
tag := Tag(9999)
invalidHeaderFieldMessage.Header.SetField(tag, FIXString("hello"))
msgBytes := invalidHeaderFieldMessage.build()
return validateTest{
TestName: "Invalid Tag Number Header",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonInvalidTagNumber,
ExpectedRefTagID: &tag,
}
}
func tcInvalidTagNumberBody() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
invalidBodyFieldMessage := createFIX40NewOrderSingle()
tag := Tag(9999)
invalidBodyFieldMessage.Body.SetField(tag, FIXString("hello"))
msgBytes := invalidBodyFieldMessage.build()
return validateTest{
TestName: "Invalid Tag Number Body",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonInvalidTagNumber,
ExpectedRefTagID: &tag,
}
}
func tcInvalidTagNumberTrailer() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
invalidTrailerFieldMessage := createFIX40NewOrderSingle()
tag := Tag(9999)
invalidTrailerFieldMessage.Trailer.SetField(tag, FIXString("hello"))
msgBytes := invalidTrailerFieldMessage.build()
return validateTest{
TestName: "Invalid Tag Number Trailer",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonInvalidTagNumber,
ExpectedRefTagID: &tag,
}
}
func tcTagNotDefinedForMessage() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
invalidMsg := createFIX40NewOrderSingle()
tag := Tag(41)
invalidMsg.Body.SetField(tag, FIXString("hello"))
msgBytes := invalidMsg.build()
return validateTest{
TestName: "Tag Not Defined For Message",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonTagNotDefinedForThisMessageType,
ExpectedRefTagID: &tag,
}
}
func tcTagIsDefinedForMessage() validateTest {
//compare to tcTagIsNotDefinedForMessage
dict, _ := datadictionary.Parse("spec/FIX43.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
validMsg := createFIX43NewOrderSingle()
msgBytes := validMsg.build()
return validateTest{
TestName: "TagIsDefinedForMessage",
Validator: validator,
MessageBytes: msgBytes,
DoNotExpectReject: true,
}
}
func tcFieldNotFoundBody() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
invalidMsg1 := NewMessage()
invalidMsg1.Header.SetField(tagMsgType, FIXString("D")).
SetField(tagBeginString, FIXString("FIX.4.0")).
SetField(tagBodyLength, FIXString("0")).
SetField(tagSenderCompID, FIXString("0")).
SetField(tagTargetCompID, FIXString("0")).
SetField(tagMsgSeqNum, FIXString("0")).
SetField(tagSendingTime, FIXUTCTimestamp{Time: time.Now()})
invalidMsg1.Trailer.SetField(tagCheckSum, FIXString("000"))
invalidMsg1.Body.SetField(Tag(11), FIXString("A")).
SetField(Tag(21), FIXString("A")).
SetField(Tag(55), FIXString("A")).
SetField(Tag(54), FIXString("A")).
SetField(Tag(38), FIXString("A"))
tag := Tag(40)
//ord type is required
//invalidMsg1.Body.SetField(Tag(40), "A"))
msgBytes := invalidMsg1.build()
return validateTest{
TestName: "FieldNotFoundBody",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonRequiredTagMissing,
ExpectedRefTagID: &tag,
}
}
func tcFieldNotFoundHeader() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
invalidMsg2 := NewMessage()
invalidMsg2.Trailer.SetField(tagCheckSum, FIXString("000"))
invalidMsg2.Body.SetField(Tag(11), FIXString("A")).
SetField(Tag(21), FIXString("A")).
SetField(Tag(55), FIXString("A")).
SetField(Tag(54), FIXString("A")).
SetField(Tag(38), FIXString("A"))
invalidMsg2.Header.SetField(tagMsgType, FIXString("D")).
SetField(tagBeginString, FIXString("FIX.4.0")).
SetField(tagBodyLength, FIXString("0")).
SetField(tagSenderCompID, FIXString("0")).
SetField(tagTargetCompID, FIXString("0")).
SetField(tagMsgSeqNum, FIXString("0"))
//sending time is required
//invalidMsg2.Header.FieldMap.SetField(tag.SendingTime, "0"))
tag := tagSendingTime
msgBytes := invalidMsg2.build()
return validateTest{
TestName: "FieldNotFoundHeader",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonRequiredTagMissing,
ExpectedRefTagID: &tag,
}
}
func tcTagSpecifiedWithoutAValue() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
bogusTag := Tag(109)
builder.Body.SetField(bogusTag, FIXString(""))
msgBytes := builder.build()
return validateTest{
TestName: "Tag SpecifiedWithoutAValue",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonTagSpecifiedWithoutAValue,
ExpectedRefTagID: &bogusTag,
}
}
func tcInvalidMsgType() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
builder.Header.SetField(tagMsgType, FIXString("z"))
msgBytes := builder.build()
return validateTest{
TestName: "Invalid MsgType",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonInvalidMsgType,
}
}
func tcValueIsIncorrect() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
tag := Tag(21)
builder := createFIX40NewOrderSingle()
builder.Body.SetField(tag, FIXString("4"))
msgBytes := builder.build()
return validateTest{
TestName: "ValueIsIncorrect",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonValueIsIncorrect,
ExpectedRefTagID: &tag,
}
}
func tcIncorrectDataFormatForValue() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
tag := Tag(38)
builder.Body.SetField(tag, FIXString("+200.00"))
msgBytes := builder.build()
return validateTest{
TestName: "IncorrectDataFormatForValue",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonIncorrectDataFormatForValue,
ExpectedRefTagID: &tag,
}
}
func tcTagSpecifiedOutOfRequiredOrderHeader() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
tag := tagOnBehalfOfCompID
//should be in header
builder.Body.SetField(tag, FIXString("CWB"))
msgBytes := builder.build()
return validateTest{
TestName: "Tag specified out of required order in Header",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonTagSpecifiedOutOfRequiredOrder,
ExpectedRefTagID: &tag,
}
}
func tcTagSpecifiedOutOfRequiredOrderTrailer() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
tag := tagSignature
//should be in trailer
builder.Body.SetField(tag, FIXString("SIG"))
msgBytes := builder.build()
refTag := Tag(100)
return validateTest{
TestName: "Tag specified out of required order in Trailer",
Validator: validator,
MessageBytes: msgBytes,
ExpectedRejectReason: rejectReasonTagSpecifiedOutOfRequiredOrder,
ExpectedRefTagID: &refTag,
}
}
func tcInvalidTagCheckDisabled() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
customValidatorSettings := defaultValidatorSettings
customValidatorSettings.RejectInvalidMessage = false
validator := NewValidator(customValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
tag := Tag(9999)
builder.Body.SetField(tag, FIXString("hello"))
msgBytes := builder.build()
return validateTest{
TestName: "Invalid Tag Check - Disabled",
Validator: validator,
MessageBytes: msgBytes,
DoNotExpectReject: true,
}
}
func tcInvalidTagCheckEnabled() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
customValidatorSettings := defaultValidatorSettings
customValidatorSettings.RejectInvalidMessage = true
validator := NewValidator(customValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
tag := Tag(9999)
builder.Body.SetField(tag, FIXString("hello"))
msgBytes := builder.build()
return validateTest{
TestName: "Invalid Tag Check - Enabled",
Validator: validator,
MessageBytes: msgBytes,
DoNotExpectReject: false,
ExpectedRefTagID: &tag,
}
}
func tcTagSpecifiedOutOfRequiredOrderDisabledHeader() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
customValidatorSettings := defaultValidatorSettings
customValidatorSettings.CheckFieldsOutOfOrder = false
validator := NewValidator(customValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
tag := tagOnBehalfOfCompID
//should be in header
builder.Body.SetField(tag, FIXString("CWB"))
msgBytes := builder.build()
return validateTest{
TestName: "Tag specified out of required order in Header - Disabled",
Validator: validator,
MessageBytes: msgBytes,
DoNotExpectReject: true,
}
}
func tcTagSpecifiedOutOfRequiredOrderDisabledTrailer() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
customValidatorSettings := defaultValidatorSettings
customValidatorSettings.CheckFieldsOutOfOrder = false
validator := NewValidator(customValidatorSettings, dict, nil)
builder := createFIX40NewOrderSingle()
tag := tagSignature
//should be in trailer
builder.Body.SetField(tag, FIXString("SIG"))
msgBytes := builder.build()
return validateTest{
TestName: "Tag specified out of required order in Trailer - Disabled",
Validator: validator,
MessageBytes: msgBytes,
DoNotExpectReject: true,
}
}
func tcTagAppearsMoreThanOnce() validateTest {
dict, _ := datadictionary.Parse("spec/FIX40.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
tag := Tag(40)
return validateTest{
TestName: "Tag appears more than once",
Validator: validator,
MessageBytes: []byte("8=FIX.4.09=10735=D34=249=TW52=20060102-15:04:0556=ISLD11=ID21=140=140=254=138=20055=INTC60=20060102-15:04:0510=234"),
ExpectedRejectReason: rejectReasonTagAppearsMoreThanOnce,
ExpectedRefTagID: &tag,
}
}
func tcFloatValidation() validateTest {
dict, _ := datadictionary.Parse("spec/FIX42.xml")
validator := NewValidator(defaultValidatorSettings, dict, nil)
tag := Tag(38)
return validateTest{
TestName: "FloatValidation",
Validator: validator,
MessageBytes: []byte("8=FIX.4.29=10635=D34=249=TW52=20140329-22:38:4556=ISLD11=ID21=140=154=138=+200.0055=INTC60=20140329-22:38:4510=178"),
ExpectedRejectReason: rejectReasonIncorrectDataFormatForValue,
ExpectedRefTagID: &tag,
}
}
func TestValidateVisitField(t *testing.T) {
fieldType0 := datadictionary.NewFieldType("myfield", 11, "STRING")
fieldDef0 := &datadictionary.FieldDef{FieldType: fieldType0}
fieldType1 := datadictionary.NewFieldType("myfield", 2, "STRING")
fieldDef1 := &datadictionary.FieldDef{FieldType: fieldType1, Fields: []*datadictionary.FieldDef{}}
fieldType2 := datadictionary.NewFieldType("myfield", 3, "STRING")
fieldDef2 := &datadictionary.FieldDef{FieldType: fieldType2, Fields: []*datadictionary.FieldDef{}}
groupFieldType := datadictionary.NewFieldType("mygroupfield", 1, "INT")
groupFieldDef := &datadictionary.FieldDef{FieldType: groupFieldType, Fields: []*datadictionary.FieldDef{fieldDef1, fieldDef2}}
var field TagValue
field.init(Tag(11), []byte("value"))
var repField1 TagValue
var repField2 TagValue
repField1.init(Tag(2), []byte("a"))
repField2.init(Tag(3), []byte("a"))
var groupID TagValue
groupID.init(Tag(1), []byte("1"))
var groupID2 TagValue
groupID2.init(Tag(1), []byte("2"))
var groupID3 TagValue
groupID3.init(Tag(1), []byte("3"))
var tests = []struct {
fieldDef *datadictionary.FieldDef
fields []TagValue
expectedRemFields int
expectReject bool
expectedRejectReason int
}{
//non-repeating
{expectedRemFields: 0,
fieldDef: fieldDef0,
fields: []TagValue{field}},
//single field group
{expectedRemFields: 0,
fieldDef: groupFieldDef,
fields: []TagValue{groupID, repField1}},
//multiple field group
{expectedRemFields: 0,
fieldDef: groupFieldDef,
fields: []TagValue{groupID, repField1, repField2}},
//test with trailing tag not in group
{expectedRemFields: 1,
fieldDef: groupFieldDef,
fields: []TagValue{groupID, repField1, repField2, field}},
//repeats
{expectedRemFields: 1,
fieldDef: groupFieldDef,
fields: []TagValue{groupID2, repField1, repField2, repField1, repField2, field}},
//REJECT: group size declared > actual group size
{expectReject: true,
fieldDef: groupFieldDef,
fields: []TagValue{groupID3, repField1, repField2, repField1, repField2, field},
expectedRejectReason: rejectReasonIncorrectNumInGroupCountForRepeatingGroup,
},
{expectReject: true,
fieldDef: groupFieldDef,
fields: []TagValue{groupID3, repField1, repField1, field},
expectedRejectReason: rejectReasonIncorrectNumInGroupCountForRepeatingGroup,
},
//REJECT: group size declared < actual group size
{expectReject: true,
fieldDef: groupFieldDef,
fields: []TagValue{groupID, repField1, repField2, repField1, repField2, field},
expectedRejectReason: rejectReasonIncorrectNumInGroupCountForRepeatingGroup,
},
}
for _, test := range tests {
remFields, reject := validateVisitField(test.fieldDef, test.fields)
if test.expectReject {
if reject == nil {
t.Error("Expected Reject")
}
if reject.RejectReason() != test.expectedRejectReason {
t.Errorf("Expected reject reason %v got %v", test.expectedRejectReason, reject.RejectReason())
}
continue
}
if reject != nil {
t.Errorf("Unexpected reject: %v", reject)
}
if len(remFields) != test.expectedRemFields {
t.Errorf("Expected len %v got %v", test.expectedRemFields, len(remFields))
}
}
}
Go
1
https://gitee.com/bradhuang/quickfixgo.git
git@gitee.com:bradhuang/quickfixgo.git
bradhuang
quickfixgo
quickfix
dependabot/go_modules/github.com/mattn/go-sqlite3-1.14.9

搜索帮助