summaryrefslogtreecommitdiff
path: root/src/components/protocol_handler/test
diff options
context:
space:
mode:
authorJustin Dickow <jjdickow@gmail.com>2015-02-20 09:11:18 -0500
committerJustin Dickow <jjdickow@gmail.com>2015-02-20 09:11:18 -0500
commita7c5d752cb75485baa0ded5226335d0f8eb10321 (patch)
treefbfd9251ada2cdcd5cf6a03a79887d08f6b496d7 /src/components/protocol_handler/test
parentb2b2233d866f102d3de339afa8ccaf37d3cf2570 (diff)
downloadsdl_core-a7c5d752cb75485baa0ded5226335d0f8eb10321.tar.gz
Bug Fixes and ImprovementsSynchronizationCommit
Fix Empty perform iteration request Fix type of name from string to enum SendLocation implemented on HTML5 HMI Fixed PI response on VR rejection due to high priority. Fix Apps not responsive/not able to start app/apps remain listed on SYNC even after USB disconnect Mobile API change and processing capabilities Change perform interaction request conditions. Fix SDL must always start 3sec timer before resuming the HMILevel of the app Remove redundant StartSavePersistentDataTimer() call. Change wrong predicate name to right. Added stream request handling feature Made streaming timeout in media manager configurable Put navi app in LIMITED in case of phone call Handling of audio state for applications Add stop streaming timeout into ini file Implement HMILevel resumption for job-1 Fix result code ABORTED when interrupts it by Voice recognition activation Fix incorrect value parameter unexpectedDisconnect in BCOnAppUnregistered Fix SDL send BC.OnAppUnregistered with "unexpectedDisconnect" set to "true" in case received from HMI OnExitAllApplications {"reason":"MASTER_RESET"} Fix Update ini file for iAP1 support Current working directory added to image path Fix helpers to make it workable with more then 2 parameters DCHECK() for ManageMobileCommand() replaced with log message because the latter returns false in some regular situations (e.g. TOO_MANY_PENDING_REQUESTS, see SDLAQ-CRS-10) Remove connection after closing. Signed-off-by: Justin Dickow <jjdickow@gmail.com>
Diffstat (limited to 'src/components/protocol_handler/test')
-rw-r--r--src/components/protocol_handler/test/CMakeLists.txt57
-rw-r--r--src/components/protocol_handler/test/include/control_message_matcher.h144
-rw-r--r--src/components/protocol_handler/test/include/incoming_data_handler_test.h359
-rw-r--r--src/components/protocol_handler/test/include/protocol_handler_mock.h229
-rw-r--r--src/components/protocol_handler/test/include/protocol_handler_tm_test.h758
-rw-r--r--src/components/protocol_handler/test/include/protocol_header_validator_test.h249
-rw-r--r--src/components/protocol_handler/test/include/protocol_observer_mock.h57
-rw-r--r--src/components/protocol_handler/test/include/session_observer_mock.h109
-rw-r--r--src/components/protocol_handler/test/incoming_data_handler_test.cc356
-rw-r--r--src/components/protocol_handler/test/main.cc7
-rw-r--r--src/components/protocol_handler/test/protocol_handler_tm_test.cc757
-rw-r--r--src/components/protocol_handler/test/protocol_header_validator_test.cc247
12 files changed, 3329 insertions, 0 deletions
diff --git a/src/components/protocol_handler/test/CMakeLists.txt b/src/components/protocol_handler/test/CMakeLists.txt
new file mode 100644
index 0000000000..f3373d13a7
--- /dev/null
+++ b/src/components/protocol_handler/test/CMakeLists.txt
@@ -0,0 +1,57 @@
+# Copyright (c) 2014, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+if(BUILD_TESTS)
+
+include_directories(
+ ${GMOCK_INCLUDE_DIRECTORY}
+ ${COMPONENTS_DIR}/protocol_handler/include
+ ${COMPONENTS_DIR}/protocol_handler/test/include
+)
+
+set(LIBRARIES
+ gmock
+ ProtocolHandler
+ connectionHandler
+ Utils
+ ConfigProfile
+ ProtocolLibrary
+)
+
+set(SOURCES
+ main.cc
+ incoming_data_handler_test.cc
+ protocol_header_validator_test.cc
+ protocol_handler_tm_test.cc
+)
+
+create_test("protocol_handler_test" "${SOURCES}" "${LIBRARIES}")
+
+endif()
diff --git a/src/components/protocol_handler/test/include/control_message_matcher.h b/src/components/protocol_handler/test/include/control_message_matcher.h
new file mode 100644
index 0000000000..9239d0847f
--- /dev/null
+++ b/src/components/protocol_handler/test/include/control_message_matcher.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TEST_COMPONENTS_INCLUDE_PROTOCOL_HANDLER_CONTROL_MESSAGE_MATCHER_H_
+#define TEST_COMPONENTS_INCLUDE_PROTOCOL_HANDLER_CONTROL_MESSAGE_MATCHER_H_
+
+#include <gmock/gmock.h>
+#include <string>
+#include <vector>
+#include "protocol/raw_message.h"
+#include "protocol_handler/protocol_packet.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+/*
+ * Matcher for checking RawMessage with ControlMessage
+ * Check error id
+ */
+
+MATCHER_P2(ControlMessage, ExpectedFrameData, ExpectedEncryption,
+ (std::string(ExpectedEncryption ? "Protected" : "Unprotected")
+ + " control message ")) {
+ // Nack shall be always with flag protected off
+ DCHECK(ExpectedFrameData != 0x03 /*FRAME_DATA_START_SERVICE_NACK*/ ||
+ !ExpectedEncryption);
+ const ::protocol_handler::RawMessagePtr message = arg;
+ ::protocol_handler::ProtocolPacket packet(message->connection_key());
+ const protocol_handler::RESULT_CODE result =
+ packet.deserializePacket(message->data(), message->data_size());
+ if (result != protocol_handler::RESULT_OK) {
+ *result_listener << "Error while message deserialization.";
+ return false;
+ }
+ if (::protocol_handler::FRAME_TYPE_CONTROL != packet.frame_type()) {
+ *result_listener << "Is not control message";
+ return false;
+ }
+ if (ExpectedFrameData != packet.frame_data()) {
+ *result_listener << "Control message with data 0x"
+ << std::hex << static_cast<int>(packet.frame_data())
+ << ", not 0x"
+ << std::hex << static_cast<int>(ExpectedFrameData);
+ return false;
+ }
+ if (ExpectedEncryption != packet.protection_flag()) {
+ *result_listener << "Control message is " <<
+ (ExpectedEncryption ? "" : "not ") << "protected";
+ return false;
+ }
+ return true;
+}
+
+
+
+MATCHER_P4(ControlMessage, ExpectedFrameData, ExpectedEncryption,
+ ConnectionKey, VectorMatcher,
+ (std::string(ExpectedEncryption ? "Protected" : "Unprotected")
+ + " control message ")) {
+ // Nack shall be always with flag protected off
+ DCHECK(ExpectedFrameData != 0x03 /*FRAME_DATA_START_SERVICE_NACK*/ ||
+ !ExpectedEncryption);
+
+ const ::protocol_handler::RawMessagePtr message = arg;
+ ::protocol_handler::ProtocolPacket packet(message->connection_key());
+ const protocol_handler::RESULT_CODE result =
+ packet.deserializePacket(message->data(), message->data_size());
+ if (result != protocol_handler::RESULT_OK) {
+ *result_listener << "Error while message deserialization.";
+ return false;
+ }
+
+ if (::protocol_handler::FRAME_TYPE_CONTROL != packet.frame_type()) {
+ *result_listener << "Is not control message";
+ return false;
+ }
+ if (ExpectedFrameData != packet.frame_data()) {
+ *result_listener << "Control message with data 0x"
+ << std::hex << static_cast<int>(packet.frame_data())
+ << ", not 0x"
+ << std::hex << static_cast<int>(ExpectedFrameData);
+ return false;
+ }
+ if (ExpectedEncryption != packet.protection_flag()) {
+ *result_listener << "Control message is " <<
+ (ExpectedEncryption ? "" : "not ") << "protected";
+ return false;
+ }
+ if (ConnectionKey != message->connection_key()) {
+ *result_listener << "Message for connection_id " << message->connection_key() <<
+ ", expected for connection_id " << ConnectionKey;
+ return false;
+ }
+ std::vector<uint8_t> data_vector;
+ if (packet.data() && packet.data_size()) {
+ data_vector.assign(packet.data(), packet.data() + packet.data_size());
+ }
+ ::testing::Matcher<std::vector<uint8_t> > m = VectorMatcher;
+ if (!m.Matches(data_vector)) {
+ *result_listener << "Message with " << data_vector.size()
+ << " byte data : 0x";
+ for (size_t i = 0u; i < data_vector.size(); ++i) {
+ *result_listener << std::hex << static_cast<int>(data_vector[i]);
+ }
+ return false;
+ }
+ return true;
+}
+
+
+
+
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
+#endif // TEST_COMPONENTS_INCLUDE_PROTOCOL_HANDLER_CONTROL_MESSAGE_MATCHER_H_
diff --git a/src/components/protocol_handler/test/include/incoming_data_handler_test.h b/src/components/protocol_handler/test/include/incoming_data_handler_test.h
new file mode 100644
index 0000000000..3906778d8a
--- /dev/null
+++ b/src/components/protocol_handler/test/include/incoming_data_handler_test.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_INCOMING_DATA_HANDLER_TEST_H_
+#define TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_INCOMING_DATA_HANDLER_TEST_H_
+#include <gtest/gtest.h>
+#include <vector>
+#include <list>
+
+#include "utils/macro.h"
+#include "protocol_handler/incoming_data_handler.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+using namespace protocol_handler;
+
+class IncomingDataHandlerTest : public ::testing::Test {
+ protected:
+ void SetUp() OVERRIDE {
+ data_handler.set_validator(&header_validator);
+ uid1 = 0x1234560;
+ data_handler.AddConnection(uid1);
+ uid2 = 0x1234561;
+ data_handler.AddConnection(uid2);
+ uid_unknown = 0xFEFEFE;
+ EXPECT_NE(uid1, uid_unknown);
+ EXPECT_NE(uid2, uid_unknown);
+ some_data_size = 4;
+ some_data2_size = 512;
+ some_data = new uint8_t[some_data_size];
+ some_data2 = new uint8_t[some_data2_size];
+ protov1_message_id = 0x0;
+ some_message_id = 0xABCDEF0;
+ some_session_id = 0xFEDCBA0;
+ payload_bigger_mtu.resize(MAXIMUM_FRAME_DATA_SIZE + 1);
+ }
+ void TearDown() OVERRIDE {
+ delete[] some_data;
+ delete[] some_data2;
+ }
+ void ProcessData(transport_manager::ConnectionUID uid, const uint8_t *const data,
+ const uint32_t data_size ) {
+ actual_frames = data_handler.ProcessData(RawMessage(uid, 0, data, data_size),
+ &result_code);
+ }
+
+ void AppendPacketToTMData(const ProtocolPacket& packet) {
+ const RawMessagePtr msg = packet.serializePacket();
+ EXPECT_TRUE(msg.valid());
+ EXPECT_GT(msg->data_size(), 0u);
+ tm_data.insert(tm_data.end(), msg->data(), msg->data() + msg->data_size());
+ }
+ void ProcessPacket(const ProtocolPacket& packet) {
+ AppendPacketToTMData(packet);
+ ProcessData(uid1, &tm_data[0], tm_data.size());
+ tm_data.clear();
+ }
+
+ protocol_handler::ProtocolPacket::ProtocolHeaderValidator header_validator;
+ protocol_handler::IncomingDataHandler data_handler;
+ transport_manager::ConnectionUID uid1, uid2, uid_unknown;
+ typedef std::list<ProtocolFramePtr> FrameList;
+ FrameList actual_frames;
+ RESULT_CODE result_code;
+ uint8_t* some_data, *some_data2;
+ size_t some_data_size, some_data2_size;
+ uint32_t protov1_message_id;
+ uint32_t some_message_id;
+ uint32_t some_session_id;
+ std::vector<uint8_t> tm_data;
+ std::vector<uint8_t> payload_bigger_mtu;
+};
+
+TEST_F(IncomingDataHandlerTest, NullData) {
+ ProcessData(uid1, NULL, 0);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+
+ ProcessData(uid2, NULL, 1);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+
+ uint8_t invalide_data[] = {0, 1, 2, 3, 4};
+ ProcessData(uid_unknown, invalide_data, 0);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+}
+
+TEST_F(IncomingDataHandlerTest, DataForUnknownConnection) {
+ actual_frames = data_handler.ProcessData(RawMessage(uid_unknown, 0, NULL, 0),
+ &result_code);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+
+ AppendPacketToTMData(ProtocolPacket());
+ actual_frames = data_handler.ProcessData(RawMessage(uid_unknown, 0, tm_data.data(), tm_data.size()),
+ &result_code);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+}
+
+TEST_F(IncomingDataHandlerTest, Heartbeat_per_byte) {
+ const ProtocolPacket hb_packet(uid1, PROTOCOL_VERSION_1, PROTECTION_OFF, FRAME_TYPE_CONTROL,
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u,
+ protov1_message_id, NULL);
+ const size_t hb_count = 100;
+ for (size_t i = 0; i < hb_count; ++i) {
+ AppendPacketToTMData(hb_packet);
+ // Send per 1 byte (except last byte)
+ for (size_t i = 0; i < tm_data.size() - 1; ++i) {
+ ProcessData(uid1, &tm_data[i] , 1);
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+ }
+ ProcessData(uid1, &*(tm_data.end()-1), 1);
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_EQ(1u, actual_frames.size());
+ EXPECT_EQ(hb_packet, **actual_frames.begin());
+ tm_data.clear();
+ }
+}
+
+TEST_F(IncomingDataHandlerTest, Heartbeat_pack) {
+ const ProtocolPacket hb_packet(uid1, PROTOCOL_VERSION_2, PROTECTION_OFF, FRAME_TYPE_CONTROL,
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u,
+ some_message_id, NULL);
+ const size_t hb_count = 100;
+ for (size_t i = 0u; i < hb_count; ++i) {
+ AppendPacketToTMData(hb_packet);
+ }
+ ProcessData(uid1, &tm_data[0], tm_data.size());
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_EQ(hb_count, actual_frames.size());
+ for (FrameList::iterator it = actual_frames.begin(); it != actual_frames.end(); ++it) {
+ EXPECT_EQ(hb_packet, **it);
+ }
+}
+
+TEST_F(IncomingDataHandlerTest, MixedPayloadData_TwoConnections) {
+ FrameList mobile_packets;
+ // single packet RPC
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_1, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kRpc, FRAME_DATA_SINGLE, some_session_id, some_data_size,
+ protov1_message_id, some_data));
+ // consecutive packet Audio
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_2, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE,
+ kAudio, FRAME_DATA_LAST_CONSECUTIVE, ++some_session_id, some_data2_size,
+ some_message_id, some_data2));
+ // single packet Nav
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_SINGLE,
+ kMobileNav, FRAME_DATA_SINGLE, ++some_session_id, some_data_size,
+ ++some_message_id, some_data));
+ // consecutive packet Bulk
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE,
+ kBulk, FRAME_DATA_LAST_CONSECUTIVE, ++some_session_id, some_data2_size,
+ ++some_message_id, some_data2));
+ for (FrameList::iterator it = mobile_packets.begin(); it != mobile_packets.end(); ++it) {
+ AppendPacketToTMData(**it);
+ }
+ ProcessData(uid1, &tm_data[0], tm_data.size());
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_EQ(actual_frames.size(), mobile_packets.size());
+ FrameList::const_iterator it2 = mobile_packets.begin();
+ for (FrameList::const_iterator it = actual_frames.begin(); it != actual_frames.end();
+ ++it, ++it2) {
+ // TODO(EZamakhov): investigate valgrind warning (unitialized value)
+ EXPECT_EQ(**it, **it2);
+ }
+}
+
+// TODO(EZamakhov): add validator abstraction and replace next test with check only return frames
+
+// Protocol version shall be from 1 to 3
+TEST_F(IncomingDataHandlerTest, MalformedPacket_Version) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_versions;
+ malformed_versions.push_back(0);
+ for (uint8_t version = PROTOCOL_VERSION_3 + 1; version <= PROTOCOL_VERSION_MAX; ++version) {
+ malformed_versions.push_back(version);
+ }
+ for (size_t i = 0; i < malformed_versions.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, malformed_versions[i], PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed vesion " << static_cast<int>((*it)->protocol_version());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// ServiceType shall be equal 0x0 (Control), 0x07 (RPC), 0x0A (PCM), 0x0B (Video), 0x0F (Bulk)
+TEST_F(IncomingDataHandlerTest, MalformedPacket_ServiceType) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_serv_types;
+ for (uint8_t service_type = kControl + 1; service_type < kRpc; ++service_type) {
+ malformed_serv_types.push_back(service_type);
+ }
+ malformed_serv_types.push_back(0x08);
+ malformed_serv_types.push_back(0x09);
+ malformed_serv_types.push_back(0x0C);
+ malformed_serv_types.push_back(0x0D);
+ malformed_serv_types.push_back(0x0E);
+ for (size_t i = 0; i < malformed_serv_types.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL,
+ malformed_serv_types[i], FRAME_DATA_HEART_BEAT, some_session_id, 0u,
+ some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed service type " << static_cast<int>((*it)->service_type());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// Frame type shall be 0x00 (Control), 0x01 (Single), 0x02 (First), 0x03 (Consecutive)
+TEST_F(IncomingDataHandlerTest, MalformedPacket_FrameType) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_types;
+ for (uint8_t frame_type = FRAME_TYPE_CONSECUTIVE + 1;
+ frame_type <= FRAME_TYPE_MAX_VALUE; ++frame_type) {
+ malformed_frame_types.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_types.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, malformed_frame_types[i],
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed frame type " << static_cast<int>((*it)->service_type());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data Ack), 0xFF(HB Ack)
+TEST_F(IncomingDataHandlerTest, MalformedPacket_ControlFrame) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_END_SERVICE_NACK + 1;
+ frame_type < FRAME_DATA_SERVICE_DATA_ACK; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed Control frame with data " << static_cast<int>((*it)->frame_data());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(IncomingDataHandlerTest, MalformedPacket_SingleFrame) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_SINGLE + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed Single frame with data " << static_cast<int>((*it)->frame_data());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(IncomingDataHandlerTest, MalformedPacket_FirstFrame) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_FIRST + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed First frame with data " << static_cast<int>((*it)->frame_data());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// TODO(EZamakhov): add correctness on handling 2+ connection data
+
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
+#endif // TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_INCOMING_DATA_HANDLER_TEST_H_
diff --git a/src/components/protocol_handler/test/include/protocol_handler_mock.h b/src/components/protocol_handler/test/include/protocol_handler_mock.h
new file mode 100644
index 0000000000..742968e07d
--- /dev/null
+++ b/src/components/protocol_handler/test/include/protocol_handler_mock.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_PROTOCOL_HANDLER_MOCK_H_
+#define SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_PROTOCOL_HANDLER_MOCK_H_
+
+#include <gmock/gmock.h>
+#include "transport_manager/transport_manager.h"
+#include "protocol_handler/session_observer.h"
+#include "protocol_handler/protocol_packet.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+
+using namespace protocol_handler;
+using namespace transport_manager;
+
+/*
+ * MOCK implementation of ::protocol_handler::ProtocolObserver interface
+ */
+
+class ProtocolHandlerMock : public protocol_handler::ProtocolHandler {
+ public:
+ MOCK_METHOD2(SendMessageToMobileApp,
+ void(const ::protocol_handler::RawMessagePtr message,
+ bool final_message));
+ MOCK_METHOD1(AddProtocolObserver,
+ void(::protocol_handler::ProtocolObserver *observer));
+ MOCK_METHOD1(RemoveProtocolObserver,
+ void(::protocol_handler::ProtocolObserver *observer));
+ MOCK_METHOD2(SendFramesNumber,
+ void(uint32_t connection_key, int32_t number_of_frames));
+ MOCK_METHOD2(SendHeartBeat,
+ void(int32_t connection_id, uint8_t session_id));
+ MOCK_METHOD2(SendEndSession,
+ void(int32_t connection_id, uint8_t session_id));
+ MOCK_METHOD3(SendEndService,
+ void(int32_t connection_id, uint8_t session_id, uint8_t service_type));
+};
+
+/*
+ * MOCK implementation of transport_manager::TransportManager interface
+ */
+class TransportManagerMock : public TransportManager {
+ public:
+ MOCK_METHOD0(Init,
+ int());
+ MOCK_METHOD0(SearchDevices,
+ int());
+ MOCK_METHOD1(ConnectDevice,
+ int(const DeviceHandle&));
+ MOCK_METHOD1(DisconnectDevice,
+ int(const DeviceHandle&));
+ MOCK_METHOD1(Disconnect,
+ int(const ConnectionUID &));
+ MOCK_METHOD1(DisconnectForce,
+ int(const ConnectionUID &));
+ MOCK_METHOD1(SendMessageToDevice,
+ int(const ::protocol_handler::RawMessagePtr));
+ MOCK_METHOD1(ReceiveEventFromDevice,
+ int(const TransportAdapterEvent&));
+ MOCK_METHOD1(AddTransportAdapter,
+ int(transport_adapter::TransportAdapter *));
+ MOCK_METHOD1(AddEventListener,
+ int(TransportManagerListener *));
+ MOCK_METHOD0(Stop,
+ int());
+ MOCK_METHOD1(RemoveDevice,
+ int(const DeviceHandle& ));
+ MOCK_CONST_METHOD1(Visibility,
+ int(const bool &));
+ MOCK_METHOD0(Reinit,
+ int());
+};
+
+/*
+ * MOCK implementation of protocol_handler::SessionObserver interface
+ */
+class SessionObserverMock : public protocol_handler::SessionObserver {
+ public:
+#ifdef ENABLE_SECURITY
+ MOCK_METHOD2(SetSSLContext,
+ int (const uint32_t& key,
+ security_manager::SSLContext* context));
+ MOCK_METHOD2(GetSSLContext,
+ security_manager::SSLContext* (
+ const uint32_t& key,
+ const protocol_handler::ServiceType& service_type));
+#endif // ENABLE_SECURITY
+ MOCK_METHOD2(SetProtectionFlag,
+ void(
+ const uint32_t& key,
+ const protocol_handler::ServiceType& service_type));
+ MOCK_METHOD5(OnSessionStartedCallback,
+ uint32_t(
+ const transport_manager::ConnectionUID &connection_handle,
+ const uint8_t session_id,
+ const ::protocol_handler::ServiceType &service_type,
+ const bool is_protected, uint32_t* hash_id));
+ MOCK_METHOD4(OnSessionEndedCallback,
+ uint32_t(
+ const transport_manager::ConnectionUID& connection_handle,
+ const uint8_t sessionId,
+ const uint32_t& hashCode,
+ const protocol_handler::ServiceType& service_type));
+ MOCK_METHOD1(OnApplicationFloodCallBack,
+ void(const uint32_t&));
+ MOCK_METHOD1(OnMalformedMessageCallback,
+ void(const uint32_t&));
+ MOCK_METHOD2(KeyFromPair,
+ uint32_t(
+ transport_manager::ConnectionUID connection_handle,
+ uint8_t sessionId));
+ MOCK_METHOD3(PairFromKey,
+ void(
+ uint32_t key,
+ transport_manager::ConnectionUID* connection_handle,
+ uint8_t* sessionId));
+ MOCK_METHOD4(GetDataOnSessionKey,
+ int32_t(uint32_t key,
+ uint32_t* app_id,
+ std::list<int32_t>* sessions_list,
+ uint32_t* device_id));
+ MOCK_METHOD5(GetDataOnDeviceID,
+ int32_t(
+ uint32_t device_handle,
+ std::string *device_name,
+ std::list<uint32_t> *applications_list,
+ std::string *mac_address,
+ std::string *connection_type));
+ MOCK_METHOD2(IsHeartBeatSupported,
+ bool( transport_manager::ConnectionUID connection_handle,
+ uint8_t session_id));
+ MOCK_METHOD3(ProtocolVersionUsed,
+ bool( uint32_t connection_id,
+ uint8_t session_id, uint8_t& protocol_version));
+};
+
+#ifdef ENABLE_SECURITY
+/*
+ * MOCK implementation of security_manager::SecurityManager
+ */
+class SecurityManagerMock : public security_manager::SecurityManager {
+ public:
+ MOCK_METHOD1(AddListener,
+ void(security_manager::SecurityManagerListener *));
+ MOCK_METHOD1(CreateSSLContext,
+ security_manager::SSLContext*(const uint32_t &));
+ MOCK_METHOD1(StartHandshake,
+ void(uint32_t));
+ MOCK_METHOD4(SendInternalError,
+ void(const uint32_t ,
+ const uint8_t&,
+ const std::string&,
+ const uint32_t ));
+
+ MOCK_METHOD1(set_session_observer,
+ void(::protocol_handler::SessionObserver *));
+ MOCK_METHOD1(set_protocol_handler,
+ void(::protocol_handler::ProtocolHandler *));
+ MOCK_METHOD1(set_crypto_manager,
+ void(::security_manager::CryptoManager *));
+ MOCK_METHOD1(RemoveListener,
+ void(::security_manager::SecurityManagerListener *));
+ // protocol_handler::ProtocolObserver part
+ MOCK_METHOD1(OnMessageReceived,
+ void(const ::protocol_handler::RawMessagePtr));
+ MOCK_METHOD1(OnMobileMessageSent,
+ void(const ::protocol_handler::RawMessagePtr));
+};
+
+class SSLContextMock : public security_manager::SSLContext {
+ public:
+ MOCK_CONST_METHOD0(mode, int ());
+ MOCK_METHOD2(StartHandshake,
+ security_manager::SSLContext::HandshakeResult (
+ const uint8_t** const, size_t*));
+ MOCK_METHOD4(DoHandshakeStep,
+ security_manager::SSLContext::HandshakeResult (
+ const uint8_t* const, size_t,
+ const uint8_t** const, size_t*));
+ MOCK_METHOD4(Encrypt,
+ bool (const uint8_t* const, size_t,
+ const uint8_t** const, size_t*));
+ MOCK_METHOD4(Decrypt,
+ bool (const uint8_t* const, size_t,
+ const uint8_t** const, size_t*));
+ MOCK_CONST_METHOD1(get_max_block_size, size_t (size_t));
+ MOCK_CONST_METHOD0(IsInitCompleted, bool());
+ MOCK_CONST_METHOD0(IsHandshakePending, bool());
+ MOCK_CONST_METHOD0(LastError,
+ std::string());
+};
+#endif // ENABLE_SECURITY
+}
+ // namespace test
+} // namespace components
+} // namespace protocol_handler_test
+#endif // SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_PROTOCOL_HANDLER_MOCK_H_
+
diff --git a/src/components/protocol_handler/test/include/protocol_handler_tm_test.h b/src/components/protocol_handler/test/include/protocol_handler_tm_test.h
new file mode 100644
index 0000000000..aeccf98060
--- /dev/null
+++ b/src/components/protocol_handler/test/include/protocol_handler_tm_test.h
@@ -0,0 +1,758 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_PROTOCOL_HANDLER_TM_TEST_H_
+#define TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_PROTOCOL_HANDLER_TM_TEST_H_
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include "utils/shared_ptr.h"
+
+#include "protocol_handler/protocol_handler_impl.h"
+#include "protocol/common.h"
+
+#include "protocol_handler/protocol_handler_mock.h"
+#include "protocol_handler/protocol_observer_mock.h"
+#include "protocol_handler/session_observer_mock.h"
+#include "protocol_handler/control_message_matcher.h"
+#include "security_manager/security_manager_mock.h"
+#include "security_manager/ssl_context_mock.h"
+#include "transport_manager/transport_manager_mock.h"
+#include "protocol_handler/control_message_matcher.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+
+// id passed as NULL for new session establishing
+#define NEW_SESSION_ID 0u
+#define SESSION_START_REJECT 0u
+
+using namespace ::protocol_handler;
+using namespace ::transport_manager; // For TM states
+//using namespace ::security_manager;
+using ::transport_manager::TransportManagerListener;
+using protocol_handler_test::ControlMessage;
+using ::testing::Return;
+using ::testing::ReturnNull;
+using ::testing::AnyOf;
+using ::testing::Ge;
+using ::testing::Le;
+using ::testing::_;
+using ::testing::Invoke;
+
+class ProtocolHandlerImplTest : public ::testing::Test {
+ protected:
+ void IntitProtocolHandlerImpl(const size_t period_msec, const size_t max_messages) {
+ protocol_handler_impl.reset(new ProtocolHandlerImpl(&transport_manager_mock,
+ period_msec, max_messages));
+ protocol_handler_impl->set_session_observer(&session_observer_mock);
+ tm_listener = protocol_handler_impl.get();
+ }
+ void SetUp() OVERRIDE {
+ IntitProtocolHandlerImpl(0u, 0u);
+ connection_id = 0xAu;
+ session_id = 0xFFu;
+ connection_key = 0xFF00AAu;
+ message_id = 0xABCDEFu;
+ some_date.resize(256, 0xAB);
+
+ // expect ConnectionHandler support methods call (conversion, check heartbeat)
+ EXPECT_CALL(session_observer_mock,
+ KeyFromPair(connection_id, _)).
+ //return some connection_key
+ WillRepeatedly(Return(connection_key));
+ EXPECT_CALL(session_observer_mock,
+ IsHeartBeatSupported(connection_id, _)).
+ //return false to avoid call KeepConnectionAlive
+ WillRepeatedly(Return(false));
+ }
+
+ void TearDown() OVERRIDE {
+ // Wait call methods in thread
+ usleep(100000);
+ }
+
+ // Emulate connection establish
+ void AddConnection() {
+ tm_listener->OnConnectionEstablished(
+ DeviceInfo(DeviceHandle(1u),
+ std::string("mac"),
+ std::string("name"),
+ std::string("BTMAC")),
+ connection_id);
+ }
+ void AddSession() {
+ AddConnection();
+ const ServiceType start_service = kRpc;
+ #ifdef ENABLE_SECURITY
+ // For enabled protection callback shall use protection ON
+ const bool callback_protection_flag = PROTECTION_ON;
+ #else
+ // For disabled protection callback shall ignore protection income flad and use protection OFF
+ const bool callback_protection_flag = PROTECTION_OFF;
+ #endif // ENABLE_SECURITY
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service,
+ callback_protection_flag, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack with PROTECTION_OFF (on no Security Manager)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ }
+
+#ifdef ENABLE_SECURITY
+ // Emulate security manager initilization establish
+ void AddSecurityManager() {
+ protocol_handler_impl->set_security_manager(&security_manager_mock);
+ }
+#endif // ENABLE_SECURITY
+ void SendTMMessage(uint8_t connection_id,
+ uint8_t version, bool protection, uint8_t frameType,
+ uint8_t serviceType, uint8_t frameData,
+ uint8_t sessionId, uint32_t dataSize,
+ uint32_t messageID, const uint8_t *data = 0) {
+ // Create packet
+ const ProtocolPacket packet(
+ connection_id, version, protection, frameType,
+ serviceType, frameData, sessionId, dataSize,
+ messageID, data);
+ // Emulate resive packet from transoprt manager
+ tm_listener->OnTMMessageReceived(packet.serializePacket());
+ }
+ void SendControlMessage(bool protection, uint8_t service_type,
+ uint8_t sessionId, uint32_t frame_data,
+ uint32_t dataSize = 0u, const uint8_t *data = NULL) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, protection, FRAME_TYPE_CONTROL,
+ service_type, frame_data, sessionId, dataSize, message_id, data);
+ }
+
+ ::utils::SharedPtr<ProtocolHandlerImpl> protocol_handler_impl;
+ TransportManagerListener* tm_listener;
+ // Uniq connection
+ ::transport_manager::ConnectionUID connection_id;
+ // id of established session
+ uint8_t session_id;
+ // uniq id as connection_id and session_id in one
+ uint32_t connection_key;
+ uint32_t message_id;
+ std::vector<uint8_t> some_date;
+ // Strict mocks (same as all methods EXPECT_CALL().Times(0))
+ testing::StrictMock<transport_manager_test::TransportManagerMock> transport_manager_mock;
+ testing::StrictMock<protocol_handler_test::SessionObserverMock> session_observer_mock;
+#ifdef ENABLE_SECURITY
+ testing::NiceMock<security_manager_test::SecurityManagerMock> security_manager_mock;
+ testing::NiceMock<security_manager_test::SSLContextMock> ssl_context_mock;
+#endif // ENABLE_SECURITY
+};
+
+#ifdef ENABLE_SECURITY
+class OnHandshakeDoneFunctor {
+public:
+ OnHandshakeDoneFunctor(const uint32_t connection_key, const bool result)
+ : connection_key(connection_key), result(result) {}
+ void operator()(security_manager::SecurityManagerListener * listener) const {
+ listener->OnHandshakeDone(connection_key, result);
+ }
+private:
+ const uint32_t connection_key;
+ const bool result;
+};
+#endif // ENABLE_SECURITY
+
+/*
+ * ProtocolHandler shall skip empty message
+ */
+TEST_F(ProtocolHandlerImplTest, RecieveEmptyRawMessage) {
+ tm_listener->OnTMMessageReceived(RawMessagePtr());
+}
+/*
+ * ProtocolHandler shall disconnect on no connection
+ */
+TEST_F(ProtocolHandlerImplTest, RecieveOnUnknownConenction) {
+ // expect malformed message callback call on no connection for received data
+ EXPECT_CALL(session_observer_mock,
+ OnMalformedMessageCallback(connection_id));
+
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL,
+ kRpc, FRAME_DATA_START_SERVICE, NEW_SESSION_ID, 0, message_id);
+}
+/*
+ * ProtocolHandler shall send NAck on session_observer rejection
+ * Check protection flag OFF for all services from kControl to kBulk
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Unprotected_SessionObserverReject) {
+ const int call_times = 5;
+ AddConnection();
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(
+ connection_id, NEW_SESSION_ID, AnyOf(kControl, kRpc, kAudio,
+ kMobileNav, kBulk), PROTECTION_OFF, _)).
+ Times(call_times).
+ //return sessions start rejection
+ WillRepeatedly(Return(SESSION_START_REJECT));
+
+ // expect send NAck
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_NACK, PROTECTION_OFF))).
+ Times(call_times).
+ WillRepeatedly(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, kControl, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kRpc, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kAudio, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kMobileNav,NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kBulk, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send NAck on session_observer rejection
+ * Emulate getting PROTECTION_ON and check protection flag OFF in NAck
+ * For ENABLE_SECURITY=OFF session_observer shall be called with protection flag OFF
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverReject) {
+ const int call_times = 5;
+ AddConnection();
+#ifdef ENABLE_SECURITY
+ // For enabled protection callback shall use protection ON
+ const bool callback_protection_flag = PROTECTION_ON;
+#else
+ // For disabled protection callback shall ignore protection income flad and use protection OFF
+ const bool callback_protection_flag = PROTECTION_OFF;
+#endif // ENABLE_SECURITY
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(
+ connection_id, NEW_SESSION_ID, AnyOf(kControl, kRpc, kAudio,
+ kMobileNav, kBulk), callback_protection_flag, _)).
+ Times(call_times).
+ //return sessions start rejection
+ WillRepeatedly(Return(SESSION_START_REJECT));
+
+ // expect send NAck with encryption OFF
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_NACK, PROTECTION_OFF))).
+ Times(call_times).
+ WillRepeatedly(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, kControl, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kRpc, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kAudio, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kMobileNav,NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kBulk, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack on session_observer accept
+ * Check protection flag OFF
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Unprotected_SessionObserverAccept) {
+ AddConnection();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack on session_observer accept
+ * Emulate getting PROTECTION_ON and check protection flag OFF in Ack
+ * For ENABLE_SECURITY=OFF session_observer shall be called with protection flag OFF
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverAccept) {
+ AddSession();
+}
+// TODO(EZamakhov): add test for get_hash_id/set_hash_id from protocol_handler_impl.cc
+/*
+ * ProtocolHandler shall send NAck on session_observer rejection
+ */
+TEST_F(ProtocolHandlerImplTest, EndSession_SessionObserverReject) {
+ AddSession();
+ const ServiceType service = kRpc;
+
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionEndedCallback(connection_id, session_id, _, service)).
+ // reject session start
+ WillOnce(Return(SESSION_START_REJECT));
+
+ // expect send NAck
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_END_SERVICE_NACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, service, session_id, FRAME_DATA_END_SERVICE);
+}
+/*
+ * ProtocolHandler shall send NAck on wrong hash code
+ */
+TEST_F(ProtocolHandlerImplTest, EndSession_Success) {
+ AddSession();
+ const ServiceType service = kRpc;
+
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionEndedCallback(connection_id, session_id, _, service)).
+ // return sessions start success
+ WillOnce(Return(connection_key));
+
+ // expect send Ack
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_END_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, service, session_id, FRAME_DATA_END_SERVICE);
+}
+
+#ifdef ENABLE_SECURITY
+/*
+ * ProtocolHandler shall not call Security logics with Protocol version 1
+ * Check session_observer with PROTECTION_OFF and Ack with PROTECTION_OFF
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) {
+ AddConnection();
+ // Add security manager
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack with PROTECTION_OFF (on no Security Manager)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendTMMessage(connection_id, PROTOCOL_VERSION_1, PROTECTION_ON, FRAME_TYPE_CONTROL,
+ start_service, FRAME_DATA_START_SERVICE, NEW_SESSION_ID, 0, message_id);
+}
+/*
+ * ProtocolHandler shall not call Security logics on start session with PROTECTION_OFF
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionUnprotected) {
+ AddConnection();
+ // Add security manager
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack with PROTECTION_OFF (on no Security Manager)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_OFF on fail SLL creation
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect start protection for unprotected session
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return fail protection
+ WillOnce(ReturnNull());
+
+ // expect send Ack with PROTECTION_OFF (on fail SLL creation)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on already established and initialized SLLContext
+ */
+TEST_F(ProtocolHandlerImplTest,SecurityEnable_StartSessionProtected_SSLInitialized) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is initilized
+ WillOnce(Return(true));
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_ON (on SSL is initilized)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_OFF on session handshhake fail
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeFail) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(true));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_OFF)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on session handshhake success
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeSuccess) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(true));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_ON)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on session handshhake success
+ */
+TEST_F(ProtocolHandlerImplTest,
+ SecurityEnable_StartSessionProtected_HandshakeSuccess_ServiceProtectedBefore) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(true));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_ON)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on session handshhake success
+ */
+TEST_F(ProtocolHandlerImplTest,
+ SecurityEnable_StartSessionProtected_HandshakeSuccess_SSLIsNotPending) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(false));
+
+ // Wait restart handshake operation
+ EXPECT_CALL(security_manager_mock,
+ StartHandshake(connection_key));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_ON)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect flood notification to CH
+ EXPECT_CALL(session_observer_mock,
+ OnApplicationFloodCallBack(connection_key)).
+ Times(1);
+
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kControl, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification_ThresholdValue) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to CH
+ for (size_t i = 0; i < max_messages - 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kControl, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification_VideoFrameSkip) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to CH on video data streaming
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kMobileNav, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification_AudioFrameSkip) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to CH on video data streaming
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kAudio, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerificationDisable) {
+ const size_t period_msec = 0;
+ const size_t max_messages = 0;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to session observer
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kControl, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+#endif // ENABLE_SECURITY
+} // namespace test
+} // namespace components
+} // namespace protocol_handler_test
+#endif //TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_PROTOCOL_HANDLER_TM_TEST_H_
diff --git a/src/components/protocol_handler/test/include/protocol_header_validator_test.h b/src/components/protocol_handler/test/include/protocol_header_validator_test.h
new file mode 100644
index 0000000000..91762c427f
--- /dev/null
+++ b/src/components/protocol_handler/test/include/protocol_header_validator_test.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_PROTOCOL_HEADER_VALIDATOR_TEST_H_
+#define TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_PROTOCOL_HEADER_VALIDATOR_TEST_H_
+#include <gtest/gtest.h>
+#include <vector>
+#include <list>
+
+#include "utils/macro.h"
+#include "protocol_handler/protocol_packet.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+using namespace ::protocol_handler;
+
+class ProtocolHeaderValidatorTest : public ::testing::Test {
+ protected:
+ void SetUp() OVERRIDE {
+ some_message_id = 0xABCDEF0;
+ some_session_id = 0xFEDCBA0;
+ }
+ ProtocolPacket::ProtocolHeaderValidator header_validator;
+ uint32_t some_message_id;
+ uint32_t some_session_id;
+};
+
+// Protocol version shall be from 1 to 3
+TEST_F(ProtocolHeaderValidatorTest, MaxPayloadSizeSetGet) {
+ EXPECT_EQ(std::numeric_limits<size_t>::max(),
+ header_validator.max_payload_size());
+ for (size_t value = 0; value < MAXIMUM_FRAME_DATA_SIZE * 2; ++value) {
+ header_validator.set_max_payload_size(value);
+ EXPECT_EQ(value, header_validator.max_payload_size());
+ }
+}
+
+// Protocol version shall be from 1 to 3
+TEST_F(ProtocolHeaderValidatorTest, Malformed_Version) {
+ std::vector<uint8_t> malformed_versions;
+ malformed_versions.push_back(0);
+ for (uint8_t version = PROTOCOL_VERSION_3 + 1; version <= PROTOCOL_VERSION_MAX; ++version) {
+ malformed_versions.push_back(version);
+ }
+
+ for (size_t i = 0; i < malformed_versions.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ malformed_versions[i], PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed version " << malformed_message_header.version;
+
+ }
+}
+
+// ServiceType shall be equal 0x0 (Control), 0x07 (RPC), 0x0A (PCM), 0x0B (Video), 0x0F (Bulk)
+TEST_F(ProtocolHeaderValidatorTest, Malformed_ServiceType) {
+ std::vector<uint8_t> malformed_serv_types;
+ for (uint8_t service_type = kControl + 1; service_type < kRpc; ++service_type) {
+ malformed_serv_types.push_back(service_type);
+ }
+ malformed_serv_types.push_back(0x08);
+ malformed_serv_types.push_back(0x09);
+ malformed_serv_types.push_back(0x0C);
+ malformed_serv_types.push_back(0x0D);
+ malformed_serv_types.push_back(0x0E);
+
+ for (size_t i = 0; i < malformed_serv_types.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL, malformed_serv_types[i],
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed service type " << malformed_message_header.serviceType;
+ }
+}
+
+// Frame type shall be 0x00 (Control), 0x01 (Single), 0x02 (First), 0x03 (Consecutive)
+TEST_F(ProtocolHeaderValidatorTest, Malformed_FrameType) {
+ std::vector<uint8_t> malformed_frame_types;
+ for (uint8_t frame_type = FRAME_TYPE_CONSECUTIVE + 1;
+ frame_type <= FRAME_TYPE_MAX_VALUE; ++frame_type) {
+ malformed_frame_types.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_types.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, malformed_frame_types[i],
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed frame type " << malformed_message_header.frameType;
+ }
+}
+
+// For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data Ack), 0xFF(HB Ack)
+TEST_F(ProtocolHeaderValidatorTest, Malformed_ControlFrame) {
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_END_SERVICE_NACK + 1;
+ frame_type < FRAME_DATA_SERVICE_DATA_ACK; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed Control frame with data " << malformed_message_header.frameData;
+ }
+}
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(ProtocolHeaderValidatorTest, Malformed_SingleFrame) {
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_SINGLE + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed Single frame with data " << malformed_message_header.frameData;
+ // All malformed messages shall be ignored
+ }
+}
+
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(ProtocolHeaderValidatorTest, Malformed_FirstFrame) {
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_FIRST + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed First frame with data " << malformed_message_header.frameData;
+ }
+}
+
+TEST_F(ProtocolHeaderValidatorTest, Malformed_ControlFrame_EmptyPayload) {
+ const size_t payload_size = 0u;
+ const ProtocolPacket::ProtocolHeader control_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader single_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_SINGLE, kControl,
+ FRAME_DATA_SINGLE, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader consecutive_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE, kControl,
+ FRAME_DATA_LAST_CONSECUTIVE, some_session_id, payload_size, some_message_id);
+
+ for (uint32_t max_payload_size = 0; max_payload_size < MAXIMUM_FRAME_DATA_SIZE * 2;
+ ++max_payload_size) {
+ header_validator.set_max_payload_size(MAXIMUM_FRAME_DATA_SIZE + max_payload_size);
+
+ // For Control frames Data Size value could be zero
+ EXPECT_EQ(RESULT_OK, header_validator.validate(control_message_header));
+ // For Control frames Data Size value could be zero
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(single_message_header));
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(consecutive_message_header));
+ }
+}
+
+// For Control frames Data Size value shall be less than MTU header
+TEST_F(ProtocolHeaderValidatorTest, Malformed_Payload) {
+ const size_t payload_size = MAXIMUM_FRAME_DATA_SIZE;
+ const ProtocolPacket::ProtocolHeader control_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader single_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_SINGLE, kControl,
+ FRAME_DATA_SINGLE, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader consecutive_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE, kControl,
+ FRAME_DATA_LAST_CONSECUTIVE, some_session_id, payload_size, some_message_id);
+
+ for (uint32_t max_payload_size = 0; max_payload_size < MAXIMUM_FRAME_DATA_SIZE;
+ ++max_payload_size) {
+ header_validator.set_max_payload_size(max_payload_size);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(control_message_header));
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(single_message_header));
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(consecutive_message_header));
+ }
+
+ for (uint32_t max_payload_size = MAXIMUM_FRAME_DATA_SIZE + 1; max_payload_size < MAXIMUM_FRAME_DATA_SIZE * 2;
+ ++max_payload_size) {
+ header_validator.set_max_payload_size(max_payload_size);
+ EXPECT_EQ(RESULT_OK, header_validator.validate(control_message_header));
+ EXPECT_EQ(RESULT_OK, header_validator.validate(single_message_header));
+ EXPECT_EQ(RESULT_OK, header_validator.validate(consecutive_message_header));
+ }
+}
+
+// Message ID be equal or greater than 0x01
+TEST_F(ProtocolHeaderValidatorTest, Malformed_MessageID) {
+ const uint32_t malformed_message_id = 0x0u;
+ ProtocolPacket::ProtocolHeader message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_FIRST, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, malformed_message_id);
+
+ message_header.frameType = FRAME_TYPE_FIRST;
+ message_header.version = PROTOCOL_VERSION_1;
+ EXPECT_EQ(RESULT_OK, header_validator.validate(message_header));
+
+ message_header.version = PROTOCOL_VERSION_2;
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(message_header));
+ message_header.version = PROTOCOL_VERSION_3;
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(message_header));
+
+ message_header.frameType = FRAME_TYPE_CONTROL;
+ EXPECT_EQ(RESULT_OK, header_validator.validate(message_header));
+}
+
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
+#endif // TEST_COMPONENTS_PROTOCOL_HANDLER_INCLUDE_PROTOCOL_HANDLER_PROTOCOL_HEADER_VALIDATOR_TEST_H_
diff --git a/src/components/protocol_handler/test/include/protocol_observer_mock.h b/src/components/protocol_handler/test/include/protocol_observer_mock.h
new file mode 100644
index 0000000000..c415e66e40
--- /dev/null
+++ b/src/components/protocol_handler/test/include/protocol_observer_mock.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_PROTOCOL_OBSERVER_MOCK_H_
+#define SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_PROTOCOL_OBSERVER_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <string>
+#include "protocol_handler/protocol_observer.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+
+/*
+ * MOCK implementation of ::protocol_handler::ProtocolObserver interface
+ */
+class ProtocolObserverMock : public ::protocol_handler::ProtocolObserver {
+ public:
+ MOCK_METHOD1(OnMessageReceived,
+ void(const ::protocol_handler::RawMessagePtr));
+ MOCK_METHOD1(OnMobileMessageSent,
+ void(const ::protocol_handler::RawMessagePtr));
+};
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
+#endif //SRC_COMPONENTS_PROTOCOL_HANDLER_TEST_INCLUDE_PROTOCOL_OBSERVER_MOCK_H_
diff --git a/src/components/protocol_handler/test/include/session_observer_mock.h b/src/components/protocol_handler/test/include/session_observer_mock.h
new file mode 100644
index 0000000000..d562ec8373
--- /dev/null
+++ b/src/components/protocol_handler/test/include/session_observer_mock.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_COMPONENTS_INCLUDE_PROTOCOL_HANDLER_SESSION_OBSERVER_MOCK_H_
+#define TEST_COMPONENTS_INCLUDE_PROTOCOL_HANDLER_SESSION_OBSERVER_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <string>
+#include <list>
+#include "protocol_handler/session_observer.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+/*
+ * MOCK implementation of ::protocol_handler::SessionObserver interface
+ */
+class SessionObserverMock: public ::protocol_handler::SessionObserver {
+ public:
+ MOCK_METHOD5(OnSessionStartedCallback,
+ uint32_t(
+ const transport_manager::ConnectionUID &connection_handle,
+ const uint8_t session_id,
+ const ::protocol_handler::ServiceType &service_type,
+ const bool is_protected, uint32_t* hash_id));
+ MOCK_METHOD4(OnSessionEndedCallback,
+ uint32_t(
+ const transport_manager::ConnectionUID &connection_handle,
+ const uint8_t sessionId,
+ const uint32_t &hashCode,
+ const ::protocol_handler::ServiceType &service_type));
+ MOCK_METHOD1(OnApplicationFloodCallBack,
+ void(const uint32_t&));
+ MOCK_METHOD1(OnMalformedMessageCallback,
+ void(const uint32_t&));
+ MOCK_METHOD2(KeyFromPair,
+ uint32_t(
+ transport_manager::ConnectionUID connection_handle,
+ uint8_t sessionId));
+ MOCK_METHOD3(PairFromKey,
+ void(
+ uint32_t key,
+ transport_manager::ConnectionUID *connection_handle,
+ uint8_t *sessionId));
+ MOCK_METHOD4(GetDataOnSessionKey,
+ int32_t(uint32_t key,
+ uint32_t *app_id,
+ std::list<int32_t> *sessions_list,
+ uint32_t *device_id));
+ MOCK_METHOD5(GetDataOnDeviceID,
+ int32_t(
+ uint32_t device_handle,
+ std::string *device_name,
+ std::list<uint32_t> *applications_list,
+ std::string *mac_address,
+ std::string *connection_type));
+ MOCK_METHOD2(IsHeartBeatSupported,
+ bool(transport_manager::ConnectionUID connection_handle,
+ uint8_t session_id));
+ MOCK_METHOD3(ProtocolVersionUsed,
+ bool ( uint32_t connection_id,
+ uint8_t session_id, uint8_t& protocol_version));
+#ifdef ENABLE_SECURITY
+ MOCK_METHOD2(SetSSLContext,
+ int(const uint32_t &key,
+ ::security_manager::SSLContext *context));
+ MOCK_METHOD2(GetSSLContext,
+ ::security_manager::SSLContext * (
+ const uint32_t &key,
+ const ::protocol_handler::ServiceType &service_type));
+ MOCK_METHOD2(SetProtectionFlag,
+ void(
+ const uint32_t &key,
+ const ::protocol_handler::ServiceType &service_type));
+#endif // ENABLE_SECURITY
+};
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
+#endif // TEST_COMPONENTS_INCLUDE_PROTOCOL_HANDLER_SESSION_OBSERVER_MOCK_H_
diff --git a/src/components/protocol_handler/test/incoming_data_handler_test.cc b/src/components/protocol_handler/test/incoming_data_handler_test.cc
new file mode 100644
index 0000000000..f4736f5653
--- /dev/null
+++ b/src/components/protocol_handler/test/incoming_data_handler_test.cc
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <gtest/gtest.h>
+#include <vector>
+#include <list>
+
+#include "utils/macro.h"
+#include "protocol_handler/incoming_data_handler.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+using namespace protocol_handler;
+
+class IncomingDataHandlerTest : public ::testing::Test {
+ protected:
+ void SetUp() OVERRIDE {
+ data_handler.set_validator(&header_validator);
+ uid1 = 0x1234560;
+ data_handler.AddConnection(uid1);
+ uid2 = 0x1234561;
+ data_handler.AddConnection(uid2);
+ uid_unknown = 0xFEFEFE;
+ EXPECT_NE(uid1, uid_unknown);
+ EXPECT_NE(uid2, uid_unknown);
+ some_data_size = 4;
+ some_data2_size = 512;
+ some_data = new uint8_t[some_data_size];
+ some_data2 = new uint8_t[some_data2_size];
+ protov1_message_id = 0x0;
+ some_message_id = 0xABCDEF0;
+ some_session_id = 0xFEDCBA0;
+ payload_bigger_mtu.resize(MAXIMUM_FRAME_DATA_SIZE + 1);
+ }
+ void TearDown() OVERRIDE {
+ delete[] some_data;
+ delete[] some_data2;
+ }
+ void ProcessData(transport_manager::ConnectionUID uid, const uint8_t *const data,
+ const uint32_t data_size ) {
+ actual_frames = data_handler.ProcessData(RawMessage(uid, 0, data, data_size),
+ &result_code);
+ }
+
+ void AppendPacketToTMData(const ProtocolPacket& packet) {
+ const RawMessagePtr msg = packet.serializePacket();
+ EXPECT_TRUE(msg.valid());
+ EXPECT_GT(msg->data_size(), 0u);
+ tm_data.insert(tm_data.end(), msg->data(), msg->data() + msg->data_size());
+ }
+ void ProcessPacket(const ProtocolPacket& packet) {
+ AppendPacketToTMData(packet);
+ ProcessData(uid1, &tm_data[0], tm_data.size());
+ tm_data.clear();
+ }
+
+ protocol_handler::ProtocolPacket::ProtocolHeaderValidator header_validator;
+ protocol_handler::IncomingDataHandler data_handler;
+ transport_manager::ConnectionUID uid1, uid2, uid_unknown;
+ typedef std::list<ProtocolFramePtr> FrameList;
+ FrameList actual_frames;
+ RESULT_CODE result_code;
+ uint8_t* some_data, *some_data2;
+ size_t some_data_size, some_data2_size;
+ uint32_t protov1_message_id;
+ uint32_t some_message_id;
+ uint32_t some_session_id;
+ std::vector<uint8_t> tm_data;
+ std::vector<uint8_t> payload_bigger_mtu;
+};
+
+TEST_F(IncomingDataHandlerTest, NullData) {
+ ProcessData(uid1, NULL, 0);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+
+ ProcessData(uid2, NULL, 1);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+
+ uint8_t invalide_data[] = {0, 1, 2, 3, 4};
+ ProcessData(uid_unknown, invalide_data, 0);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+}
+
+TEST_F(IncomingDataHandlerTest, DataForUnknownConnection) {
+ actual_frames = data_handler.ProcessData(RawMessage(uid_unknown, 0, NULL, 0),
+ &result_code);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+
+ AppendPacketToTMData(ProtocolPacket());
+ actual_frames = data_handler.ProcessData(RawMessage(uid_unknown, 0, tm_data.data(), tm_data.size()),
+ &result_code);
+ EXPECT_EQ(RESULT_FAIL, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+}
+
+TEST_F(IncomingDataHandlerTest, Heartbeat_per_byte) {
+ const ProtocolPacket hb_packet(uid1, PROTOCOL_VERSION_1, PROTECTION_OFF, FRAME_TYPE_CONTROL,
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u,
+ protov1_message_id, NULL);
+ const size_t hb_count = 100;
+ for (size_t i = 0; i < hb_count; ++i) {
+ AppendPacketToTMData(hb_packet);
+ // Send per 1 byte (except last byte)
+ for (size_t i = 0; i < tm_data.size() - 1; ++i) {
+ ProcessData(uid1, &tm_data[i] , 1);
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_TRUE(actual_frames.empty());
+ }
+ ProcessData(uid1, &*(tm_data.end()-1), 1);
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_EQ(1u, actual_frames.size());
+ EXPECT_EQ(hb_packet, **actual_frames.begin());
+ tm_data.clear();
+ }
+}
+
+TEST_F(IncomingDataHandlerTest, Heartbeat_pack) {
+ const ProtocolPacket hb_packet(uid1, PROTOCOL_VERSION_2, PROTECTION_OFF, FRAME_TYPE_CONTROL,
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u,
+ some_message_id, NULL);
+ const size_t hb_count = 100;
+ for (size_t i = 0u; i < hb_count; ++i) {
+ AppendPacketToTMData(hb_packet);
+ }
+ ProcessData(uid1, &tm_data[0], tm_data.size());
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_EQ(hb_count, actual_frames.size());
+ for (FrameList::iterator it = actual_frames.begin(); it != actual_frames.end(); ++it) {
+ EXPECT_EQ(hb_packet, **it);
+ }
+}
+
+TEST_F(IncomingDataHandlerTest, MixedPayloadData_TwoConnections) {
+ FrameList mobile_packets;
+ // single packet RPC
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_1, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kRpc, FRAME_DATA_SINGLE, some_session_id, some_data_size,
+ protov1_message_id, some_data));
+ // consecutive packet Audio
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_2, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE,
+ kAudio, FRAME_DATA_LAST_CONSECUTIVE, ++some_session_id, some_data2_size,
+ some_message_id, some_data2));
+ // single packet Nav
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_SINGLE,
+ kMobileNav, FRAME_DATA_SINGLE, ++some_session_id, some_data_size,
+ ++some_message_id, some_data));
+ // consecutive packet Bulk
+ mobile_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE,
+ kBulk, FRAME_DATA_LAST_CONSECUTIVE, ++some_session_id, some_data2_size,
+ ++some_message_id, some_data2));
+ for (FrameList::iterator it = mobile_packets.begin(); it != mobile_packets.end(); ++it) {
+ AppendPacketToTMData(**it);
+ }
+ ProcessData(uid1, &tm_data[0], tm_data.size());
+ EXPECT_EQ(RESULT_OK, result_code);
+ EXPECT_EQ(actual_frames.size(), mobile_packets.size());
+ FrameList::const_iterator it2 = mobile_packets.begin();
+ for (FrameList::const_iterator it = actual_frames.begin(); it != actual_frames.end();
+ ++it, ++it2) {
+ // TODO(EZamakhov): investigate valgrind warning (unitialized value)
+ EXPECT_EQ(**it, **it2);
+ }
+}
+
+// TODO(EZamakhov): add validator abstraction and replace next test with check only return frames
+
+// Protocol version shall be from 1 to 3
+TEST_F(IncomingDataHandlerTest, MalformedPacket_Version) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_versions;
+ malformed_versions.push_back(0);
+ for (uint8_t version = PROTOCOL_VERSION_4 + 1; version <= PROTOCOL_VERSION_MAX; ++version) {
+ malformed_versions.push_back(version);
+ }
+ for (size_t i = 0; i < malformed_versions.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, malformed_versions[i], PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed vesion " << static_cast<int>((*it)->protocol_version());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// ServiceType shall be equal 0x0 (Control), 0x07 (RPC), 0x0A (PCM), 0x0B (Video), 0x0F (Bulk)
+TEST_F(IncomingDataHandlerTest, MalformedPacket_ServiceType) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_serv_types;
+ for (uint8_t service_type = kControl + 1; service_type < kRpc; ++service_type) {
+ malformed_serv_types.push_back(service_type);
+ }
+ malformed_serv_types.push_back(0x08);
+ malformed_serv_types.push_back(0x09);
+ malformed_serv_types.push_back(0x0C);
+ malformed_serv_types.push_back(0x0D);
+ malformed_serv_types.push_back(0x0E);
+ for (size_t i = 0; i < malformed_serv_types.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL,
+ malformed_serv_types[i], FRAME_DATA_HEART_BEAT, some_session_id, 0u,
+ some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed service type " << static_cast<int>((*it)->service_type());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// Frame type shall be 0x00 (Control), 0x01 (Single), 0x02 (First), 0x03 (Consecutive)
+TEST_F(IncomingDataHandlerTest, MalformedPacket_FrameType) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_types;
+ for (uint8_t frame_type = FRAME_TYPE_CONSECUTIVE + 1;
+ frame_type <= FRAME_TYPE_MAX_VALUE; ++frame_type) {
+ malformed_frame_types.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_types.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, malformed_frame_types[i],
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed frame type " << static_cast<int>((*it)->service_type());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data Ack), 0xFF(HB Ack)
+TEST_F(IncomingDataHandlerTest, MalformedPacket_ControlFrame) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_END_SERVICE_NACK + 1;
+ frame_type < FRAME_DATA_SERVICE_DATA_ACK; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed Control frame with data " << static_cast<int>((*it)->frame_data());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(IncomingDataHandlerTest, MalformedPacket_SingleFrame) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_SINGLE + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed Single frame with data " << static_cast<int>((*it)->frame_data());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(IncomingDataHandlerTest, MalformedPacket_FirstFrame) {
+ FrameList malformed_packets;
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_FIRST + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ malformed_packets.push_back(
+ new ProtocolPacket(
+ uid1, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id, NULL));
+ }
+ for (FrameList::iterator it = malformed_packets.begin(); it != malformed_packets.end(); ++it) {
+ ProcessPacket(**it);
+ EXPECT_EQ(RESULT_FAIL, result_code)
+ << "Malformed First frame with data " << static_cast<int>((*it)->frame_data());
+ // All malformed messages shall be ignored
+ EXPECT_EQ(0u, actual_frames.size());
+ }
+}
+
+// TODO(EZamakhov): add correctness on handling 2+ connection data
+
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test
diff --git a/src/components/protocol_handler/test/main.cc b/src/components/protocol_handler/test/main.cc
new file mode 100644
index 0000000000..59fa20e8b5
--- /dev/null
+++ b/src/components/protocol_handler/test/main.cc
@@ -0,0 +1,7 @@
+#include "gmock/gmock.h"
+
+int main(int argc, char** argv) {
+ testing::InitGoogleMock(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/src/components/protocol_handler/test/protocol_handler_tm_test.cc b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
new file mode 100644
index 0000000000..e36d1f647b
--- /dev/null
+++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
@@ -0,0 +1,757 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <gtest/gtest.h>
+#include <string>
+#include "protocol_handler/protocol_handler_impl.h"
+#include "protocol/common.h"
+#include "control_message_matcher.h"
+#include "protocol_handler_mock.h"
+#include "protocol_observer_mock.h"
+
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+
+// id passed as NULL for new session establishing
+#define NEW_SESSION_ID 0u
+#define SESSION_START_REJECT 0u
+
+using namespace ::protocol_handler;
+using namespace ::transport_manager;
+// For TM states
+using ::transport_manager::TransportManagerListener;
+using ::testing::Return;
+using ::testing::ReturnNull;
+using ::testing::AnyOf;
+using ::testing::Ge;
+using ::testing::Le;
+using ::testing::_;
+using ::testing::Invoke;
+
+class ProtocolHandlerImplTest : public ::testing::Test {
+ protected:
+ void IntitProtocolHandlerImpl(const size_t period_msec,
+ const size_t max_messages) {
+ protocol_handler_impl.reset(
+ new ProtocolHandlerImpl(&transport_manager_mock, period_msec,
+ max_messages));
+ protocol_handler_impl->set_session_observer(&session_observer_mock);
+ tm_listener = protocol_handler_impl.get();
+ }
+ void SetUp() OVERRIDE {
+ IntitProtocolHandlerImpl(0u, 0u);
+ connection_id = 0xAu;
+ session_id = 0xFFu;
+ connection_key = 0xFF00AAu;
+ message_id = 0xABCDEFu;
+ some_date.resize(256, 0xAB);
+
+ // expect ConnectionHandler support methods call (conversion, check heartbeat)
+ EXPECT_CALL(session_observer_mock,
+ KeyFromPair(connection_id, _)).
+ //return some connection_key
+ WillRepeatedly(Return(connection_key));
+ EXPECT_CALL(session_observer_mock,
+ IsHeartBeatSupported(connection_id, _)).
+ //return false to avoid call KeepConnectionAlive
+ WillRepeatedly(Return(false));
+ }
+
+ void TearDown() OVERRIDE {
+ // Wait call methods in thread
+ usleep(100000);
+ }
+
+ // Emulate connection establish
+ void AddConnection() {
+ tm_listener->OnConnectionEstablished(
+ DeviceInfo(DeviceHandle(1u), std::string("mac"), std::string("name"),
+ std::string("BTMAC")),
+ connection_id);
+ }
+ void AddSession() {
+ AddConnection();
+ const ServiceType start_service = kRpc;
+#ifdef ENABLE_SECURITY
+ // For enabled protection callback shall use protection ON
+ const bool callback_protection_flag = PROTECTION_ON;
+#else
+ // For disabled protection callback shall ignore protection income flad and use protection OFF
+ const bool callback_protection_flag = PROTECTION_OFF;
+#endif // ENABLE_SECURITY
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service,
+ callback_protection_flag, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack with PROTECTION_OFF (on no Security Manager)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF)))
+ .WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ }
+
+#ifdef ENABLE_SECURITY
+ // Emulate security manager initilization establish
+ void AddSecurityManager() {
+ protocol_handler_impl->set_security_manager(&security_manager_mock);
+ }
+#endif // ENABLE_SECURITY
+ void SendTMMessage(uint8_t connection_id, uint8_t version, bool protection,
+ uint8_t frameType, uint8_t serviceType, uint8_t frameData,
+ uint8_t sessionId, uint32_t dataSize, uint32_t messageID,
+ const uint8_t *data = 0) {
+ // Create packet
+ const ProtocolPacket packet(connection_id, version, protection, frameType,
+ serviceType, frameData, sessionId, dataSize,
+ messageID, data);
+ // Emulate resive packet from transoprt manager
+ tm_listener->OnTMMessageReceived(packet.serializePacket());
+ }
+ void SendControlMessage(bool protection, uint8_t service_type,
+ uint8_t sessionId, uint32_t frame_data,
+ uint32_t dataSize = 0u, const uint8_t *data = NULL) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, protection,
+ FRAME_TYPE_CONTROL, service_type, frame_data, sessionId,
+ dataSize, message_id, data);
+ }
+
+ ::utils::SharedPtr<ProtocolHandlerImpl> protocol_handler_impl;
+ TransportManagerListener* tm_listener;
+ // Uniq connection
+ ::transport_manager::ConnectionUID connection_id;
+ // id of established session
+ uint8_t session_id;
+ // uniq id as connection_id and session_id in one
+ uint32_t connection_key;
+ uint32_t message_id;
+ std::vector<uint8_t> some_date;
+ // Strict mocks (same as all methods EXPECT_CALL().Times(0))
+ testing::StrictMock<protocol_handler_test::TransportManagerMock> transport_manager_mock;
+ testing::StrictMock<protocol_handler_test::SessionObserverMock> session_observer_mock;
+#ifdef ENABLE_SECURITY
+ testing::NiceMock<protocol_handler_test::SecurityManagerMock> security_manager_mock;
+ testing::NiceMock<protocol_handler_test::SSLContextMock> ssl_context_mock;
+#endif // ENABLE_SECURITY
+};
+
+#ifdef ENABLE_SECURITY
+class OnHandshakeDoneFunctor {
+public:
+ OnHandshakeDoneFunctor(const uint32_t connection_key, const bool result)
+ : connection_key(connection_key), result(result) {}
+ void operator()(security_manager::SecurityManagerListener * listener) const {
+ listener->OnHandshakeDone(connection_key, result);
+ }
+private:
+ const uint32_t connection_key;
+ const bool result;
+};
+#endif // ENABLE_SECURITY
+
+/*
+ * ProtocolHandler shall skip empty message
+ */
+TEST_F(ProtocolHandlerImplTest, RecieveEmptyRawMessage) {
+ tm_listener->OnTMMessageReceived(RawMessagePtr());
+}
+/*
+ * ProtocolHandler shall disconnect on no connection
+ */
+TEST_F(ProtocolHandlerImplTest, RecieveOnUnknownConenction) {
+ // expect malformed message callback call on no connection for received data
+ EXPECT_CALL(session_observer_mock,
+ OnMalformedMessageCallback(connection_id));
+
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF,
+ FRAME_TYPE_CONTROL, kRpc, FRAME_DATA_START_SERVICE,
+ NEW_SESSION_ID, 0, message_id);
+}
+/*
+ * ProtocolHandler shall send NAck on session_observer rejection
+ * Check protection flag OFF for all services from kControl to kBulk
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Unprotected_SessionObserverReject) {
+ const int call_times = 5;
+ AddConnection();
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(
+ connection_id, NEW_SESSION_ID, AnyOf(kControl, kRpc, kAudio,
+ kMobileNav, kBulk), PROTECTION_OFF, _)).Times(call_times).
+ //return sessions start rejection
+ WillRepeatedly(Return(SESSION_START_REJECT));
+
+ // expect send NAck
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_NACK, PROTECTION_OFF)))
+ .Times(call_times).WillRepeatedly(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, kControl, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kRpc, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kAudio, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kMobileNav, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_OFF, kBulk, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send NAck on session_observer rejection
+ * Emulate getting PROTECTION_ON and check protection flag OFF in NAck
+ * For ENABLE_SECURITY=OFF session_observer shall be called with protection flag OFF
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverReject) {
+ const int call_times = 5;
+ AddConnection();
+#ifdef ENABLE_SECURITY
+ // For enabled protection callback shall use protection ON
+ const bool callback_protection_flag = PROTECTION_ON;
+#else
+ // For disabled protection callback shall ignore protection income flad and use protection OFF
+ const bool callback_protection_flag = PROTECTION_OFF;
+#endif // ENABLE_SECURITY
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(
+ connection_id, NEW_SESSION_ID, AnyOf(kControl, kRpc, kAudio,
+ kMobileNav, kBulk), callback_protection_flag, _)).Times(
+ call_times).
+ //return sessions start rejection
+ WillRepeatedly(Return(SESSION_START_REJECT));
+
+ // expect send NAck with encryption OFF
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_NACK, PROTECTION_OFF)))
+ .Times(call_times).WillRepeatedly(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, kControl, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kRpc, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kAudio, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kMobileNav, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+ SendControlMessage(PROTECTION_ON, kBulk, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack on session_observer accept
+ * Check protection flag OFF
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Unprotected_SessionObserverAccept) {
+ AddConnection();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _))
+ .
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF)))
+ .WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, start_service, NEW_SESSION_ID,
+ FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack on session_observer accept
+ * Emulate getting PROTECTION_ON and check protection flag OFF in Ack
+ * For ENABLE_SECURITY=OFF session_observer shall be called with protection flag OFF
+ */
+TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverAccept) {
+ AddSession();
+}
+// TODO(EZamakhov): add test for get_hash_id/set_hash_id from protocol_handler_impl.cc
+/*
+ * ProtocolHandler shall send NAck on session_observer rejection
+ */
+TEST_F(ProtocolHandlerImplTest, EndSession_SessionObserverReject) {
+ AddSession();
+ const ServiceType service = kRpc;
+
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionEndedCallback(connection_id, session_id, _, service)).
+ // reject session start
+ WillOnce(Return(SESSION_START_REJECT));
+
+ // expect send NAck
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_END_SERVICE_NACK, PROTECTION_OFF)))
+ .WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, service, session_id,
+ FRAME_DATA_END_SERVICE);
+}
+/*
+ * ProtocolHandler shall send NAck on wrong hash code
+ */
+TEST_F(ProtocolHandlerImplTest, EndSession_Success) {
+ AddSession();
+ const ServiceType service = kRpc;
+
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionEndedCallback(connection_id, session_id, _, service)).
+ // return sessions start success
+ WillOnce(Return(connection_key));
+
+ // expect send Ack
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_END_SERVICE_ACK, PROTECTION_OFF)))
+ .WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, service, session_id,
+ FRAME_DATA_END_SERVICE);
+}
+
+#ifdef ENABLE_SECURITY
+/*
+ * ProtocolHandler shall not call Security logics with Protocol version 1
+ * Check session_observer with PROTECTION_OFF and Ack with PROTECTION_OFF
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) {
+ AddConnection();
+ // Add security manager
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack with PROTECTION_OFF (on no Security Manager)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendTMMessage(connection_id, PROTOCOL_VERSION_1, PROTECTION_ON, FRAME_TYPE_CONTROL,
+ start_service, FRAME_DATA_START_SERVICE, NEW_SESSION_ID, 0, message_id);
+}
+/*
+ * ProtocolHandler shall not call Security logics on start session with PROTECTION_OFF
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionUnprotected) {
+ AddConnection();
+ // Add security manager
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect send Ack with PROTECTION_OFF (on no Security Manager)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_OFF, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_OFF on fail SLL creation
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // expect start protection for unprotected session
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return fail protection
+ WillOnce(ReturnNull());
+
+ // expect send Ack with PROTECTION_OFF (on fail SLL creation)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on already established and initialized SLLContext
+ */
+TEST_F(ProtocolHandlerImplTest,SecurityEnable_StartSessionProtected_SSLInitialized) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is initilized
+ WillOnce(Return(true));
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_ON (on SSL is initilized)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_OFF on session handshhake fail
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeFail) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(true));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_OFF)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on session handshhake success
+ */
+TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeSuccess) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(true));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_ON)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on session handshhake success
+ */
+TEST_F(ProtocolHandlerImplTest,
+ SecurityEnable_StartSessionProtected_HandshakeSuccess_ServiceProtectedBefore) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(true));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_ON)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+/*
+ * ProtocolHandler shall send Ack with PROTECTION_ON on session handshhake success
+ */
+TEST_F(ProtocolHandlerImplTest,
+ SecurityEnable_StartSessionProtected_HandshakeSuccess_SSLIsNotPending) {
+ AddConnection();
+ AddSecurityManager();
+ const ServiceType start_service = kRpc;
+ // expect ConnectionHandler check
+ EXPECT_CALL(session_observer_mock,
+ OnSessionStartedCallback(connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)).
+ //return sessions start success
+ WillOnce(Return(session_id));
+
+ // call new SSLContext creation
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key)).
+ //return new SSLContext
+ WillOnce(Return(&ssl_context_mock));
+
+ // initilization check
+ EXPECT_CALL(ssl_context_mock,
+ IsInitCompleted()).
+ //emulate SSL is not initilized
+ WillOnce(Return(false));
+
+ // Pending handshake check
+ EXPECT_CALL(ssl_context_mock,
+ IsHandshakePending()).
+ //emulate is pending
+ WillOnce(Return(false));
+
+ // Wait restart handshake operation
+ EXPECT_CALL(security_manager_mock,
+ StartHandshake(connection_key));
+
+ // expect add listener for handshake result
+ EXPECT_CALL(security_manager_mock,
+ AddListener(_))
+ // emulate handshake fail
+ .WillOnce(Invoke(OnHandshakeDoneFunctor(connection_key, PROTECTION_ON)));
+
+ // Listener check SSLContext
+ EXPECT_CALL(session_observer_mock,
+ GetSSLContext(connection_key, start_service)).
+ // emulate protection for service is not enabled
+ WillOnce(ReturnNull());
+
+ // Expect service protection enable
+ EXPECT_CALL(session_observer_mock,
+ SetProtectionFlag(connection_key, start_service));
+
+ // expect send Ack with PROTECTION_OFF (on fail handshake)
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))).
+ WillOnce(Return(E_SUCCESS));
+
+ SendControlMessage(PROTECTION_ON, start_service, NEW_SESSION_ID, FRAME_DATA_START_SERVICE);
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect flood notification to CH
+ EXPECT_CALL(session_observer_mock,
+ OnApplicationFloodCallBack(connection_key)).
+ Times(1);
+
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kControl, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification_ThresholdValue) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to CH
+ for (size_t i = 0; i < max_messages - 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kControl, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification_VideoFrameSkip) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to CH on video data streaming
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kMobileNav, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerification_AudioFrameSkip) {
+ const size_t period_msec = 1000;
+ const size_t max_messages = 1000;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to CH on video data streaming
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kAudio, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+TEST_F(ProtocolHandlerImplTest,
+ FloodVerificationDisable) {
+ const size_t period_msec = 0;
+ const size_t max_messages = 0;
+ IntitProtocolHandlerImpl(period_msec, max_messages);
+ AddConnection();
+ AddSession();
+
+ // expect NO flood notification to session observer
+ for (size_t i = 0; i < max_messages + 1; ++i) {
+ SendTMMessage(connection_id, PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE,
+ kControl, FRAME_DATA_SINGLE, session_id,
+ some_date.size(), message_id, &some_date[0]);
+ }
+}
+#endif // ENABLE_SECURITY
+}
+ // namespace test
+} // namespace components
+} // namespace protocol_handler_test
diff --git a/src/components/protocol_handler/test/protocol_header_validator_test.cc b/src/components/protocol_handler/test/protocol_header_validator_test.cc
new file mode 100644
index 0000000000..0ae7910145
--- /dev/null
+++ b/src/components/protocol_handler/test/protocol_header_validator_test.cc
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#include <vector>
+#include <list>
+
+#include "utils/macro.h"
+#include "protocol_handler/protocol_packet.h"
+
+namespace test {
+namespace components {
+namespace protocol_handler_test {
+using namespace ::protocol_handler;
+
+class ProtocolHeaderValidatorTest : public ::testing::Test {
+ protected:
+ void SetUp() OVERRIDE {
+ some_message_id = 0xABCDEF0;
+ some_session_id = 0xFEDCBA0;
+ }
+ ProtocolPacket::ProtocolHeaderValidator header_validator;
+ uint32_t some_message_id;
+ uint32_t some_session_id;
+};
+
+// Protocol version shall be from 1 to 3
+TEST_F(ProtocolHeaderValidatorTest, MaxPayloadSizeSetGet) {
+ EXPECT_EQ(std::numeric_limits<size_t>::max(),
+ header_validator.max_payload_size());
+ for (size_t value = 0; value < MAXIMUM_FRAME_DATA_SIZE * 2; ++value) {
+ header_validator.set_max_payload_size(value);
+ EXPECT_EQ(value, header_validator.max_payload_size());
+ }
+}
+
+// Protocol version shall be from 1 to 3
+TEST_F(ProtocolHeaderValidatorTest, Malformed_Version) {
+ std::vector<uint8_t> malformed_versions;
+ malformed_versions.push_back(0);
+ for (uint8_t version = PROTOCOL_VERSION_4 + 1; version <= PROTOCOL_VERSION_MAX; ++version) {
+ malformed_versions.push_back(version);
+ }
+
+ for (size_t i = 0; i < malformed_versions.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ malformed_versions[i], PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed version " << malformed_message_header.version;
+
+ }
+}
+
+// ServiceType shall be equal 0x0 (Control), 0x07 (RPC), 0x0A (PCM), 0x0B (Video), 0x0F (Bulk)
+TEST_F(ProtocolHeaderValidatorTest, Malformed_ServiceType) {
+ std::vector<uint8_t> malformed_serv_types;
+ for (uint8_t service_type = kControl + 1; service_type < kRpc; ++service_type) {
+ malformed_serv_types.push_back(service_type);
+ }
+ malformed_serv_types.push_back(0x08);
+ malformed_serv_types.push_back(0x09);
+ malformed_serv_types.push_back(0x0C);
+ malformed_serv_types.push_back(0x0D);
+ malformed_serv_types.push_back(0x0E);
+
+ for (size_t i = 0; i < malformed_serv_types.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL, malformed_serv_types[i],
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed service type " << malformed_message_header.serviceType;
+ }
+}
+
+// Frame type shall be 0x00 (Control), 0x01 (Single), 0x02 (First), 0x03 (Consecutive)
+TEST_F(ProtocolHeaderValidatorTest, Malformed_FrameType) {
+ std::vector<uint8_t> malformed_frame_types;
+ for (uint8_t frame_type = FRAME_TYPE_CONSECUTIVE + 1;
+ frame_type <= FRAME_TYPE_MAX_VALUE; ++frame_type) {
+ malformed_frame_types.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_types.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, malformed_frame_types[i],
+ kControl, FRAME_DATA_HEART_BEAT, some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed frame type " << malformed_message_header.frameType;
+ }
+}
+
+// For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data Ack), 0xFF(HB Ack)
+TEST_F(ProtocolHeaderValidatorTest, Malformed_ControlFrame) {
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_END_SERVICE_NACK + 1;
+ frame_type < FRAME_DATA_SERVICE_DATA_ACK; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_CONTROL, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed Control frame with data " << malformed_message_header.frameData;
+ }
+}
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(ProtocolHeaderValidatorTest, Malformed_SingleFrame) {
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_SINGLE + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed Single frame with data " << malformed_message_header.frameData;
+ // All malformed messages shall be ignored
+ }
+}
+
+// For Single and First frames Frame info value shall be equal 0x00
+TEST_F(ProtocolHeaderValidatorTest, Malformed_FirstFrame) {
+ std::vector<uint8_t> malformed_frame_data;
+ for (uint8_t frame_type = FRAME_DATA_FIRST + 1;
+ frame_type < FRAME_DATA_MAX_VALUE; ++frame_type) {
+ malformed_frame_data.push_back(frame_type);
+ }
+ malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
+ for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
+ const ProtocolPacket::ProtocolHeader malformed_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_OFF, FRAME_TYPE_SINGLE, kControl,
+ malformed_frame_data[i], some_session_id, 0u, some_message_id);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(malformed_message_header))
+ << "Malformed First frame with data " << malformed_message_header.frameData;
+ }
+}
+
+TEST_F(ProtocolHeaderValidatorTest, Malformed_ControlFrame_EmptyPayload) {
+ const size_t payload_size = 0u;
+ const ProtocolPacket::ProtocolHeader control_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader single_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_SINGLE, kControl,
+ FRAME_DATA_SINGLE, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader consecutive_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE, kControl,
+ FRAME_DATA_LAST_CONSECUTIVE, some_session_id, payload_size, some_message_id);
+
+ for (uint32_t max_payload_size = 0; max_payload_size < MAXIMUM_FRAME_DATA_SIZE * 2;
+ ++max_payload_size) {
+ header_validator.set_max_payload_size(MAXIMUM_FRAME_DATA_SIZE + max_payload_size);
+
+ // For Control frames Data Size value could be zero
+ EXPECT_EQ(RESULT_OK, header_validator.validate(control_message_header));
+ // For Control frames Data Size value could be zero
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(single_message_header));
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(consecutive_message_header));
+ }
+}
+
+// For Control frames Data Size value shall be less than MTU header
+TEST_F(ProtocolHeaderValidatorTest, Malformed_Payload) {
+ const size_t payload_size = MAXIMUM_FRAME_DATA_SIZE;
+ const ProtocolPacket::ProtocolHeader control_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONTROL, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader single_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_SINGLE, kControl,
+ FRAME_DATA_SINGLE, some_session_id, payload_size, some_message_id);
+ const ProtocolPacket::ProtocolHeader consecutive_message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_CONSECUTIVE, kControl,
+ FRAME_DATA_LAST_CONSECUTIVE, some_session_id, payload_size, some_message_id);
+
+ for (uint32_t max_payload_size = 0; max_payload_size < MAXIMUM_FRAME_DATA_SIZE;
+ ++max_payload_size) {
+ header_validator.set_max_payload_size(max_payload_size);
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(control_message_header));
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(single_message_header));
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(consecutive_message_header));
+ }
+
+ for (uint32_t max_payload_size = MAXIMUM_FRAME_DATA_SIZE + 1; max_payload_size < MAXIMUM_FRAME_DATA_SIZE * 2;
+ ++max_payload_size) {
+ header_validator.set_max_payload_size(max_payload_size);
+ EXPECT_EQ(RESULT_OK, header_validator.validate(control_message_header));
+ EXPECT_EQ(RESULT_OK, header_validator.validate(single_message_header));
+ EXPECT_EQ(RESULT_OK, header_validator.validate(consecutive_message_header));
+ }
+}
+
+// Message ID be equal or greater than 0x01
+TEST_F(ProtocolHeaderValidatorTest, Malformed_MessageID) {
+ const uint32_t malformed_message_id = 0x0u;
+ ProtocolPacket::ProtocolHeader message_header(
+ PROTOCOL_VERSION_3, PROTECTION_ON, FRAME_TYPE_FIRST, kControl,
+ FRAME_DATA_HEART_BEAT, some_session_id, 0u, malformed_message_id);
+
+ message_header.frameType = FRAME_TYPE_FIRST;
+ message_header.version = PROTOCOL_VERSION_1;
+ EXPECT_EQ(RESULT_OK, header_validator.validate(message_header));
+
+ message_header.version = PROTOCOL_VERSION_2;
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(message_header));
+ message_header.version = PROTOCOL_VERSION_3;
+ EXPECT_EQ(RESULT_FAIL, header_validator.validate(message_header));
+
+ message_header.frameType = FRAME_TYPE_CONTROL;
+ EXPECT_EQ(RESULT_OK, header_validator.validate(message_header));
+}
+
+} // namespace protocol_handler_test
+} // namespace components
+} // namespace test