/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.f1x.io.parsers;
import org.f1x.util.AsciiUtils;
import org.f1x.util.ByteRingReader;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class Test_BodyLengthParser {
@Test
public void testBodyLength () {
assertBodyLength("8=FIX.4.4\u00019=0\u000110=056\u0001", 0);
assertBodyLength("8=FIX.4.4\u00019=1\u000135=A\u000134=1\u0001", 1);
assertBodyLength("8=FIX.4.1\u00019=12\u000135=A\u000134=1\u0001", 12);
assertBodyLength("8=FIX.5.0\u00019=123\u000135=A\u000134=1\u0001", 123);
assertBodyLength("8=FIX.5.0\u00019=1234\u000135=A\u000134=1\u0001", 1234);
assertBodyLength("8=FIX.5.0\u00019=000001234\u000135=A\u000134=1\u0001", 1234);
}
@Test
public void testMessageSize () {
assertRemainingMessageSize("8=FIX.4.1\u00019=0\u000110=056\u0001", 0);
assertRemainingMessageSize("8=FIX.4.2\u00019=73\u000135=1\u000134=4\u000149=CITIFX\u000156=XXXXXXXXXX\u000152=20131013-21:10:22\u0001112=1381698622643\u000110=143\u0001", 0);
assertRemainingMessageSize("8=FIX.4.3\u00019=128\u000135=A\u000134=1\u000149=XXXXXXXXXX\u000150=XXXXXXXXXX\u000152=20131013-21:10:17.498\u000156=CITIFX\u000157=CITIFX\u000198=0\u0001108=30\u0001141=Y\u0001553=DT130429\u0001554=*********\u000110=075\u0001", 0);
}
@Test
public void testInvalidMessagePrefix () {
// Bad Prefix
assertInvalid("NOT-FIX\u00019=73\u000135=1\u000134=4\u000149=CITIFX\u000156=XXXXXXXXXX\u000152=20131013-21:10:22\u0001112=1381698622643\u000110=143\u0001",
"Message must begin with BeginString and BodyLength tags");
// Bad length (1X)
assertInvalid("8=FIX.4.4\u00019=\u000135=1\u000134=4\u000149=CITIFX\u000156=XXXXXXXXXX\u000152=20131013-21:10:22\u0001112=1381698622643\u000110=143\u0001",
"Message BodyLength is empty");
assertInvalid("8=FIX.4.4\u00019=X\u000135=1\u000134=4\u000149=CITIFX\u000156=XXXXXXXXXX\u000152=20131013-21:10:22\u0001112=1381698622643\u000110=143\u0001",
"Message BodyLength is invalid");
assertInvalid("8=FIX.4.4\u00019=1X\u000135=1\u000134=4\u000149=CITIFX\u000156=XXXXXXXXXX\u000152=20131013-21:10:22\u0001112=1381698622643\u000110=143\u0001",
"Message BodyLength is invalid");
}
@Test
public void testPerformance () {
String message = "8=FIX.4.3\u00019=128\u000135=A\u000134=1\u000149=XXXXXXXXXX\u000150=XXXXXXXXXX\u000152=20131013-21:10:17.498\u000156=CITIFX1\u000157=CITIFX1\u000198=0\u0001108=30\u0001141=Y\u0001553=DT130429\u0001554=*********\u000110=075\u0001";
final int messageSize = message.length();
ByteRingReader reader = new ByteRingReader(AsciiUtils.getBytes(message));
final int WARMUP = 20000;
final int TEST = 200000;
int result = 1;
for (int i=0; i < WARMUP; i++) {
reader.reset(0, messageSize);
result += parseBodyLength(reader);
}
long start = System.currentTimeMillis();
for (int i=0; i < TEST; i++) {
reader.reset(0, messageSize);
result |= parseBodyLength(reader);
}
long end = System.currentTimeMillis();
System.out.println(" Cost of BodyLengthParser call: " + 1000000L*(end-start)/TEST + " nanoseconds/call");
if (result % 2 == 1)
System.out.print("Odd");
}
private static final byte [] EXPECTED_HEADER = AsciiUtils.getBytes("8=FIX.*.*\0019=");
private static final int EXPECTED_HEADER_LENGTH = EXPECTED_HEADER.length;
private static int parseBodyLength(ByteRingReader reader) {
//BodyLengthParser.validateMessagePrefix(reader);
reader.skip(EXPECTED_HEADER_LENGTH);
return BodyLengthParser.parseBodyLength(reader);
}
private static void assertInvalid(String header, String expectedError) {
try {
ByteRingReader reader = mockByteRingReader(header);
BodyLengthParser.getRemainingMessageSize(reader);
fail("Parsing was supposed to fail but it didn't");
} catch (Exception expected) {
assertEquals(expectedError, expected.getMessage());
}
}
private static void assertBodyLength (String header, int expectedBodyLength) {
ByteRingReader reader = mockByteRingReader(header);
BodyLengthParser.validateMessagePrefix(reader);
int actualBodyLength = BodyLengthParser.parseBodyLength(reader);
Assert.assertEquals(expectedBodyLength, actualBodyLength);
}
private static void assertRemainingMessageSize(String header, int expectedMessageSize) {
ByteRingReader reader = mockByteRingReader(header);
int actualMessageSize = BodyLengthParser.getRemainingMessageSize(reader);
Assert.assertEquals(expectedMessageSize, actualMessageSize);
}
static ByteRingReader mockByteRingReader (String text) {
ByteRingReader reader = new ByteRingReader(AsciiUtils.getBytes(text));
reader.reset(0, text.length());
return reader;
}
}