#![feature(attr_literals)]
#![feature(const_fn)]
#![allow(non_snake_case)]
extern crate chrono;
#[macro_use]
extern crate fix_rs;
#[macro_use]
extern crate fix_rs_macros;
extern crate mio;
extern crate phf;
use mio::tcp::Shutdown;
use std::any::Any;
use std::collections::HashMap;
use std::io::Write;
use std::thread;
use std::time::Duration;
#[macro_use]
mod common;
use common::{CLIENT_SENDER_COMP_ID,CLIENT_TARGET_COMP_ID,SERVER_SENDER_COMP_ID,SERVER_TARGET_COMP_ID,TestStream,new_logon_message,recv_bytes_with_timeout,send_message};
use fix_rs::dictionary::standard_msg_types;
use fix_rs::dictionary::field_types::generic::{CharFieldType,NoneFieldType,StringFieldType};
use fix_rs::dictionary::field_types::other::{BusinessRejectReason,OrdType,SecurityIDSource,SessionRejectReason,Side};
use fix_rs::dictionary::fields::{TestReqID,HeartBtInt,EndSeqNo,SideField,OrigSendingTime,NoHops,HopCompID};
use fix_rs::dictionary::messages::{Logon,Logout,NewOrderSingle,ResendRequest,TestRequest,Heartbeat,SequenceReset,Reject,BusinessMessageReject};
use fix_rs::field::Field;
use fix_rs::fix::ParseError;
use fix_rs::field_tag::{self,FieldTag};
use fix_rs::fix_version::FIXVersion;
use fix_rs::fixt;
use fix_rs::fixt::engine::{Engine,EngineEvent,Connection,ConnectionTerminatedReason,Listener,ResendResponse};
use fix_rs::fixt::message::{BuildFIXTMessage,FIXTMessage};
use fix_rs::message::{self,NOT_REQUIRED,REQUIRED,MessageDetails};
use fix_rs::message_version::{self,MessageVersion};
fn is_logon_valid(message: &Logon) -> bool {
true
}
#[test]
fn test_1B() {
define_dictionary!(
Logout,
Logon,
NewOrderSingle,
ResendRequest,
SequenceReset,
);
fn do_logon<F>(server_response_func: F) -> (TestStream,Engine,Connection,Logon)
where F: Fn(&mut TestStream,Logon) {
let (mut test_server,mut client,connection) = TestStream::setup_test_server(build_dictionary());
let logon_message = new_logon_message();
client.send_message(connection,logon_message.clone());
let message = test_server.recv_message::<Logon>();
server_response_func(&mut test_server,message.clone());
(test_server,client,connection,logon_message)
}
{
let (_,mut client,connection,logon_message) = do_logon(|mut test_server,message| {
assert!(is_logon_valid(&message));
let mut response_message = new_fixt_message!(Logon);
response_message.encrypt_method = message.encrypt_method;
response_message.heart_bt_int = message.heart_bt_int;
response_message.default_appl_ver_id = message.default_appl_ver_id;
test_server.send_message(response_message);
});
engine_poll_event!(client,EngineEvent::SessionEstablished(session_connection) => {
assert_eq!(session_connection,connection);
});
let mut message = engine_poll_message!(client,connection,Logon);
assert!((logon_message.sending_time - message.sending_time).num_milliseconds() < 50);
message.sending_time = logon_message.sending_time;
assert_eq!(message.sender_comp_id,SERVER_SENDER_COMP_ID);
message.sender_comp_id = logon_message.sender_comp_id.clone();
assert_eq!(message.target_comp_id,SERVER_TARGET_COMP_ID);
message.target_comp_id = logon_message.target_comp_id.clone();
assert_eq!(message.appl_ver_id.unwrap(),MessageVersion::FIX50SP2);
message.appl_ver_id = logon_message.appl_ver_id.clone();
assert!(message == logon_message);
}
{
let (mut test_server,mut client,connection,_) = do_logon(|mut test_server,message| {
assert!(is_logon_valid(&message));
let mut response_message = new_fixt_message!(Logon);
response_message.msg_seq_num = 9;
response_message.encrypt_method = message.encrypt_method;
response_message.heart_bt_int = message.heart_bt_int;
response_message.default_appl_ver_id = message.default_appl_ver_id;
test_server.send_message(response_message);
});
engine_poll_event!(client,EngineEvent::SessionEstablished(session_connection) => {
assert_eq!(session_connection,connection);
});
let message = test_server.recv_message::<ResendRequest>();
assert_eq!(message.begin_seq_no,1);
assert!(message.end_seq_no == 0 || message.end_seq_no == 8);
let mut message = new_fixt_message!(SequenceReset);
message.gap_fill_flag = true;
message.new_seq_no = 10;
message.msg_seq_num = 1;
test_server.send_message(message);
let _ = engine_poll_message!(client,connection,Logon);
}
{
let (mut test_server,mut client,connection,_) = do_logon(|mut test_server,message| {
let mut response_message = new_fixt_message!(Logon);
response_message.encrypt_method = message.encrypt_method;
response_message.heart_bt_int = -1;
response_message.default_appl_ver_id = message.default_appl_ver_id;
test_server.send_message(response_message);
});
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"HeartBtInt cannot be negative".to_vec());
thread::sleep(Duration::from_millis(500));
assert!(test_server.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::LogonHeartBtIntNegativeError = reason { true } else { false });
});
}
{
let (mut test_server,mut client,connection,_) = do_logon(|mut test_server,_| {
let mut new_order_single = new_fixt_message!(NewOrderSingle);
new_order_single.cl_ord_id = b"0".to_vec();
new_order_single.symbol = b"TEST".to_vec();
new_order_single.security_id = b"0".to_vec();
new_order_single.security_id_source = Some(SecurityIDSource::CUSIP);
new_order_single.side = Side::Buy;
new_order_single.transact_time = new_order_single.sending_time;
new_order_single.order_qty = b"1".to_vec();
new_order_single.ord_type = OrdType::Market;
test_server.send_message(new_order_single);
});
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"First message not a logon".to_vec());
thread::sleep(Duration::from_millis(500));
assert!(test_server.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::LogonNotFirstMessageError = reason { true } else { false });
});
}
}
#[test]
fn test_1S() {
define_dictionary!(
Logout,
Logon,
ResendRequest,
SequenceReset,
);
fn do_logon<F1,F2>(logon_message_setup_func: F1,server_response_func: F2) -> (TestStream,Engine,Listener,Connection,Logon)
where F1: Fn(&mut Logon),
F2: Fn(&mut Engine,Connection,Box<Logon>) {
let (mut test_client,mut engine,listener,connection) = TestStream::setup_test_client(build_dictionary());
let mut logon_message = new_logon_message();
logon_message.sender_comp_id = CLIENT_SENDER_COMP_ID.to_vec();
logon_message.target_comp_id = CLIENT_TARGET_COMP_ID.to_vec();
logon_message_setup_func(&mut logon_message);
test_client.send_message(logon_message.clone());
engine_poll_event!(engine,EngineEvent::ConnectionLoggingOn(some_listener,some_connection,logon_message) => {
assert_eq!(some_listener,listener);
assert_eq!(some_connection,connection);
server_response_func(&mut engine,some_connection,logon_message);
});
(test_client,engine,listener,connection,logon_message)
}
{
let (mut test_client,_engine,_listener,_connection,initial_logon_message) = do_logon(|_|{},|mut engine,connection,logon_message| {
let mut response_message = new_fixt_message!(Logon);
response_message.encrypt_method = logon_message.encrypt_method.clone();
response_message.heart_bt_int = logon_message.heart_bt_int.clone();
response_message.default_appl_ver_id = logon_message.default_appl_ver_id;
engine.approve_new_connection(connection,Box::new(response_message),None);
});
let message = test_client.recv_message::<Logon>();
assert_eq!(message.msg_seq_num,1);
assert!((initial_logon_message.sending_time - message.sending_time).num_milliseconds() < 50);
assert_eq!(message.sender_comp_id,SERVER_SENDER_COMP_ID);
assert_eq!(message.target_comp_id,SERVER_TARGET_COMP_ID);
assert_eq!(message.appl_ver_id.unwrap(),MessageVersion::FIX50SP2);
}
{
let (mut test_client,_engine,_listener,_connection,_initial_logon_message) = do_logon(|logon_message: &mut Logon| {
logon_message.msg_seq_num = 45;
},
|mut engine,connection,logon_message| {
let mut response_message = new_fixt_message!(Logon);
response_message.encrypt_method = logon_message.encrypt_method.clone();
response_message.heart_bt_int = logon_message.heart_bt_int.clone();
response_message.default_appl_ver_id = logon_message.default_appl_ver_id;
engine.approve_new_connection(connection,Box::new(response_message),20);
});
let message = test_client.recv_message::<Logon>();
assert_eq!(message.msg_seq_num,1);
let message = test_client.recv_message::<ResendRequest>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.begin_seq_no,20);
assert!(message.end_seq_no == 0 || message.end_seq_no == 45);
}
{
let (mut test_client,mut engine,_listener,connection,_initial_logon_message) = do_logon(|logon_message: &mut Logon| {
logon_message.username = b"Username".to_vec();
logon_message.password = b"password".to_vec()
},
|mut engine,connection,_| {
engine.reject_new_connection(connection,Some(b"Invalid username and/or password".to_vec()));
});
let message = test_client.recv_message::<Logout>();
assert_eq!(message.text,b"Invalid username and/or password".to_vec());
thread::sleep(Duration::from_millis(500));
assert!(test_client.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(engine,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::LogonRejectedError = reason { true } else { false });
});
}
{
let (mut test_client,mut engine,_listener,connection) = TestStream::setup_test_client(build_dictionary());
let mut message = new_fixt_message!(FROM_CLIENT ResendRequest);
message.begin_seq_no = 1;
message.end_seq_no = 0;
test_client.send_message(message);
thread::sleep(Duration::from_millis(500));
assert!(test_client.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(engine,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::LogonNotFirstMessageError = reason { true } else { false });
});
}
}
#[test]
fn test_2B() {
fn garbled_test_requests() -> Vec<&'static [u8]> {
let mut result: Vec<&'static [u8]> = Vec::new();
result.push(b"8=FIX.4.2\x0149=TEST\x019=38\x0135=1\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=204\x01"); result.push(b"8=FIX.4.2\x019=39\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=204\x01"); result.push(b"8=FIX.4.2\x019=37\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=204\x01"); result.push(b"8=FIX.4.2\x019=38\x0149=TEST\x0135=1\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=204\x01"); result.push(b"8=FIX.4.2\x019=38\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x0110=204\x01112=1\x01"); result.push(b"8=FIX.4.2\x019=38\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=255\x01"); result.push(b"8=FIX.4.2\x019=38\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=25\x01"); result.push(b"8=FIX.4.2\x019=38\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=2\x01"); result.push(b"8=FIX.4.2\x019=38\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=\x01"); result.push(b"8=FIX.4.2\x019=38\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=2555");
result
}
define_dictionary!(
Logout,
Logon,
ResendRequest,
TestRequest,
Heartbeat,
SequenceReset,
Reject,
);
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.test_req_id = b"1".to_vec();
client.send_message(connection,message);
let message = test_server.recv_message::<TestRequest>();
assert_eq!(message.msg_seq_num,2);
let mut hb_message = new_fixt_message!(Heartbeat);
hb_message.msg_seq_num = 2;
hb_message.test_req_id = message.test_req_id;
test_server.send_message(hb_message);
let message = engine_poll_message!(client,connection,Heartbeat);
assert_eq!(message.msg_seq_num,2);
let message = new_fixt_message!(Logout);
client.send_message(connection,message);
let message = test_server.recv_message::<Logout>();
assert_eq!(message.msg_seq_num,3);
let mut message = new_fixt_message!(Logout);
message.msg_seq_num = 3;
test_server.send_message(message);
let message = engine_poll_message!(client,connection,Logout);
assert_eq!(message.msg_seq_num,3);
}
{
let (mut test_server,_client,_) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 25;
message.test_req_id = b"1".to_vec();
test_server.send_message(message);
let message = test_server.recv_message::<ResendRequest>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.begin_seq_no,2);
assert!(message.end_seq_no == 0 || message.end_seq_no == 25);
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 1;
message.test_req_id = b"1".to_vec();
test_server.send_message(message);
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"MsgSeqNum too low, expected 2 but received 1".to_vec());
thread::sleep(Duration::from_millis(500));
assert!(test_server.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::InboundMsgSeqNumLowerThanExpectedError = reason { true } else { false });
});
}
for garbled_test_request in garbled_test_requests() {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let bytes_written = test_server.stream.write(garbled_test_request).unwrap();
assert_eq!(bytes_written,garbled_test_request.len());
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,_) => {
assert_eq!(connection,gm_connection);
});
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 3;
message.test_req_id = b"1".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,3);
}
let mut orig_sending_time_setup_fns = Vec::<Box<FnMut(&mut TestRequest)>>::new();
orig_sending_time_setup_fns.push(Box::new(|message| { message.orig_sending_time = message.sending_time - chrono::Duration::seconds(1); }));
orig_sending_time_setup_fns.push(Box::new(|message| { message.orig_sending_time = message.sending_time; }));
for mut orig_sending_time_setup_fn in orig_sending_time_setup_fns {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 9;
message.test_req_id = b"1".to_vec();
test_server.send_message(message);
let message = test_server.recv_message::<ResendRequest>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.begin_seq_no,2);
assert!(message.end_seq_no == 0 || message.end_seq_no == 9);
let mut message = new_fixt_message!(SequenceReset);
message.gap_fill_flag = true;
message.new_seq_no = 9;
message.msg_seq_num = 2;
test_server.send_message(message);
let message = engine_poll_message!(client,connection,SequenceReset);
assert_eq!(message.gap_fill_flag,true);
assert_eq!(message.new_seq_no,9);
assert_eq!(message.msg_seq_num,2);
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"2".to_vec();
message.poss_dup_flag = true;
message.orig_sending_time = message.sending_time + chrono::Duration::seconds(1);
test_server.send_message(message);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.ref_seq_num,2);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::SendingTimeAccuracyProblem);
assert_eq!(message.text,b"SendingTime accuracy problem".to_vec());
engine_poll_event!(client,EngineEvent::MessageRejected(msg_connection,rejected_message) => {
assert_eq!(msg_connection,connection);
let message = rejected_message.as_any().downcast_ref::<TestRequest>().expect("Not expected message type").clone();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.test_req_id,b"2".to_vec());
assert_eq!(message.poss_dup_flag,true);
});
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"2".to_vec();
message.poss_dup_flag = true;
test_server.send_message(message);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.ref_seq_num,2);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::RequiredTagMissing);
assert_eq!(message.text,b"Conditionally required tag missing".to_vec());
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(msg_connection,parse_error) => {
assert_eq!(msg_connection,connection);
match parse_error {
ParseError::MissingConditionallyRequiredTag(tag,message) => {
assert_eq!(tag,OrigSendingTime::tag());
let message = message.as_any().downcast_ref::<TestRequest>().expect("Not expected message type").clone();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.test_req_id,b"2".to_vec());
assert_eq!(message.poss_dup_flag,true);
},
_ => panic!("Wrong parse error"),
};
});
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon_with_ver(FIXVersion::FIXT_1_1,MessageVersion::FIX50SP2,build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"2".to_vec();
send_message(&mut test_server.stream,FIXVersion::FIX_4_2,MessageVersion::FIX42,Box::new(message));
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"BeginStr is wrong, expected 'FIXT.1.1' but received 'FIX.4.2'".to_vec());
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(
if let ConnectionTerminatedReason::BeginStrWrongError{received,expected} = reason {
assert_eq!(received,FIXVersion::FIX_4_2);
assert_eq!(expected,FIXVersion::FIXT_1_1);
true
}
else {
false
}
);
});
}
{
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"1".to_vec();
message.sender_comp_id = SERVER_SENDER_COMP_ID.to_vec();
message.target_comp_id = SERVER_TARGET_COMP_ID.to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.sender_comp_id,SERVER_SENDER_COMP_ID);
assert_eq!(message.target_comp_id,SERVER_TARGET_COMP_ID);
let _ = test_server.recv_message::<Heartbeat>();
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 3;
message.test_req_id = b"2".to_vec();
message.sender_comp_id = b"unknown".to_vec();
message.target_comp_id = SERVER_SENDER_COMP_ID.to_vec();
test_server.send_message(message);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.msg_seq_num,3);
assert_eq!(message.ref_seq_num,3);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::CompIDProblem);
assert_eq!(message.text,b"CompID problem".to_vec());
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"SenderCompID is wrong".to_vec());
engine_poll_event!(client,EngineEvent::MessageRejected(msg_connection,rejected_message) => {
assert_eq!(msg_connection,connection);
let _ = rejected_message.as_any().downcast_ref::<TestRequest>().expect("Not expected message type").clone();
});
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::SenderCompIDWrongError = reason { true } else { false });
});
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"2".to_vec();
message.sender_comp_id = SERVER_SENDER_COMP_ID.to_vec();
message.target_comp_id = b"unknown".to_vec();
test_server.send_message(message);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.ref_seq_num,2);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::CompIDProblem);
assert_eq!(message.text,b"CompID problem".to_vec());
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"TargetCompID is wrong".to_vec());
engine_poll_event!(client,EngineEvent::MessageRejected(msg_connection,rejected_message) => {
assert_eq!(msg_connection,connection);
let _ = rejected_message.as_any().downcast_ref::<TestRequest>().expect("Not expected message type").clone();
});
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::TargetCompIDWrongError = reason { true } else { false });
});
}
}
{
define_dictionary!(
Logon,
Reject,
TestRequest,
);
define_fixt_message!(MessageWithInvalidMsgType: b"99999" => {
NOT_REQUIRED, test_req_id: TestReqID [FIX40..],
});
let message = new_fixt_message!(MessageWithInvalidMsgType);
let invalid_msg_type = <MessageWithInvalidMsgType as FIXTMessage>::msg_type(&message);
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(MessageWithInvalidMsgType);
message.msg_seq_num = 2;
test_server.send_message(message);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.ref_msg_type,invalid_msg_type);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::InvalidMsgType);
assert_eq!(message.text,b"Invalid MsgType".to_vec());
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(msg_connection,parse_error) => {
assert_eq!(msg_connection,connection);
assert!(if let ParseError::MsgTypeUnknown(_) = parse_error { true } else { false });
});
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 3;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,3);
}
{
define_dictionary!(
BusinessMessageReject,
Logon,
TestRequest,
);
define_fixt_message!(MessageWithUnsupportedMsgType: b"AA" => {
NOT_REQUIRED, test_req_id: TestReqID [FIX40..],
});
let message = new_fixt_message!(MessageWithUnsupportedMsgType);
let unsupported_msg_type = <MessageWithUnsupportedMsgType as FIXTMessage>::msg_type(&message);
assert!(standard_msg_types().contains(unsupported_msg_type));
assert!(!build_dictionary().contains_key(unsupported_msg_type));
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(MessageWithUnsupportedMsgType);
message.msg_seq_num = 2;
test_server.send_message(message);
let message = test_server.recv_message::<BusinessMessageReject>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.ref_msg_type,unsupported_msg_type);
assert_eq!(message.business_reject_reason,BusinessRejectReason::UnsupportedMessageType);
assert_eq!(message.text,b"Unsupported Message Type".to_vec());
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(msg_connection,parse_error) => {
assert_eq!(msg_connection,connection);
assert!(if let ParseError::MsgTypeUnknown(_) = parse_error { true } else { false });
});
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 3;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,3);
}
}
#[test]
fn test_3B() {
}
#[test]
fn test_4B() {
define_dictionary!(
Logon,
TestRequest,
Heartbeat,
);
{
let (mut test_server,_client,_) = TestStream::setup_test_server_and_logon(build_dictionary());
thread::sleep(Duration::from_millis(5500));
let _ = test_server.recv_message::<Heartbeat>();
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
thread::sleep(Duration::from_millis(2500));
let mut message = new_fixt_message!(TestRequest);
message.test_req_id = b"1".to_vec();
client.send_message(connection,message);
let _ = test_server.recv_message::<TestRequest>();
thread::sleep(Duration::from_millis(1000));
let _ = test_server.recv_message::<TestRequest>();
thread::sleep(Duration::from_millis(2000));
assert!(test_server.try_recv_fixt_message(Duration::from_secs(1)).is_none());
}
{
let (mut test_server,_client,_connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = test_server.recv_message::<Heartbeat>();
assert_eq!(message.test_req_id,b"test_id".to_vec());
}
}
#[test]
fn test_5B() {
define_dictionary!(
Logon,
Heartbeat,
);
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut hb_message = new_fixt_message!(Heartbeat);
hb_message.msg_seq_num = 2;
test_server.send_message(hb_message);
let message = engine_poll_message!(client,connection,Heartbeat);
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.test_req_id,b"".to_vec());
}
#[test]
fn test_6B() {
define_dictionary!(
Logon,
TestRequest,
Heartbeat,
);
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
thread::sleep(Duration::from_millis(6000));
let message = test_server.recv_message::<Heartbeat>();
assert_eq!(message.msg_seq_num,2);
let message = test_server.recv_message::<TestRequest>();
assert_eq!(message.msg_seq_num,3);
let test_req_id = message.test_req_id;
let mut hb_message = new_fixt_message!(Heartbeat);
hb_message.msg_seq_num = 2;
hb_message.test_req_id = test_req_id.clone();
test_server.send_message(hb_message);
let message = engine_poll_message!(client,connection,Heartbeat);
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.test_req_id,test_req_id);
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
thread::sleep(Duration::from_millis(6000));
let _ = test_server.recv_message::<Heartbeat>();
let message = test_server.recv_message::<TestRequest>();
assert_eq!(message.msg_seq_num,3);
thread::sleep(Duration::from_millis(6000));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::TestRequestNotRespondedError = reason { true } else { false });
});
}
}
#[test]
fn test_7B() {
define_dictionary!(
Logon,
TestRequest,
Reject,
);
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(Reject);
message.msg_seq_num = 2;
message.ref_seq_num = 2;
test_server.send_message(message);
let message = engine_poll_message!(client,connection,Reject);
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.ref_seq_num,2);
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 3;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,3);
}
#[test]
fn test_8B() {
define_dictionary!(
Logon,
TestRequest,
Heartbeat,
ResendRequest,
SequenceReset,
);
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
thread::sleep(Duration::from_millis(6000));
let _ = test_server.recv_message::<Heartbeat>();
let _ = test_server.recv_message::<TestRequest>();
let mut message = new_fixt_message!(ResendRequest);
message.msg_seq_num = 2;
message.begin_seq_no = 2;
message.end_seq_no = 3;
test_server.send_message(message);
engine_gap_fill_resend_request!(client,connection,2..4);
let message = test_server.recv_message::<SequenceReset>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.gap_fill_flag,true);
assert_eq!(message.new_seq_no,4);
}
#[test]
fn test_9B() {
}
#[test]
fn test_10B() {
define_dictionary!(
Logon,
ResendRequest,
SequenceReset,
TestRequest,
Logout,
Reject,
);
{
let (mut test_server,_client,_) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = 10;
message.gap_fill_flag = true;
message.new_seq_no = 15;
test_server.send_message(message);
let message = test_server.recv_message::<ResendRequest>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.begin_seq_no,2);
assert!(message.end_seq_no == 9 || message.end_seq_no == 0);
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = 2;
message.gap_fill_flag = true;
message.new_seq_no = 15;
test_server.send_message(message);
let message = engine_poll_message!(client,connection,SequenceReset);
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.gap_fill_flag,true);
assert_eq!(message.new_seq_no,15);
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 15;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,15);
assert_eq!(message.test_req_id,b"test_id".to_vec());
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = 1;
message.gap_fill_flag = true;
message.new_seq_no = 15;
message.poss_dup_flag = true;
message.orig_sending_time = message.sending_time;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedDuplicate(msg_connection,duplicate_message) => {
assert_eq!(msg_connection,connection);
let message = duplicate_message.as_any().downcast_ref::<SequenceReset>().expect("Not expected message type").clone();
assert_eq!(message.msg_seq_num,1);
assert_eq!(message.gap_fill_flag,true);
assert_eq!(message.new_seq_no,15);
assert_eq!(message.poss_dup_flag,true);
});
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.test_req_id,b"test_id".to_vec());
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = 1;
message.gap_fill_flag = true;
message.new_seq_no = 15;
test_server.send_message(message);
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"MsgSeqNum too low, expected 2 but received 1".to_vec());
thread::sleep(Duration::from_millis(500));
assert!(test_server.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::InboundMsgSeqNumLowerThanExpectedError = reason { true } else { false });
});
}
for new_seq_no in 1..3 {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = 2;
message.gap_fill_flag = true;
message.new_seq_no = new_seq_no;
test_server.send_message(message);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.ref_seq_num,2);
let mut expected_error_text = b"Attempt to lower sequence number, invalid value NewSeqNo=".to_vec();
expected_error_text.extend_from_slice(new_seq_no.to_string().as_bytes());
assert_eq!(message.text,expected_error_text);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::ValueIsIncorrectForThisTag);
engine_poll_event!(client,EngineEvent::MessageRejected(msg_connection,rejected_message) => {
assert_eq!(msg_connection,connection);
let message = rejected_message.as_any().downcast_ref::<SequenceReset>().expect("Not expected message type").clone();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.gap_fill_flag,true);
assert_eq!(message.new_seq_no,new_seq_no);
});
}
}
#[test]
fn test_11B() {
define_dictionary!(
Logon,
SequenceReset,
ResendRequest,
TestRequest,
Logout,
Reject,
);
let msg_seq_nums: Vec<u64> = vec![1,2,800,2000000];
for msg_seq_num in msg_seq_nums.clone() {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = msg_seq_num;
message.new_seq_no = 99999;
test_server.send_message(message);
let message = engine_poll_message!(client,connection,SequenceReset);
assert_eq!(message.msg_seq_num,msg_seq_num);
assert_eq!(message.gap_fill_flag,false);
assert_eq!(message.new_seq_no,99999);
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 99999;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,99999);
assert_eq!(message.test_req_id,b"test_id".to_vec());
}
for msg_seq_num in msg_seq_nums.clone() {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 10;
message.test_req_id = b"buffer_me".to_vec();
test_server.send_message(message);
let _ = test_server.recv_message::<ResendRequest>();
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = msg_seq_num;
message.new_seq_no = 99999;
test_server.send_message(message);
let message = engine_poll_message!(client,connection,SequenceReset);
assert_eq!(message.msg_seq_num,msg_seq_num);
assert_eq!(message.gap_fill_flag,false);
assert_eq!(message.new_seq_no,99999);
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 99999;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,99999);
assert_eq!(message.test_req_id,b"test_id".to_vec());
}
for msg_seq_num in msg_seq_nums.clone() {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = msg_seq_num;
message.new_seq_no = 2;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::SequenceResetResetHasNoEffect(warning_connection) => {
assert_eq!(warning_connection,connection);
});
let message = engine_poll_message!(client,connection,SequenceReset);
assert_eq!(message.msg_seq_num,msg_seq_num);
assert_eq!(message.gap_fill_flag,false);
assert_eq!(message.new_seq_no,2);
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.test_req_id,b"test_id".to_vec());
}
for msg_seq_num in msg_seq_nums.clone() {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(SequenceReset);
message.msg_seq_num = msg_seq_num;
message.new_seq_no = 1;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::SequenceResetResetInThePast(warning_connection) => {
assert_eq!(warning_connection,connection);
});
let message = engine_poll_message!(client,connection,SequenceReset);
assert_eq!(message.msg_seq_num,msg_seq_num);
assert_eq!(message.gap_fill_flag,false);
assert_eq!(message.new_seq_no,1);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.ref_seq_num,msg_seq_num);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::ValueIsIncorrectForThisTag);
assert_eq!(message.text,b"Attempt to lower sequence number, invalid value NewSeqNo=1".to_vec());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.test_req_id,b"test_id".to_vec());
}
}
#[test]
fn test_12B() {
define_dictionary!(
Logon,
Logout,
);
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
client.logout(connection);
let message = test_server.recv_message::<Logout>();
assert_eq!(message.text,b"".to_vec());
let mut message = new_fixt_message!(Logout);
message.msg_seq_num = 2;
message.session_status = b"4".to_vec(); test_server.send_message(message);
thread::sleep(Duration::from_millis(500));
assert!(test_server.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::LocalRequested = reason { true } else { false });
});
}
{
let (test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
client.logout(connection);
assert!(!test_server.is_stream_closed(Duration::from_secs(1)));
thread::sleep(Duration::from_millis(9500));
assert!(test_server.is_stream_closed(Duration::from_secs(5)));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::LogoutNoResponseError = reason { true } else { false });
});
}
}
#[test]
fn test_13B() {
define_dictionary!(
Logon,
Logout,
);
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(Logout);
message.msg_seq_num = 2;
test_server.send_message(message);
let _ = engine_poll_message!(client,connection,Logout);
let _ = test_server.recv_message::<Logout>();
let _ = test_server.stream.shutdown(Shutdown::Both);
thread::sleep(Duration::from_secs(6)); engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::RemoteRequested = reason { true } else { false });
});
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(Logout);
message.msg_seq_num = 2;
test_server.send_message(message);
let _ = engine_poll_message!(client,connection,Logout);
let _ = test_server.recv_message::<Logout>();
thread::sleep(Duration::from_secs(5));
assert!(!test_server.is_stream_closed(Duration::from_millis(100)));
thread::sleep(Duration::from_millis(5500));
assert!(recv_bytes_with_timeout(&mut test_server.stream,Duration::from_secs(1)).is_none()); assert!(test_server.is_stream_closed(Duration::from_secs(1)));
engine_poll_event!(client,EngineEvent::ConnectionTerminated(terminated_connection,reason) => {
assert_eq!(terminated_connection,connection);
assert!(if let ConnectionTerminatedReason::LogoutNoHangUpError = reason { true } else { false });
});
}
}
#[test]
fn test_14B() {
define_dictionary!(
Logon,
TestRequest,
ResendRequest,
Reject,
BusinessMessageReject,
);
define_fields!(
BeginSeqNoString: StringFieldType = 7,
TestReqIDEmpty: NoneFieldType = 112,
UndefinedField: StringFieldType = 9999999,
);
define_fixt_message!(TestRequestWithUndefinedField: b"1" => {
REQUIRED, test_req_id: TestReqID [FIX40..],
REQUIRED, undefined: UndefinedField [FIX40..],
});
define_fixt_message!(TestRequestWithNotRequiredField: b"1" => {
NOT_REQUIRED, test_req_id: TestReqID [FIX40..],
});
define_fixt_message!(TestRequestWithWrongField: b"1" => {
REQUIRED, test_req_id: TestReqID [FIX40..],
REQUIRED, heart_bt_int: HeartBtInt [FIX40..],
});
define_fixt_message!(TestRequestWithEmptyField: b"1" => {
REQUIRED, test_req_id: TestReqIDEmpty [FIX40..],
});
define_fixt_message!(ResendRequestWithStringBeginSeqNo: b"2" => {
REQUIRED, begin_seq_no: BeginSeqNoString [FIX40..],
REQUIRED, end_seq_no: EndSeqNo [FIX40..],
});
define_fixt_message!(TestRequestWithDuplicateField: b"1" => {
REQUIRED, test_req_id_1: TestReqID [FIX40..],
REQUIRED, test_req_id_2: TestReqID [FIX40..],
});
fn do_garbled_test_with_dict<F: Fn(&mut TestStream,&mut Engine,Connection),TestRequestResponse: FIXTMessage + Any + Clone>(session_reject_reason: SessionRejectReason,ref_tag_id: &'static [u8],test_func: F,dict: HashMap<&'static [u8],Box<BuildFIXTMessage + Send>>) {
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(dict);
test_func(&mut test_server,&mut client,connection);
let message = test_server.recv_message::<Reject>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.session_reject_reason.unwrap(),session_reject_reason);
assert_eq!(message.ref_tag_id,ref_tag_id);
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 3;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequestResponse);
assert_eq!(message.msg_seq_num(),3);
}
fn do_garbled_test<F: Fn(&mut TestStream,&mut Engine,Connection)>(session_reject_reason: SessionRejectReason,ref_tag_id: &'static [u8],test_func: F) {
do_garbled_test_with_dict::<F,TestRequest>(session_reject_reason,ref_tag_id,test_func,build_dictionary());
}
do_garbled_test(SessionRejectReason::InvalidTagNumber,UndefinedField::tag_bytes(),|test_server,client,connection| {
let mut message = new_fixt_message!(TestRequestWithUndefinedField);
message.msg_seq_num = 2;
message.test_req_id = b"test_id".to_vec();
message.undefined = b"undefined".to_vec();
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::UnknownTag(tag) => assert_eq!(tag,UndefinedField::tag()),
_ => panic!("Wrong parse error"),
};
});
});
do_garbled_test(SessionRejectReason::RequiredTagMissing,TestReqID::tag_bytes(),|test_server,client,connection| {
let mut message = new_fixt_message!(TestRequestWithNotRequiredField);
message.msg_seq_num = 2;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::MissingRequiredTag(tag,message) => {
assert_eq!(tag,TestReqID::tag());
assert_eq!(message.msg_seq_num(),2);
},
_ => panic!("Wrong parse error"),
};
});
});
do_garbled_test(SessionRejectReason::TagNotDefinedForThisMessageType,HeartBtInt::tag_bytes(),|test_server,client,connection| {
let mut message = new_fixt_message!(TestRequestWithWrongField);
message.msg_seq_num = 2;
message.test_req_id = b"test_id".to_vec();
message.heart_bt_int = 5;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::UnexpectedTag(tag) => assert_eq!(tag,HeartBtInt::tag()),
_ => panic!("Wrong parse error"),
};
});
});
do_garbled_test(SessionRejectReason::TagSpecifiedWithoutAValue,TestReqIDEmpty::tag_bytes(),|test_server,client,connection| {
let mut message = new_fixt_message!(TestRequestWithEmptyField);
message.msg_seq_num = 2;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::NoValueAfterTag(tag) => assert_eq!(tag,TestReqIDEmpty::tag()),
_ => panic!("Wrong parse error"),
};
});
});
{
define_fixt_message!(TestRequestWithEnumeratedField: b"1" => {
REQUIRED, test_req_id: TestReqID [FIX40..],
NOT_REQUIRED, enumerated_field: SideField [FIX40..],
});
define_fields!(
SideChar: CharFieldType = 54,
);
define_fixt_message!(TestRequestWithIncorrectField: b"1" => {
REQUIRED, test_req_id: TestReqID [FIX40..],
NOT_REQUIRED, enumerated_field: SideChar [FIX40..],
});
define_dictionary!(
Logon,
TestRequestWithEnumeratedField,
ResendRequest,
Reject,
);
do_garbled_test_with_dict::<_,TestRequestWithEnumeratedField>(SessionRejectReason::ValueIsIncorrectForThisTag,SideField::tag_bytes(),|test_server,client,connection| {
let mut message = new_fixt_message!(TestRequestWithIncorrectField);
message.test_req_id = b"test_id".to_vec();
message.enumerated_field = b'Z';
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::OutOfRangeTag(tag) => assert_eq!(tag,SideField::tag()),
_ => panic!("Wrong parse error"),
};
});
},build_dictionary());
}
do_garbled_test(SessionRejectReason::IncorrectDataFormatForValue,BeginSeqNoString::tag_bytes(),|test_server,client,connection| {
let mut message = new_fixt_message!(ResendRequestWithStringBeginSeqNo);
message.msg_seq_num = 2;
message.begin_seq_no = b"-1".to_vec();
message.end_seq_no = 0;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::WrongFormatTag(tag) => assert_eq!(tag,BeginSeqNoString::tag()),
_ => panic!("Wrong parse error"),
};
});
});
for message_bytes in vec![
b"49=TEST\x018=FIX.4.2\x019=38\x0135=1\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=204\x01", b"8=FIX.4.2\x0149=TEST\x019=38\x0135=1\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=204\x01", b"8=FIX.4.2\x019=38\x0149=TEST\x0135=1\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01112=1\x0110=204\x01", b"8=FIX.4.2\x019=38\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x0110=204\x01112=1\x01" ] {
do_garbled_test(SessionRejectReason::TagSpecifiedOutOfRequiredOrder,b"",|test_server,client,connection| {
let bytes_written = test_server.stream.write(message_bytes).unwrap();
assert_eq!(bytes_written,message_bytes.len());
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::BeginStrNotFirstTag => {},
ParseError::BodyLengthNotSecondTag => {},
ParseError::MsgTypeNotThirdTag => {},
ParseError::ChecksumNotLastTag => {},
_ => panic!("Wrong parse error"),
};
});
});
}
do_garbled_test(SessionRejectReason::TagAppearsMoreThanOnce,TestReqID::tag_bytes(),|test_server,client,connection| {
let mut message = new_fixt_message!(TestRequestWithDuplicateField);
message.msg_seq_num = 2;
message.test_req_id_1 = b"test_id_1".to_vec();
message.test_req_id_2 = b"test_id_2".to_vec();
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::DuplicateTag(tag) => assert_eq!(tag,TestReqID::tag()),
_ => panic!("Wrong parse error"),
};
});
});
{
let mut messages_bytes: Vec<(FieldTag,&'static[u8],&'static [u8])> = Vec::new();
messages_bytes.push((NoHops::tag(),NoHops::tag_bytes(),b"8=FIX.4.3\x019=999\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01627=2\x01112=1\x0110=204\x01")); messages_bytes.push((TestReqID::tag(),TestReqID::tag_bytes(),b"8=FIX.4.3\x019=999\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01627=2\x01628=1\x01112=1\x0110=204\x01")); messages_bytes.push((HopCompID::tag(),HopCompID::tag_bytes(),b"8=FIX.4.3\x019=999\x0135=1\x0149=TEST\x0156=TX\x0134=1\x0152=20090107-18:15:16\x01627=2\x01628=1\x01628=2\x01628=3\x01112=1\x0110=204\x01")); for (ref_tag_id,ref_tag_id_bytes,message_bytes) in messages_bytes {
do_garbled_test(SessionRejectReason::IncorrectNumInGroupCountForRepeatingGroup,ref_tag_id_bytes,|test_server,client,connection| {
let bytes_written = test_server.stream.write(message_bytes).unwrap();
assert_eq!(bytes_written,message_bytes.len());
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::NonRepeatingGroupTagInRepeatingGroup(tag) => assert_eq!(tag,ref_tag_id),
ParseError::RepeatingGroupTagWithNoRepeatingGroup(tag) => assert_eq!(tag,ref_tag_id),
ParseError::MissingFirstRepeatingGroupTagAfterNumberOfRepeatingGroupTag(tag) => assert_eq!(tag,ref_tag_id),
_ => panic!("Wrong parse error: {}",&parse_error),
};
});
});
}
}
{
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 2;
message.test_req_id = b"test_id".to_vec();
message.poss_dup_flag = true;
test_server.send_message(message);
engine_poll_event!(client,EngineEvent::MessageReceivedGarbled(gm_connection,parse_error) => {
assert_eq!(gm_connection,connection);
match parse_error {
ParseError::MissingConditionallyRequiredTag(tag,_) => assert_eq!(tag,OrigSendingTime::tag()),
_ => panic!("Wrong parse error"),
};
});
let message = test_server.recv_message::<Reject>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.session_reject_reason.unwrap(),SessionRejectReason::RequiredTagMissing);
assert_eq!(message.ref_msg_type,<TestRequest as MessageDetails>::msg_type());
assert_eq!(message.ref_tag_id,OrigSendingTime::tag_bytes());
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 3;
message.test_req_id = b"test_id".to_vec();
test_server.send_message(message);
let message = engine_poll_message!(client,connection,TestRequest);
assert_eq!(message.msg_seq_num(),3);
}
}
#[test]
fn test_15B() {
}
#[test]
#[ignore]
fn test_16B() {
unimplemented!();
}
#[test]
fn test_17B() {
}
#[test]
fn test_18B() {
}
#[test]
#[ignore]
fn test_19B() {
unimplemented!();
}
#[test]
fn test_20B() {
define_dictionary!(
Logon,
ResendRequest,
SequenceReset,
TestRequest,
);
let (mut test_server,mut client,connection) = TestStream::setup_test_server_and_logon(build_dictionary());
for x in 2..6 {
let mut message = new_fixt_message!(TestRequest);
message.test_req_id = x.to_string().as_bytes().to_vec();
client.send_message(connection,message);
let message = test_server.recv_message::<TestRequest>();
assert_eq!(message.msg_seq_num,x);
}
let mut message = new_fixt_message!(TestRequest);
message.msg_seq_num = 10;
message.test_req_id = b"10".to_vec();
test_server.send_message(message);
let message = test_server.recv_message::<ResendRequest>();
assert_eq!(message.msg_seq_num,6);
assert_eq!(message.begin_seq_no,2);
assert!(message.end_seq_no == 9 || message.end_seq_no == 0);
let mut message = new_fixt_message!(ResendRequest);
message.msg_seq_num = 11;
message.begin_seq_no = 2;
message.end_seq_no = 5;
test_server.send_message(message);
engine_gap_fill_resend_request!(client,connection,2..6);
let message = test_server.recv_message::<SequenceReset>();
assert_eq!(message.msg_seq_num,2);
assert_eq!(message.gap_fill_flag,true);
assert_eq!(message.new_seq_no,6);
let message = test_server.recv_message::<ResendRequest>();
assert_eq!(message.msg_seq_num,7);
assert_eq!(message.begin_seq_no,2);
assert!(message.end_seq_no == 9 || message.end_seq_no == 0);
}