Skip to content

Commit ffdc4c7

Browse files
Fixed broken tests after fixing parsing to validate checksum
1 parent 2497d57 commit ffdc4c7

File tree

5 files changed

+85
-21
lines changed

5 files changed

+85
-21
lines changed

message.go

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,20 @@ func ParseMessageWithDataDictionary(
182182
// doParsing executes the message parsing process.
183183
func doParsing(mp *msgParser) (err error) {
184184
mp.msg.Header.rwLock.Lock()
185-
defer mp.msg.Header.rwLock.Unlock()
186185
mp.msg.Body.rwLock.Lock()
187-
defer mp.msg.Body.rwLock.Unlock()
188186
mp.msg.Trailer.rwLock.Lock()
189-
defer mp.msg.Trailer.rwLock.Unlock()
187+
188+
// 2. SETUP SAFETY DEFER
189+
// We use a flag 'locked' to track if we still hold the locks.
190+
// This ensures that if a panic or early error return happens, we still unlock.
191+
locked := true
192+
defer func() {
193+
if locked {
194+
mp.msg.Header.rwLock.Unlock()
195+
mp.msg.Body.rwLock.Unlock()
196+
mp.msg.Trailer.rwLock.Unlock()
197+
}
198+
}()
190199

191200
// Initialize for parsing.
192201
mp.msg.Header.clearNoLock()
@@ -301,6 +310,44 @@ func doParsing(mp *msgParser) (err error) {
301310
err = parseError{OrigError: fmt.Sprintf("Incorrect Message Length, expected %d, got %d", bodyLength, length)}
302311
}
303312

313+
// 3. EXPLICIT UNLOCK
314+
// Parsing is complete. We release the locks now so we can use the public helper methods below.
315+
mp.msg.Header.rwLock.Unlock()
316+
mp.msg.Body.rwLock.Unlock()
317+
mp.msg.Trailer.rwLock.Unlock()
318+
locked = false // Prevent the defer from unlocking again
319+
320+
// --- VALIDATION SECTION ---
321+
// Since we are unlocked, we can safely use .length() and .total()
322+
323+
//=== RUN TestValidate/Tag_appears_more_than_once
324+
//validation_test.go:95: ParseMessage failed: error parsing message: Expected CheckSum=211, Received CheckSum=234
325+
326+
//=== RUN TestValidate/Tag_appears_more_than_once_FIXT
327+
//validation_test.go:95: ParseMessage failed: error parsing message: Expected CheckSum=037, Received CheckSum=234
328+
329+
//=== RUN TestValidate/Multiple_repeating_group_fields_in_a_message
330+
//validation_test.go:95: ParseMessage failed: error parsing message: Expected CheckSum=005, Received CheckSum=178
331+
332+
// 2. Validate CheckSum
333+
// We calculate the total using the helper methods.
334+
calculatedCheckSum := mp.msg.Header.total() + mp.msg.Body.total() + mp.msg.Trailer.total()
335+
336+
// Final modulo
337+
calculatedCheckSum = calculatedCheckSum % 256
338+
339+
// Get expected checksum from the message
340+
expectedCheckSumStr, err := mp.msg.Trailer.GetString(tagCheckSum)
341+
if err != nil {
342+
return parseError{OrigError: "CheckSum tag missing"}
343+
}
344+
345+
if expectedCheckSumStr != formatCheckSum(calculatedCheckSum) {
346+
return parseError{
347+
OrigError: fmt.Sprintf("Expected CheckSum=%s, Received CheckSum=%s", formatCheckSum(calculatedCheckSum), expectedCheckSumStr),
348+
}
349+
}
350+
304351
return
305352
}
306353

message_router_test.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,40 @@ func (suite *MessageRouterTestSuite) SetupTest() {
115115
}
116116

117117
func (suite *MessageRouterTestSuite) TestNoRoute() {
118-
suite.givenTheMessage([]byte("8=FIX.4.39=8735=D49=TW34=356=ISLD52=20160421-14:43:5040=160=20160421-14:43:5054=121=311=id10=235"))
118+
suite.givenTheMessage([]byte("8=FIX.4.39=8735=D49=TW34=356=ISLD52=20160421-14:43:5040=160=20160421-14:43:5054=121=311=id10=236"))
119119

120120
rej := suite.Route(suite.msg, suite.sessionID)
121121
suite.verifyMessageNotRouted()
122122
suite.Equal(NewBusinessMessageRejectError("Unsupported Message Type", 3, nil), rej)
123123
}
124124

125125
func (suite *MessageRouterTestSuite) TestNoRouteWhitelistedMessageTypes() {
126-
var tests = []string{"0", "A", "1", "2", "3", "4", "5", "j"}
126+
// Pairs of (MsgType, CheckSum)
127+
// currently set to "000" placeholders for you to fill in.
128+
var tests = []struct {
129+
msgType string
130+
checksum string
131+
}{
132+
{"0", "216"},
133+
{"A", "233"},
134+
{"1", "217"},
135+
{"2", "218"},
136+
{"3", "219"},
137+
{"4", "220"},
138+
{"5", "221"},
139+
{"j", "018"},
140+
}
127141

128142
for _, test := range tests {
129143
suite.SetupTest()
130144

131-
msg := fmt.Sprintf("8=FIX.4.39=8735=%v49=TW34=356=ISLD52=20160421-14:43:5040=160=20160421-14:43:5054=121=311=id10=235", test)
145+
// We inject both the msgType and the specific checksum for that type
146+
msg := fmt.Sprintf("8=FIX.4.39=8735=%s49=TW34=356=ISLD52=20160421-14:43:5040=160=20160421-14:43:5054=121=311=id10=%s", test.msgType, test.checksum)
132147
suite.givenTheMessage([]byte(msg))
133148

134149
rej := suite.Route(suite.msg, suite.sessionID)
135150
suite.verifyMessageNotRouted()
136-
suite.Nil(rej, "Message type '%v' should not be rejected by the MessageRouter", test)
151+
suite.Nil(rej, "Message type '%s' should not be rejected by the MessageRouter", test.msgType)
137152
}
138153
}
139154

@@ -174,7 +189,7 @@ func (suite *MessageRouterTestSuite) TestRouteFIXT50AppWithApplVerID() {
174189
suite.givenTheRoute(ApplVerIDFIX50, "D")
175190
suite.givenTheRoute(ApplVerIDFIX50SP1, "D")
176191

177-
suite.givenTheMessage([]byte("8=FIXT.1.19=8935=D49=TW34=356=ISLD52=20160424-16:48:261128=740=160=20160424-16:48:2611=id21=310=120"))
192+
suite.givenTheMessage([]byte("8=FIXT.1.19=8935=D49=TW34=356=ISLD52=20160424-16:48:261128=740=160=20160424-16:48:2611=id21=310=192"))
178193
rej := suite.Route(suite.msg, suite.sessionID)
179194
suite.verifyMessageRoutedBy(ApplVerIDFIX50, "D")
180195
suite.Nil(rej)
@@ -185,7 +200,7 @@ func (suite *MessageRouterTestSuite) TestRouteFIXTAppWithApplVerID() {
185200
suite.givenTheRoute(ApplVerIDFIX50, "D")
186201
suite.givenTheRoute(ApplVerIDFIX50SP1, "D")
187202

188-
suite.givenTheMessage([]byte("8=FIXT.1.19=8935=D49=TW34=356=ISLD52=20160424-16:48:261128=840=160=20160424-16:48:2611=id21=310=120"))
203+
suite.givenTheMessage([]byte("8=FIXT.1.19=8935=D49=TW34=356=ISLD52=20160424-16:48:261128=840=160=20160424-16:48:2611=id21=310=193"))
189204
rej := suite.Route(suite.msg, suite.sessionID)
190205
suite.verifyMessageRoutedBy(ApplVerIDFIX50SP1, "D")
191206
suite.Nil(rej)

message_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (s *MessageSuite) TestParseMessageEmpty() {
6565
}
6666

6767
func (s *MessageSuite) TestParseMessage() {
68-
rawMsg := bytes.NewBufferString("8=FIX.4.29=10435=D34=249=TW52=20140515-19:49:56.65956=ISLD11=10021=140=154=155=TSLA60=00010101-00:00:00.00010=039")
68+
rawMsg := bytes.NewBufferString("8=FIX.4.29=10435=D34=249=TW52=20140515-19:49:56.65956=ISLD11=10021=140=154=155=TSLA60=00010101-00:00:00.00010=051")
6969

7070
err := ParseMessage(s.msg, rawMsg)
7171
s.Nil(err)
@@ -99,7 +99,7 @@ func (s *MessageSuite) TestParseMessageWithDataDictionary() {
9999
5050: nil,
100100
},
101101
}
102-
rawMsg := bytes.NewBufferString("8=FIX.4.29=12635=D34=249=TW52=20140515-19:49:56.65956=ISLD10030=CUST11=10021=140=154=155=TSLA60=00010101-00:00:00.0005050=HELLO10=039")
102+
rawMsg := bytes.NewBufferString("8=FIX.4.29=12635=D34=249=TW52=20140515-19:49:56.65956=ISLD10030=CUST11=10021=140=154=155=TSLA60=00010101-00:00:00.0005050=HELLO10=036")
103103

104104
err := ParseMessageWithDataDictionary(s.msg, rawMsg, dict, dict)
105105
s.Nil(err)
@@ -127,7 +127,7 @@ func (s *MessageSuite) TestBuild() {
127127
}
128128

129129
func (s *MessageSuite) TestReBuild() {
130-
rawMsg := bytes.NewBufferString("8=FIX.4.29=10435=D34=249=TW52=20140515-19:49:56.65956=ISLD11=10021=140=154=155=TSLA60=00010101-00:00:00.00010=039")
130+
rawMsg := bytes.NewBufferString("8=FIX.4.29=10435=D34=249=TW52=20140515-19:49:56.65956=ISLD11=10021=140=154=155=TSLA60=00010101-00:00:00.00010=051")
131131

132132
s.Nil(ParseMessage(s.msg, rawMsg))
133133

@@ -419,7 +419,7 @@ func (s *MessageSuite) TestReBuildWithRepeatingGroupForResend() {
419419
}
420420

421421
func (s *MessageSuite) TestReverseRoute() {
422-
s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.29=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=123")))
422+
s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.29=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=033")))
423423

424424
builder := s.msg.reverseRoute()
425425

@@ -450,15 +450,15 @@ func (s *MessageSuite) TestReverseRoute() {
450450
}
451451

452452
func (s *MessageSuite) TestReverseRouteIgnoreEmpty() {
453-
s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.09=12835=D34=249=TW52=20060102-15:04:0556=ISLD115=116=CS128=MG129=CB11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=123")))
453+
s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.09=12835=D34=249=TW52=20060102-15:04:0556=ISLD115=116=CS128=MG129=CB11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=041")))
454454
builder := s.msg.reverseRoute()
455455

456456
s.False(builder.Header.Has(tagDeliverToCompID), "Should not reverse if empty")
457457
}
458458

459459
func (s *MessageSuite) TestReverseRouteFIX40() {
460460
// The onbehalfof/deliverto location id not supported in fix 4.0.
461-
s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.09=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=123")))
461+
s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.09=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=031")))
462462

463463
builder := s.msg.reverseRoute()
464464

@@ -468,7 +468,7 @@ func (s *MessageSuite) TestReverseRouteFIX40() {
468468
}
469469

470470
func (s *MessageSuite) TestCopyIntoMessage() {
471-
msgString := "8=FIX.4.29=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=123"
471+
msgString := "8=FIX.4.29=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=033"
472472
msgBuf := bytes.NewBufferString(msgString)
473473
s.Nil(ParseMessage(s.msg, msgBuf))
474474

repeating_group_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ func TestRepeatingGroup_ReadRecursive(t *testing.T) {
230230

231231
func TestRepeatingGroup_ReadComplete(t *testing.T) {
232232

233-
rawMsg := bytes.NewBufferString("8=FIXT.1.19=26835=W34=711849=TEST52=20151027-18:41:52.69856=TST22=9948=TSTX15262=7268=4269=4270=0.07499272=20151027273=18:41:52.698269=7270=0.07501272=20151027273=18:41:52.698269=8270=0.07494272=20151027273=18:41:52.698269=B271=60272=20151027273=18:41:52.69810=163")
233+
rawMsg := bytes.NewBufferString("8=FIXT.1.19=26835=W34=711849=TEST52=20151027-18:41:52.69856=TST22=9948=TSTX15262=7268=4269=4270=0.07499272=20151027273=18:41:52.698269=7270=0.07501272=20151027273=18:41:52.698269=8270=0.07494272=20151027273=18:41:52.698269=B271=60272=20151027273=18:41:52.69810=097")
234234

235235
msg := NewMessage()
236236
err := ParseMessage(msg, rawMsg)

validation_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type validateTest struct {
3232
ExpectedRejectReason int
3333
ExpectedRefTagID *Tag
3434
DoNotExpectReject bool
35+
ExpectParseError bool
3536
}
3637

3738
func TestValidate(t *testing.T) {
@@ -201,6 +202,7 @@ func tcInvalidTagNumberHeader() validateTest {
201202
invalidHeaderFieldMessage := createFIX40NewOrderSingle()
202203
tag := Tag(9999)
203204
invalidHeaderFieldMessage.Header.SetField(tag, FIXString("hello"))
205+
invalidHeaderFieldMessage.cook()
204206
msgBytes := invalidHeaderFieldMessage.build()
205207

206208
return validateTest{
@@ -1109,7 +1111,7 @@ func tcTagAppearsMoreThanOnce() validateTest {
11091111
return validateTest{
11101112
TestName: "Tag appears more than once",
11111113
Validator: validator,
1112-
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"),
1114+
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=211"),
11131115
ExpectedRejectReason: rejectReasonTagAppearsMoreThanOnce,
11141116
ExpectedRefTagID: &tag,
11151117
}
@@ -1124,7 +1126,7 @@ func tcTagAppearsMoreThanOnceFixT() validateTest {
11241126
return validateTest{
11251127
TestName: "Tag appears more than once FIXT",
11261128
Validator: validator,
1127-
MessageBytes: []byte("8=FIXT.1.19=10735=D34=249=TW52=20060102-15:04:0556=ISLD11=ID21=140=140=254=138=20055=INTC60=20060102-15:04:0510=234"),
1129+
MessageBytes: []byte("8=FIXT.1.19=10735=D34=249=TW52=20060102-15:04:0556=ISLD11=ID21=140=140=254=138=20055=INTC60=20060102-15:04:0510=037"),
11281130
ExpectedRejectReason: rejectReasonTagAppearsMoreThanOnce,
11291131
ExpectedRefTagID: &tag,
11301132
}
@@ -1151,7 +1153,7 @@ func tcFloatValidationFixT() validateTest {
11511153
return validateTest{
11521154
TestName: "FloatValidation FIXT",
11531155
Validator: validator,
1154-
MessageBytes: []byte("8=FIXT.1.19=10635=D34=249=TW52=20140329-22:38:4556=ISLD11=ID21=140=154=138=+200.0055=INTC60=20140329-22:38:4510=178"),
1156+
MessageBytes: []byte("8=FIXT.1.19=10635=D34=249=TW52=20140329-22:38:4556=ISLD11=ID21=140=154=138=+200.0055=INTC60=20140329-22:38:4510=002"),
11551157
ExpectedRejectReason: rejectReasonIncorrectDataFormatForValue,
11561158
ExpectedRefTagID: &tag,
11571159
}
@@ -1163,7 +1165,7 @@ func tcMultipleRepeatingGroupFields() validateTest {
11631165
return validateTest{
11641166
TestName: "Multiple repeating group fields in a message",
11651167
Validator: validator,
1166-
MessageBytes: []byte("8=FIX.4.39=17635=D34=249=TW52=20140329-22:38:4556=ISLD11=ID453=2448=PARTYID452=3523=SUBID448=PARTYID2452=378=179=ACCOUNT80=121=140=154=138=20055=INTC60=20140329-22:38:4510=178"),
1168+
MessageBytes: []byte("8=FIX.4.39=17635=D34=249=TW52=20140329-22:38:4556=ISLD11=ID453=2448=PARTYID452=3523=SUBID448=PARTYID2452=378=179=ACCOUNT80=121=140=154=138=20055=INTC60=20140329-22:38:4510=005"),
11671169
DoNotExpectReject: true,
11681170
}
11691171
}

0 commit comments

Comments
 (0)