summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhii Niukalov (GitHub) <36993782+SNiukalov@users.noreply.github.com>2020-01-24 23:21:12 +0200
committerJacob Keeler <jacob.keeler@livioradio.com>2020-01-24 16:21:12 -0500
commitb901c9d720384534ab8d47735030164bd4b07d4e (patch)
treee312127ed957ac0eaee06cc9d0d8d28635e0087e
parentcf49a3ba79eea3307c3b10511eeb9c1e487a3402 (diff)
downloadsdl_core-b901c9d720384534ab8d47735030164bd4b07d4e.tar.gz
Rework Uts and add synchronization to avoid race condition in transport adapter (#3134)
* Allow code compatibility with flag TELEMETRY_MONITOR On/Off Added missed virtual keyword for SetTelemetryMonitor method. Updated related interface and dependent mock classes * Add missed mock classes and update existing ones * Update TCP transport Adapter unit test logic Replaced mock object with real TCP transport adapter to be used with mock object to allow unit testing. * Rework TransportManagerDefault class to allow its unit testing 1) Replaced local variables(raw pointers) by class members 2) Reworked Transport Manager unit tests * Add missed logic when Connection failed to ThreadedSocketConnection::threadMain() Added missed "else" case to ThreadedSocketConnection::threadMain() when connection establishing is failed * Add the Terminate method to the connection interface. To avoid race condition and deadlock during destroying object of TcpServerOriginatedSocketConnection the Terminate method was added to the ThreadedSocketConnection. Race condition can happen between the call FindEstablishedConnection from TcpTransportAdapter::Store and Terminate from TransportAdapterImpl. In case when TcpServerOriginatedSocketConnection destroyed after FindEstablishedConnection called we will get deadlock , because in destructor of TcpServerOriginatedSocketConnection we call StopAndJoinThread(), but now we are in the same thread. Co-authored-by: Andriy Byzhynar (GitHub) <AByzhynar@luxoft.com>
-rw-r--r--src/appMain/life_cycle_impl.cc3
-rw-r--r--src/components/include/test/application_manager/mock_rpc_handler.h2
-rw-r--r--src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h3
-rw-r--r--src/components/include/transport_manager/transport_adapter/transport_adapter.h8
-rw-r--r--src/components/telemetry_monitor/CMakeLists.txt1
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/connection.h7
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_manager_default.h28
-rw-r--r--src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc27
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc6
-rw-r--r--src/components/transport_manager/src/transport_manager_default.cc65
-rw-r--r--src/components/transport_manager/test/include/transport_manager/bt/mock_bluetooth_transport_adapter.h55
-rw-r--r--src/components/transport_manager/test/include/transport_manager/cloud/mock_cloud_websocket_transport_adapter.h64
-rw-r--r--src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h11
-rw-r--r--src/components/transport_manager/test/include/transport_manager/tcp/mock_tcp_transport_adapter.h8
-rw-r--r--src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_connection.h1
-rw-r--r--src/components/transport_manager/test/include/transport_manager/usb/mock_usb_aoa_adapter.h62
-rw-r--r--src/components/transport_manager/test/sample_websocket_server.cc59
-rw-r--r--src/components/transport_manager/test/tcp_transport_adapter_test.cc8
-rw-r--r--src/components/transport_manager/test/transport_adapter_test.cc12
-rw-r--r--src/components/transport_manager/test/transport_manager_default_test.cc285
-rw-r--r--src/components/transport_manager/test/websocket_connection_test.cc30
23 files changed, 566 insertions, 183 deletions
diff --git a/src/appMain/life_cycle_impl.cc b/src/appMain/life_cycle_impl.cc
index 146380f953..a7786e302b 100644
--- a/src/appMain/life_cycle_impl.cc
+++ b/src/appMain/life_cycle_impl.cc
@@ -85,7 +85,8 @@ bool LifeCycleImpl::StartComponents() {
profile_.app_info_storage());
DCHECK(!transport_manager_);
- transport_manager_ = new transport_manager::TransportManagerDefault(profile_);
+ transport_manager_ = new transport_manager::TransportManagerDefault(
+ profile_, transport_manager::TransportAdapterFactory());
DCHECK(!connection_handler_);
connection_handler_ = new connection_handler::ConnectionHandlerImpl(
diff --git a/src/components/include/test/application_manager/mock_rpc_handler.h b/src/components/include/test/application_manager/mock_rpc_handler.h
index fb577622ce..cc7fe988a0 100644
--- a/src/components/include/test/application_manager/mock_rpc_handler.h
+++ b/src/components/include/test/application_manager/mock_rpc_handler.h
@@ -30,8 +30,10 @@ class MockRPCHandler : public application_manager::rpc_handler::RPCHandler {
MOCK_METHOD1(OnErrorSending,
void(std::shared_ptr<application_manager::Message> message));
+#ifdef TELEMETRY_MONITOR
MOCK_METHOD1(SetTelemetryObserver,
void(application_manager::AMTelemetryObserver* observer));
+#endif // TELEMETRY_MONITOR
};
} // namespace application_manager_test
diff --git a/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h b/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h
index 0c0e2dd5ec..a07365f8c0 100644
--- a/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h
+++ b/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h
@@ -111,6 +111,9 @@ class MockTransportAdapter
#ifdef TELEMETRY_MONITOR
MOCK_METHOD0(GetTelemetryObserver,
::transport_manager::TMTelemetryObserver*());
+ MOCK_METHOD1(SetTelemetryObserver,
+ void(::transport_manager::TMTelemetryObserver* observer));
+
#endif // TELEMETRY_MONITOR
};
diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter.h b/src/components/include/transport_manager/transport_adapter/transport_adapter.h
index b92e010ece..8b46be253b 100644
--- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h
+++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h
@@ -357,6 +357,14 @@ class TransportAdapter {
* @param return pointer to Time metric observer
*/
virtual TMTelemetryObserver* GetTelemetryObserver() = 0;
+
+ /**
+ * @brief Setup observer for time metric.
+ *
+ * @param observer - pointer to observer
+ */
+ virtual void SetTelemetryObserver(TMTelemetryObserver* observer) = 0;
+
#endif // TELEMETRY_MONITOR
};
} // namespace transport_adapter
diff --git a/src/components/telemetry_monitor/CMakeLists.txt b/src/components/telemetry_monitor/CMakeLists.txt
index a9c0e14224..3e8b2a9741 100644
--- a/src/components/telemetry_monitor/CMakeLists.txt
+++ b/src/components/telemetry_monitor/CMakeLists.txt
@@ -47,6 +47,7 @@ include_directories (
${COMPONENTS_DIR}/media_manager/include/
${COMPONENTS_DIR}/smart_objects/include/
${COMPONENTS_DIR}/config_profile/include/
+ ${COMPONENTS_DIR}/resumption/include
${JSONCPP_INCLUDE_DIRECTORY}
${CMAKE_BINARY_DIR}/src/components/
${LOG4CXX_INCLUDE_DIRECTORY}
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h b/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h
index 2374d8a126..4d9910b9f3 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h
@@ -64,6 +64,13 @@ class Connection {
* @brief Disconnect the current connection.
*/
virtual TransportAdapter::Error Disconnect() = 0;
+
+ /**
+ * @brief Terminate method may implement the logic of correct thread
+ * termination, if necessary for specific connection. Unlike the disconnect
+ * method, which manipulates physical descriptors
+ */
+ virtual void Terminate() {}
};
typedef std::shared_ptr<Connection> ConnectionSPtr;
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h
index 11123ceb1c..7c4e07fa59 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h
@@ -74,6 +74,8 @@ class ThreadedSocketConnection : public Connection {
*/
TransportAdapter::Error Disconnect();
+ void Terminate() OVERRIDE;
+
/**
* @brief Start thread creation.
*
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h
index 0750b58aae..5f54cf8376 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h
@@ -500,7 +500,7 @@ class TransportAdapterImpl : public TransportAdapter,
*
* @param observer - pointer to observer
*/
- void SetTelemetryObserver(TMTelemetryObserver* observer);
+ void SetTelemetryObserver(TMTelemetryObserver* observer) OVERRIDE;
/**
* @brief Return Time metric observer
diff --git a/src/components/transport_manager/include/transport_manager/transport_manager_default.h b/src/components/transport_manager/include/transport_manager/transport_manager_default.h
index 7fb0904fdf..63061b14b7 100644
--- a/src/components/transport_manager/include/transport_manager/transport_manager_default.h
+++ b/src/components/transport_manager/include/transport_manager/transport_manager_default.h
@@ -44,12 +44,36 @@ class LastState;
namespace transport_manager {
+struct TransportAdapterFactory {
+ TransportAdapterFactory();
+ template <typename... Args>
+ using CreatorTA =
+ std::function<transport_adapter::TransportAdapter*(Args&&... args)>;
+#ifdef BLUETOOTH_SUPPORT
+ CreatorTA<resumption::LastState&, const TransportManagerSettings&>
+ ta_bluetooth_creator_;
+#endif
+ CreatorTA<const uint16_t,
+ resumption::LastState&,
+ const TransportManagerSettings&>
+ ta_tcp_creator_;
+#if defined(USB_SUPPORT)
+ CreatorTA<resumption::LastState&, const TransportManagerSettings&>
+ ta_usb_creator_;
+#endif
+#if defined(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
+ CreatorTA<resumption::LastState&, const TransportManagerSettings&>
+ ta_cloud_creator_;
+#endif
+};
+
/**
* @brief Default realization of transport_manager_impl class.
*/
class TransportManagerDefault : public TransportManagerImpl {
public:
- explicit TransportManagerDefault(const TransportManagerSettings& settings);
+ explicit TransportManagerDefault(const TransportManagerSettings& settings,
+ const TransportAdapterFactory& ta_factory_);
/**
* @brief Initialize transport manager.
@@ -63,6 +87,8 @@ class TransportManagerDefault : public TransportManagerImpl {
*/
virtual ~TransportManagerDefault();
+ private:
+ TransportAdapterFactory ta_factory_;
DISALLOW_COPY_AND_ASSIGN(TransportManagerDefault);
};
} // namespace transport_manager
diff --git a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc
index 96c4c2c370..7d96c685f1 100644
--- a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc
+++ b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc
@@ -62,7 +62,7 @@ ThreadedSocketConnection::ThreadedSocketConnection(
, unexpected_disconnect_(false)
, device_uid_(device_id)
, app_handle_(app_handle)
- , thread_(NULL) {
+ , thread_(nullptr) {
const std::string thread_name = std::string("Socket ") + device_handle();
thread_ = threads::CreateThread(thread_name.c_str(),
new SocketConnectionDelegate(this));
@@ -70,7 +70,7 @@ ThreadedSocketConnection::ThreadedSocketConnection(
ThreadedSocketConnection::~ThreadedSocketConnection() {
LOG4CXX_AUTO_TRACE(logger_);
- DCHECK(NULL == thread_);
+ DCHECK(nullptr == thread_);
if (-1 != read_fd_) {
close(read_fd_);
@@ -82,10 +82,12 @@ ThreadedSocketConnection::~ThreadedSocketConnection() {
void ThreadedSocketConnection::StopAndJoinThread() {
Disconnect();
- thread_->join();
- delete thread_->delegate();
- threads::DeleteThread(thread_);
- thread_ = NULL;
+ if (thread_) {
+ thread_->join();
+ delete thread_->delegate();
+ threads::DeleteThread(thread_);
+ thread_ = nullptr;
+ }
}
void ThreadedSocketConnection::Abort() {
@@ -167,16 +169,23 @@ TransportAdapter::Error ThreadedSocketConnection::Disconnect() {
return Notify();
}
+void ThreadedSocketConnection::Terminate() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ StopAndJoinThread();
+}
+
void ThreadedSocketConnection::threadMain() {
LOG4CXX_AUTO_TRACE(logger_);
- ConnectError* connect_error = NULL;
+ ConnectError* connect_error = nullptr;
if (!Establish(&connect_error)) {
LOG4CXX_ERROR(logger_, "Connection Establish failed");
delete connect_error;
Abort();
+ } else {
+ LOG4CXX_DEBUG(logger_, "Connection established");
+ controller_->ConnectDone(device_handle(), application_handle());
}
- LOG4CXX_DEBUG(logger_, "Connection established");
- controller_->ConnectDone(device_handle(), application_handle());
+
while (!terminate_flag_) {
Transmit();
}
diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
index c35520ff7b..78a9840401 100644
--- a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
+++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
@@ -138,6 +138,12 @@ void TransportAdapterImpl::Terminate() {
connections_lock_.AcquireForWriting();
std::swap(connections, connections_);
connections_lock_.Release();
+ for (const auto& connection : connections) {
+ auto& info = connection.second;
+ if (info.connection) {
+ info.connection->Terminate();
+ }
+ }
connections.clear();
LOG4CXX_DEBUG(logger_, "Connections deleted");
diff --git a/src/components/transport_manager/src/transport_manager_default.cc b/src/components/transport_manager/src/transport_manager_default.cc
index 71fc41ada9..0d58e24b5c 100644
--- a/src/components/transport_manager/src/transport_manager_default.cc
+++ b/src/components/transport_manager/src/transport_manager_default.cc
@@ -55,9 +55,39 @@
namespace transport_manager {
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+TransportAdapterFactory::TransportAdapterFactory() {
+#ifdef BLUETOOTH_SUPPORT
+ ta_bluetooth_creator_ = [](resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ return new transport_adapter::BluetoothTransportAdapter(last_state,
+ settings);
+ };
+#endif
+ ta_tcp_creator_ = [](const uint16_t port,
+ resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ return new transport_adapter::TcpTransportAdapter(
+ port, last_state, settings);
+ };
+#if defined(USB_SUPPORT)
+ ta_usb_creator_ = [](resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ return new transport_adapter::UsbAoaAdapter(last_state, settings);
+ };
+#endif
+#if defined(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
+ ta_cloud_creator_ = [](resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ return new transport_adapter::CloudWebsocketTransportAdapter(last_state,
+ settings);
+ };
+#endif
+}
+
TransportManagerDefault::TransportManagerDefault(
- const TransportManagerSettings& settings)
- : TransportManagerImpl(settings) {}
+ const TransportManagerSettings& settings,
+ const TransportAdapterFactory& ta_factory)
+ : TransportManagerImpl(settings), ta_factory_(ta_factory) {}
int TransportManagerDefault::Init(resumption::LastState& last_state) {
LOG4CXX_TRACE(logger_, "enter");
@@ -68,54 +98,45 @@ int TransportManagerDefault::Init(resumption::LastState& last_state) {
return E_TM_IS_NOT_INITIALIZED;
}
-#ifdef BLUETOOTH_SUPPORT
- transport_adapter::TransportAdapterImpl* ta_bluetooth =
- new transport_adapter::BluetoothTransportAdapter(last_state,
- get_settings());
+ const auto& settings = get_settings();
+
+#if defined(BLUETOOTH_SUPPORT)
+ auto ta_bluetooth = ta_factory_.ta_bluetooth_creator_(last_state, settings);
#ifdef TELEMETRY_MONITOR
if (metric_observer_) {
ta_bluetooth->SetTelemetryObserver(metric_observer_);
}
#endif // TELEMETRY_MONITOR
AddTransportAdapter(ta_bluetooth);
- ta_bluetooth = NULL;
-#endif
+#endif // BLUETOOTH_SUPPORT
- const uint16_t port = get_settings().transport_manager_tcp_adapter_port();
- transport_adapter::TransportAdapterImpl* ta_tcp =
- new transport_adapter::TcpTransportAdapter(
- port, last_state, get_settings());
+ auto ta_tcp = ta_factory_.ta_tcp_creator_(
+ settings.transport_manager_tcp_adapter_port(), last_state, settings);
#ifdef TELEMETRY_MONITOR
if (metric_observer_) {
ta_tcp->SetTelemetryObserver(metric_observer_);
}
#endif // TELEMETRY_MONITOR
AddTransportAdapter(ta_tcp);
- ta_tcp = NULL;
#if defined(USB_SUPPORT)
- transport_adapter::TransportAdapterImpl* ta_usb =
- new transport_adapter::UsbAoaAdapter(last_state, get_settings());
+ auto ta_usb = ta_factory_.ta_usb_creator_(last_state, settings);
#ifdef TELEMETRY_MONITOR
if (metric_observer_) {
ta_usb->SetTelemetryObserver(metric_observer_);
}
#endif // TELEMETRY_MONITOR
AddTransportAdapter(ta_usb);
- ta_usb = NULL;
#endif // USB_SUPPORT
#if defined(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
- transport_adapter::TransportAdapterImpl* ta_cloud =
- new transport_adapter::CloudWebsocketTransportAdapter(last_state,
- get_settings());
+ auto ta_cloud = ta_factory_.ta_cloud_creator_(last_state, settings);
#ifdef TELEMETRY_MONITOR
if (metric_observer_) {
ta_cloud->SetTelemetryObserver(metric_observer_);
}
#endif // TELEMETRY_MONITOR
AddTransportAdapter(ta_cloud);
- ta_cloud = NULL;
#endif // CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT
#if defined BUILD_TESTS
@@ -123,14 +144,14 @@ int TransportManagerDefault::Init(resumption::LastState& last_state) {
transport_adapter::IAP2BluetoothEmulationTransportAdapter*
iap2_bt_emu_adapter =
new transport_adapter::IAP2BluetoothEmulationTransportAdapter(
- iap2_bt_emu_port, last_state, get_settings());
+ iap2_bt_emu_port, last_state, settings);
AddTransportAdapter(iap2_bt_emu_adapter);
const uint16_t iap2_usb_emu_port = 34567;
transport_adapter::IAP2USBEmulationTransportAdapter* iap2_usb_emu_adapter =
new transport_adapter::IAP2USBEmulationTransportAdapter(
- iap2_usb_emu_port, last_state, get_settings());
+ iap2_usb_emu_port, last_state, settings);
AddTransportAdapter(iap2_usb_emu_adapter);
#endif // BUILD_TEST
diff --git a/src/components/transport_manager/test/include/transport_manager/bt/mock_bluetooth_transport_adapter.h b/src/components/transport_manager/test/include/transport_manager/bt/mock_bluetooth_transport_adapter.h
new file mode 100644
index 0000000000..ffd8cd9647
--- /dev/null
+++ b/src/components/transport_manager/test/include/transport_manager/bt/mock_bluetooth_transport_adapter.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, 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_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_BT_MOCK_BLUETOOTH_TRANSPORT_ADAPTER_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_BT_MOCK_BLUETOOTH_TRANSPORT_ADAPTER_H_
+
+#include "transport_manager/transport_adapter/mock_transport_adapter.h"
+
+namespace test {
+namespace components {
+namespace transport_manager_test {
+
+using namespace ::transport_manager::transport_adapter;
+
+class MockBluetoothTransportAdapter : public MockTransportAdapter {
+ public:
+ MOCK_CONST_METHOD0(GetDeviceType, DeviceType());
+ MOCK_CONST_METHOD0(Store, void());
+ MOCK_METHOD0(Restore, bool());
+};
+
+} // namespace transport_manager_test
+} // namespace components
+} // namespace test
+
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_BT_MOCK_BLUETOOTH_TRANSPORT_ADAPTER_H_
diff --git a/src/components/transport_manager/test/include/transport_manager/cloud/mock_cloud_websocket_transport_adapter.h b/src/components/transport_manager/test/include/transport_manager/cloud/mock_cloud_websocket_transport_adapter.h
new file mode 100644
index 0000000000..2d240ab3ff
--- /dev/null
+++ b/src/components/transport_manager/test/include/transport_manager/cloud/mock_cloud_websocket_transport_adapter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2019, 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_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_CLOUD_MOCK_CLOUD_WEBSOCKET_TRANSPORT_ADAPTER_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_CLOUD_MOCK_CLOUD_WEBSOCKET_TRANSPORT_ADAPTER_H_
+
+#include "transport_manager/cloud/cloud_websocket_transport_adapter.h"
+
+namespace test {
+namespace components {
+namespace transport_manager_test {
+
+using namespace ::transport_manager::transport_adapter;
+
+class MockCloudWebsocketTransportAdapter
+ : public CloudWebsocketTransportAdapter {
+ public:
+ MockCloudWebsocketTransportAdapter(
+ resumption::LastState& last_state,
+ const transport_manager::TransportManagerSettings& settings)
+ : CloudWebsocketTransportAdapter(last_state, settings) {}
+ MOCK_CONST_METHOD0(GetDeviceType, DeviceType());
+ MOCK_CONST_METHOD0(Store, void());
+ MOCK_METHOD0(Restore, bool());
+ MOCK_CONST_METHOD0(IsInitialised, bool());
+ MOCK_METHOD1(AddListener, void(TransportAdapterListener* listener));
+ MOCK_METHOD0(Init, TransportAdapter::Error());
+ MOCK_METHOD0(Terminate, void());
+};
+
+} // namespace transport_manager_test
+} // namespace components
+} // namespace test
+
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_CLOUD_MOCK_CLOUD_WEBSOCKET_TRANSPORT_ADAPTER_H_
diff --git a/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h b/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h
index a8b801c1fe..e29f182059 100644
--- a/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h
+++ b/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h
@@ -39,6 +39,7 @@
#include <boost/asio/placeholders.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <boost/asio/strand.hpp>
+#include <boost/asio/thread_pool.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
@@ -61,9 +62,9 @@ namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
// Accepts incoming connections and launches the WSServer
-class WSSession {
+class WSSession : public std::enable_shared_from_this<WSSession> {
private:
- class WSServer {
+ class WSServer : public std::enable_shared_from_this<WSServer> {
public:
explicit WSServer(tcp::socket&& socket);
void AddURLRoute(const std::string& route);
@@ -95,6 +96,7 @@ class WSSession {
private:
void on_accept(boost::system::error_code ec);
boost::asio::io_context ioc_;
+ boost::asio::thread_pool io_pool_;
const std::string& address_;
uint16_t port_;
tcp::acceptor acceptor_;
@@ -106,9 +108,9 @@ class WSSession {
};
// Accepts incoming connections and launches the sessions
-class WSSSession {
+class WSSSession : public std::enable_shared_from_this<WSSSession> {
private:
- class WSSServer {
+ class WSSServer : public std::enable_shared_from_this<WSSServer> {
public:
// Take ownership of the socket
WSSServer(tcp::socket&& socket, ssl::context& ctx);
@@ -148,6 +150,7 @@ class WSSSession {
private:
boost::asio::io_context ioc_;
+ boost::asio::thread_pool io_pool_;
tcp::acceptor acceptor_;
tcp::socket socket_;
ssl::context ctx_;
diff --git a/src/components/transport_manager/test/include/transport_manager/tcp/mock_tcp_transport_adapter.h b/src/components/transport_manager/test/include/transport_manager/tcp/mock_tcp_transport_adapter.h
index daa9397b7d..fb84bce085 100644
--- a/src/components/transport_manager/test/include/transport_manager/tcp/mock_tcp_transport_adapter.h
+++ b/src/components/transport_manager/test/include/transport_manager/tcp/mock_tcp_transport_adapter.h
@@ -33,10 +33,7 @@
#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_TCP_MOCK_TCP_TRANSPORT_ADAPTER_H_
#define SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_TCP_MOCK_TCP_TRANSPORT_ADAPTER_H_
-#include "gmock/gmock.h"
-#include "transport_manager/common.h"
#include "transport_manager/tcp/tcp_transport_adapter.h"
-#include "transport_manager/transport_manager_settings.h"
namespace test {
namespace components {
@@ -63,6 +60,11 @@ class MockTCPTransportAdapter : public TcpTransportAdapter {
TransportAdapter::Error(
const transport_manager::DeviceUID& device_handle,
const transport_manager::ApplicationHandle& app_handle));
+
+ MOCK_CONST_METHOD0(IsInitialised, bool());
+ MOCK_METHOD1(AddListener, void(TransportAdapterListener* listener));
+ MOCK_METHOD0(Init, TransportAdapter::Error());
+ MOCK_METHOD0(Terminate, void());
void CallStore() {
Store();
}
diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_connection.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_connection.h
index d1f48c1ed9..7bb272c82e 100644
--- a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_connection.h
+++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_connection.h
@@ -48,6 +48,7 @@ class MockConnection : public Connection {
SendData,
TransportAdapter::Error(::protocol_handler::RawMessagePtr message));
MOCK_METHOD0(Disconnect, TransportAdapter::Error());
+ MOCK_METHOD0(Terminate, void());
};
} // namespace transport_manager_test
diff --git a/src/components/transport_manager/test/include/transport_manager/usb/mock_usb_aoa_adapter.h b/src/components/transport_manager/test/include/transport_manager/usb/mock_usb_aoa_adapter.h
new file mode 100644
index 0000000000..230f5ed170
--- /dev/null
+++ b/src/components/transport_manager/test/include/transport_manager/usb/mock_usb_aoa_adapter.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019, 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_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_USB_MOCK_USB_AOA_ADAPTER_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_USB_MOCK_USB_AOA_ADAPTER_H_
+
+#include "transport_manager/usb/usb_aoa_adapter.h"
+
+namespace test {
+namespace components {
+namespace transport_manager_test {
+
+using namespace ::transport_manager::transport_adapter;
+
+class MockUsbAoaAdapter : public UsbAoaAdapter {
+ public:
+ MockUsbAoaAdapter(resumption::LastState& last_state,
+ const transport_manager::TransportManagerSettings& settings)
+ : UsbAoaAdapter(last_state, settings) {}
+ MOCK_CONST_METHOD0(GetDeviceType, DeviceType());
+ MOCK_CONST_METHOD0(IsInitialised, bool());
+ MOCK_METHOD1(AddListener, void(TransportAdapterListener* listener));
+ MOCK_METHOD0(Init, TransportAdapter::Error());
+ MOCK_METHOD0(Terminate, void());
+
+ MOCK_CONST_METHOD1(ToBeAutoConnected, bool(DeviceSptr device));
+};
+
+} // namespace transport_manager_test
+} // namespace components
+} // namespace test
+
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_USB_MOCK_USB_AOA_ADAPTER_H_
diff --git a/src/components/transport_manager/test/sample_websocket_server.cc b/src/components/transport_manager/test/sample_websocket_server.cc
index 917184a361..9b0e5b59d5 100644
--- a/src/components/transport_manager/test/sample_websocket_server.cc
+++ b/src/components/transport_manager/test/sample_websocket_server.cc
@@ -51,11 +51,12 @@ void WSSession::WSServer::AddURLRoute(const std::string& target) {
void WSSession::WSServer::Run() {
req_ = {};
- http::async_read(
- ws_.next_layer(),
- buffer_,
- req_,
- std::bind(&WSServer::OnWebsocketHandshake, this, std::placeholders::_1));
+ http::async_read(ws_.next_layer(),
+ buffer_,
+ req_,
+ std::bind(&WSServer::OnWebsocketHandshake,
+ shared_from_this(),
+ std::placeholders::_1));
}
void WSSession::WSServer::OnWebsocketHandshake(
@@ -75,9 +76,10 @@ void WSSession::WSServer::OnWebsocketHandshake(
// Accept the websocket handshake
ws_.async_accept(
req_,
- boost::asio::bind_executor(
- strand_,
- std::bind(&WSServer::OnAccept, this, std::placeholders::_1)));
+ boost::asio::bind_executor(strand_,
+ std::bind(&WSServer::OnAccept,
+ shared_from_this(),
+ std::placeholders::_1)));
}
}
@@ -112,7 +114,8 @@ std::string WSSession::WSServer::ParseRouteFromTarget(
}
WSSession::WSSession(const std::string& address, uint16_t port)
- : address_(address)
+ : io_pool_(1)
+ , address_(address)
, port_(port)
, acceptor_(ioc_)
, socket_(ioc_)
@@ -152,8 +155,10 @@ WSSession::WSSession(const std::string& address, uint16_t port)
void WSSession::Run() {
if (acceptor_.is_open()) {
acceptor_.async_accept(
- socket_, std::bind(&WSSession::on_accept, this, std::placeholders::_1));
- ioc_.run();
+ socket_,
+ std::bind(
+ &WSSession::on_accept, shared_from_this(), std::placeholders::_1));
+ boost::asio::post(io_pool_, [&]() { ioc_.run(); });
}
}
@@ -161,6 +166,7 @@ void WSSession::Stop() {
try {
ioc_.stop();
acceptor_.close();
+ io_pool_.join();
} catch (...) {
std::cerr << "Failed to close connection" << std::endl;
}
@@ -199,9 +205,10 @@ void WSSSession::WSSServer::AddURLRoute(const std::string& target) {
}
void WSSSession::WSSServer::Run() {
// Perform the SSL handshake
- wss_.next_layer().async_handshake(
- ssl::stream_base::server,
- std::bind(&WSSServer::OnSSLHandshake, this, std::placeholders::_1));
+ wss_.next_layer().async_handshake(ssl::stream_base::server,
+ std::bind(&WSSServer::OnSSLHandshake,
+ shared_from_this(),
+ std::placeholders::_1));
}
void WSSSession::WSSServer::OnSSLHandshake(beast::error_code ec) {
@@ -210,11 +217,12 @@ void WSSSession::WSSServer::OnSSLHandshake(beast::error_code ec) {
}
req_ = {};
- http::async_read(
- wss_.next_layer(),
- buffer_,
- req_,
- std::bind(&WSSServer::OnWebsocketHandshake, this, std::placeholders::_1));
+ http::async_read(wss_.next_layer(),
+ buffer_,
+ req_,
+ std::bind(&WSSServer::OnWebsocketHandshake,
+ shared_from_this(),
+ std::placeholders::_1));
}
void WSSSession::WSSServer::OnWebsocketHandshake(
@@ -233,7 +241,9 @@ void WSSSession::WSSServer::OnWebsocketHandshake(
}
// Accept the websocket handshake
wss_.async_accept(
- req_, std::bind(&WSSServer::OnAccept, this, std::placeholders::_1));
+ req_,
+ std::bind(
+ &WSSServer::OnAccept, shared_from_this(), std::placeholders::_1));
}
}
@@ -271,7 +281,8 @@ WSSSession::WSSSession(const std::string& address,
uint16_t port,
const std::string& certificate,
const std::string& private_key)
- : acceptor_(ioc_)
+ : io_pool_(1)
+ , acceptor_(ioc_)
, socket_(ioc_)
, ctx_(ssl::context::sslv23_server)
, wss_(nullptr) {
@@ -336,6 +347,7 @@ void WSSSession::Stop() {
try {
ioc_.stop();
acceptor_.close();
+ io_pool_.join();
} catch (...) {
std::cerr << "Failed to close connection" << std::endl;
}
@@ -353,8 +365,9 @@ void WSSSession::do_accept() {
if (acceptor_.is_open()) {
acceptor_.async_accept(
socket_,
- std::bind(&WSSSession::on_accept, this, std::placeholders::_1));
- ioc_.run();
+ std::bind(
+ &WSSSession::on_accept, shared_from_this(), std::placeholders::_1));
+ boost::asio::post(io_pool_, [&]() { ioc_.run(); });
}
}
diff --git a/src/components/transport_manager/test/tcp_transport_adapter_test.cc b/src/components/transport_manager/test/tcp_transport_adapter_test.cc
index f5f6cc38c8..0fbdc6d65f 100644
--- a/src/components/transport_manager/test/tcp_transport_adapter_test.cc
+++ b/src/components/transport_manager/test/tcp_transport_adapter_test.cc
@@ -350,7 +350,7 @@ TEST_F(TcpAdapterTest, StoreDataWithSeveralDevices_RestoreData) {
TEST_F(TcpAdapterTest, NotifyTransportConfigUpdated) {
MockTransportAdapterListener mock_adapter_listener;
- MockTCPTransportAdapter transport_adapter(
+ TcpTransportAdapter transport_adapter(
port, last_state_, transport_manager_settings);
transport_adapter.AddListener(&mock_adapter_listener);
@@ -359,13 +359,15 @@ TEST_F(TcpAdapterTest, NotifyTransportConfigUpdated) {
config[tc_tcp_ip_address] = std::string("192.168.1.1");
config[tc_tcp_port] = std::string("12345");
- EXPECT_CALL(mock_adapter_listener, OnTransportConfigUpdated(_)).Times(1);
+ EXPECT_CALL(mock_adapter_listener,
+ OnTransportConfigUpdated(&transport_adapter))
+ .Times(1);
transport_adapter.TransportConfigUpdated(config);
}
TEST_F(TcpAdapterTest, GetTransportConfiguration) {
- MockTCPTransportAdapter transport_adapter(
+ TcpTransportAdapter transport_adapter(
port, last_state_, transport_manager_settings);
TransportConfig config;
diff --git a/src/components/transport_manager/test/transport_adapter_test.cc b/src/components/transport_manager/test/transport_adapter_test.cc
index 712cc5f750..025c86f3ac 100644
--- a/src/components/transport_manager/test/transport_adapter_test.cc
+++ b/src/components/transport_manager/test/transport_adapter_test.cc
@@ -611,6 +611,7 @@ TEST_F(TransportAdapterTest, Disconnect_ConnectDoneSuccess) {
EXPECT_EQ(TransportAdapter::OK, new_res);
EXPECT_CALL(*serverMock, Terminate());
+ EXPECT_CALL(*mock_connection, Terminate());
}
#if defined(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
@@ -651,6 +652,9 @@ TEST_F(TransportAdapterTest, FindPending) {
ConnectionSPtr mock_connection_fake =
transport_adapter.FindPendingConnection(uniq_id, 1);
ASSERT_TRUE(mock_connection_fake.use_count() == 0);
+
+ EXPECT_CALL(*serverMock, Terminate());
+ EXPECT_CALL(*connection, Terminate());
}
TEST_F(TransportAdapterTest,
@@ -743,6 +747,8 @@ TEST_F(TransportAdapterTest,
EXPECT_EQ(ConnectionStatus::PENDING, mockdev2->connection_status());
EXPECT_CALL(*serverMock, Terminate());
+ EXPECT_CALL(*mock_connection, Terminate());
+ EXPECT_CALL(*connection2, Terminate());
}
TEST_F(TransportAdapterTest, WebsocketEndpointParsing_SUCCESS) {
@@ -864,6 +870,7 @@ TEST_F(TransportAdapterTest, DisconnectDevice_DeviceAddedConnectionCreated) {
EXPECT_EQ(ConnectionStatus::CLOSING, mockdev->connection_status());
EXPECT_CALL(*serverMock, Terminate());
+ EXPECT_CALL(*mock_connection, Terminate());
}
TEST_F(TransportAdapterTest, DeviceDisconnected) {
@@ -978,6 +985,7 @@ TEST_F(TransportAdapterTest, SendData) {
EXPECT_CALL(*dev_mock, Terminate());
EXPECT_CALL(*serverMock, Terminate());
+ EXPECT_CALL(*mock_connection, Terminate());
}
TEST_F(TransportAdapterTest, SendData_ConnectionNotEstablished) {
@@ -1018,6 +1026,7 @@ TEST_F(TransportAdapterTest, SendData_ConnectionNotEstablished) {
EXPECT_CALL(*dev_mock, Terminate());
EXPECT_CALL(*clientMock, Terminate());
EXPECT_CALL(*serverMock, Terminate());
+ EXPECT_CALL(*mock_connection, Terminate());
}
TEST_F(TransportAdapterTest, StartClientListening_ClientNotInitialized) {
@@ -1171,7 +1180,7 @@ TEST_F(TransportAdapterTest, FindEstablishedConnection) {
TransportAdapter::Error res = transport_adapter.Connect(dev_id, app_handle);
EXPECT_EQ(TransportAdapter::OK, res);
- ConnectionSPtr mock_connection = std::make_shared<MockConnection>();
+ auto mock_connection = std::make_shared<MockConnection>();
transport_adapter.ConnectionCreated(mock_connection, dev_id, app_handle);
EXPECT_CALL(transport_adapter, Store());
@@ -1182,6 +1191,7 @@ TEST_F(TransportAdapterTest, FindEstablishedConnection) {
EXPECT_EQ(mock_connection, conn);
EXPECT_CALL(*serverMock, Terminate());
+ EXPECT_CALL(*mock_connection, Terminate());
}
TEST_F(TransportAdapterTest, RunAppOnDevice_NoDeviseWithAskedId_UNSUCCESS) {
diff --git a/src/components/transport_manager/test/transport_manager_default_test.cc b/src/components/transport_manager/test/transport_manager_default_test.cc
index 40938d0370..8a7f95c74b 100644
--- a/src/components/transport_manager/test/transport_manager_default_test.cc
+++ b/src/components/transport_manager/test/transport_manager_default_test.cc
@@ -33,14 +33,21 @@
#include "transport_manager/transport_manager_default.h"
#include "gtest/gtest.h"
#include "resumption/mock_last_state.h"
+#include "transport_manager/bt/mock_bluetooth_transport_adapter.h"
+#include "transport_manager/cloud/mock_cloud_websocket_transport_adapter.h"
#include "transport_manager/mock_transport_manager_settings.h"
+#include "transport_manager/tcp/mock_tcp_transport_adapter.h"
+#include "transport_manager/transport_adapter/mock_device.h"
+#include "transport_manager/transport_adapter/mock_transport_adapter_listener.h"
#include "transport_manager/transport_manager.h"
+#include "transport_manager/usb/mock_usb_aoa_adapter.h"
namespace test {
namespace components {
namespace transport_manager_test {
using resumption_test::MockLastState;
+using ::testing::_;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
@@ -75,117 +82,211 @@ std::vector<uint8_t> kBTUUID = {0x93,
0xA8};
} // namespace
-TEST(TestTransportManagerDefault, Init_LastStateNotUsed) {
- MockTransportManagerSettings transport_manager_settings;
- transport_manager::TransportManagerDefault transport_manager(
- transport_manager_settings);
-
- NiceMock<MockLastState> mock_last_state;
- Json::Value custom_dictionary = Json::Value();
-
- ON_CALL(mock_last_state, get_dictionary())
- .WillByDefault(ReturnRef(custom_dictionary));
-
- EXPECT_CALL(transport_manager_settings, use_last_state())
- .WillRepeatedly(Return(false));
- EXPECT_CALL(transport_manager_settings, transport_manager_tcp_adapter_port())
- .WillRepeatedly(Return(12345u));
- std::string network_interface = "";
- EXPECT_CALL(transport_manager_settings,
- transport_manager_tcp_adapter_network_interface())
- .WillRepeatedly(ReturnRef(network_interface));
- EXPECT_CALL(transport_manager_settings, bluetooth_uuid())
- .WillRepeatedly(Return(kBTUUID.data()));
+class TestTransportManagerDefault : public ::testing::Test {
+ public:
+ TestTransportManagerDefault()
+ : transport_manager_settings_()
+ , unique_tcp_dev_name_("unique_tcp_device_name")
+ , dev_id_("device_id")
+ , tcp_adapter_port_(1u)
+ , network_interface_("test_iface") {}
- std::string dummy_parameter;
- EXPECT_CALL(transport_manager_settings, aoa_filter_manufacturer())
- .WillRepeatedly(ReturnRef(dummy_parameter));
- EXPECT_CALL(transport_manager_settings, aoa_filter_model_name())
- .WillRepeatedly(ReturnRef(dummy_parameter));
- EXPECT_CALL(transport_manager_settings, aoa_filter_description())
- .WillRepeatedly(ReturnRef(dummy_parameter));
- EXPECT_CALL(transport_manager_settings, aoa_filter_version())
- .WillRepeatedly(ReturnRef(dummy_parameter));
- EXPECT_CALL(transport_manager_settings, aoa_filter_uri())
- .WillRepeatedly(ReturnRef(dummy_parameter));
- EXPECT_CALL(transport_manager_settings, aoa_filter_serial_number())
- .WillRepeatedly(ReturnRef(dummy_parameter));
- transport_manager.Init(mock_last_state);
- transport_manager.Stop();
-}
+ void SetUp() OVERRIDE {
+ EXPECT_CALL(transport_manager_settings_,
+ transport_manager_tcp_adapter_network_interface())
+ .WillRepeatedly(ReturnRef(network_interface_));
+
+ // Replace creation of real transport adapters by mock objects
+ // to be able to check related function calls
+ mock_bt_ta_ = new MockBluetoothTransportAdapter();
+ mock_tcp_ta_ = new MockTCPTransportAdapter(
+ tcp_adapter_port_, mock_last_state_, transport_manager_settings_);
+ mock_usb_aoa_ta_ =
+ new MockUsbAoaAdapter(mock_last_state_, transport_manager_settings_);
+ mock_cloud_websocket_ta_ = new MockCloudWebsocketTransportAdapter(
+ mock_last_state_, transport_manager_settings_);
+
+ TransportAdapterFactory ta_factory;
+#ifdef BLUETOOTH_SUPPORT
+ ta_factory.ta_bluetooth_creator_ =
+ [&](resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ UNUSED(last_state);
+ UNUSED(settings);
+ return mock_bt_ta_;
+ };
+#endif
+ ta_factory.ta_tcp_creator_ = [&](const uint16_t port,
+ resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ UNUSED(port);
+ UNUSED(last_state);
+ UNUSED(settings);
+ return mock_tcp_ta_;
+ };
+#if defined(USB_SUPPORT)
+ ta_factory.ta_usb_creator_ = [&](resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ UNUSED(last_state);
+ UNUSED(settings);
+ return mock_usb_aoa_ta_;
+ };
+#endif
+#if defined(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
+ ta_factory.ta_cloud_creator_ =
+ [&](resumption::LastState& last_state,
+ const TransportManagerSettings& settings) {
+ UNUSED(last_state);
+ UNUSED(settings);
+ return mock_cloud_websocket_ta_;
+ };
+#endif
+ transport_manager_ = std::unique_ptr<TransportManagerDefault>(
+ new TransportManagerDefault(transport_manager_settings_, ta_factory));
+ }
-TEST(TestTransportManagerDefault, Init_LastStateUsed) {
- MockTransportManagerSettings transport_manager_settings;
- transport_manager::TransportManagerDefault transport_manager(
- transport_manager_settings);
+ void ExpectationsSettings_TM(const bool use_last_state);
+ void ExpectationsBluetooth_TA();
+ void ExpectationsTCP_TA();
+ void ExpectationsUSB_TA();
+ void ExpectationsCloudWebsocket_TA();
- NiceMock<MockLastState> mock_last_state;
- Json::Value custom_dictionary;
+ protected:
+ MockTransportManagerSettings transport_manager_settings_;
+ std::unique_ptr<TransportManagerDefault> transport_manager_;
+ NiceMock<MockLastState> mock_last_state_;
+ Json::Value custom_dictionary_;
+ const std::string unique_tcp_dev_name_;
+ const std::string dev_id_;
+ const uint16_t tcp_adapter_port_;
+ std::string network_interface_;
+ std::string dummy_parameter_;
+ // Arrange necessary transport adapters mock objects
+ MockBluetoothTransportAdapter* mock_bt_ta_;
+ MockTCPTransportAdapter* mock_tcp_ta_;
+ MockUsbAoaAdapter* mock_usb_aoa_ta_;
+ MockCloudWebsocketTransportAdapter* mock_cloud_websocket_ta_;
+};
+
+void TestTransportManagerDefault::ExpectationsSettings_TM(
+ const bool use_last_state) {
+ // Arrange TM Settings expectations
Json::Value tcp_device;
- tcp_device[kDeviceName] = "unique_tcp_device_name";
+ tcp_device[kDeviceName] = unique_tcp_dev_name_;
tcp_device[kDeviceAddress] = "127.0.0.1";
- tcp_device[kDeviceApplications][0][kApplicationPort] = kApplicationPortValue;
+ tcp_device[kDeviceApplications][0][kApplicationPort] = "1";
Json::Value bluetooth_device;
- bluetooth_device[kDeviceName] = "unique_bluetooth_device_name";
+
+ std::string unique_bt_dev_name("unique_bluetooth_device_name");
+ bluetooth_device[kDeviceName] = unique_bt_dev_name;
bluetooth_device[kDeviceAddress] = "AB:CD:EF:GH:IJ:KL";
bluetooth_device[kDeviceApplications][0][kApplicationRfcomm] =
kApplicationRfcommValue;
- custom_dictionary[kTransportManager][kTcpAdapter][kDevices][0] = tcp_device;
- custom_dictionary[kTransportManager][kBluetoothAdapter][kDevices][0] =
+ custom_dictionary_[kTransportManager][kTcpAdapter][kDevices][0] = tcp_device;
+ custom_dictionary_[kTransportManager][kBluetoothAdapter][kDevices][0] =
bluetooth_device;
+ ON_CALL(mock_last_state_, get_dictionary())
+ .WillByDefault(ReturnRef(custom_dictionary_));
- ON_CALL(mock_last_state, get_dictionary())
- .WillByDefault(ReturnRef(custom_dictionary));
+ EXPECT_CALL(transport_manager_settings_, use_last_state())
+ .WillRepeatedly(Return(use_last_state));
+ EXPECT_CALL(transport_manager_settings_, transport_manager_tcp_adapter_port())
+ .WillRepeatedly(Return(tcp_adapter_port_));
- EXPECT_CALL(transport_manager_settings, use_last_state())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(transport_manager_settings, transport_manager_tcp_adapter_port())
- .WillRepeatedly(Return(12345u));
- std::string network_interface = "";
- EXPECT_CALL(transport_manager_settings,
- transport_manager_tcp_adapter_network_interface())
- .WillRepeatedly(ReturnRef(network_interface));
- EXPECT_CALL(transport_manager_settings, bluetooth_uuid())
+ EXPECT_CALL(transport_manager_settings_, bluetooth_uuid())
.WillRepeatedly(Return(kBTUUID.data()));
- transport_manager.Init(mock_last_state);
- transport_manager.Stop();
+
+ EXPECT_CALL(transport_manager_settings_, aoa_filter_manufacturer())
+ .WillRepeatedly(ReturnRef(dummy_parameter_));
+ EXPECT_CALL(transport_manager_settings_, aoa_filter_model_name())
+ .WillRepeatedly(ReturnRef(dummy_parameter_));
+ EXPECT_CALL(transport_manager_settings_, aoa_filter_description())
+ .WillRepeatedly(ReturnRef(dummy_parameter_));
+ EXPECT_CALL(transport_manager_settings_, aoa_filter_version())
+ .WillRepeatedly(ReturnRef(dummy_parameter_));
+ EXPECT_CALL(transport_manager_settings_, aoa_filter_uri())
+ .WillRepeatedly(ReturnRef(dummy_parameter_));
+ EXPECT_CALL(transport_manager_settings_, aoa_filter_serial_number())
+ .WillRepeatedly(ReturnRef(dummy_parameter_));
}
-TEST(TestTransportManagerDefault, Init_LastStateUsed_InvalidPort) {
- MockTransportManagerSettings transport_manager_settings;
- transport_manager::TransportManagerDefault transport_manager(
- transport_manager_settings);
+void TestTransportManagerDefault::ExpectationsBluetooth_TA() {
+ // Expectations for Mock of bluetooth transport adapter
+#ifdef BLUETOOTH_SUPPORT
+ EXPECT_CALL(*mock_bt_ta_, AddListener(_));
+ EXPECT_CALL(*mock_bt_ta_, IsInitialised()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_bt_ta_, Init())
+ .WillRepeatedly(Return(TransportAdapter::OK));
+ EXPECT_CALL(*mock_bt_ta_, Terminate());
+#endif
+}
- NiceMock<MockLastState> mock_last_state;
- Json::Value custom_dictionary;
- Json::Value tcp_device;
- tcp_device[kDeviceName] = "unique_tcp_device_name";
- tcp_device[kDeviceAddress] = "127.0.0.1";
- tcp_device[kDeviceApplications][0][kApplicationPort] = "1";
- Json::Value bluetooth_device;
- bluetooth_device[kDeviceName] = "unique_bluetooth_device_name";
- bluetooth_device[kDeviceAddress] = "AB:CD:EF:GH:IJ:KL";
- bluetooth_device[kDeviceApplications][0][kApplicationRfcomm] =
- kApplicationRfcommValue;
- custom_dictionary[kTransportManager][kTcpAdapter][kDevices][0] = tcp_device;
- custom_dictionary[kTransportManager][kBluetoothAdapter][kDevices][0] =
- bluetooth_device;
+void TestTransportManagerDefault::ExpectationsTCP_TA() {
+ // Expectations for Mock of TCP transport adapter
+ EXPECT_CALL(*mock_tcp_ta_, AddListener(_));
+ EXPECT_CALL(*mock_tcp_ta_, IsInitialised()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_tcp_ta_, Init())
+ .WillRepeatedly(Return(TransportAdapter::OK));
+
+ std::shared_ptr<MockDevice> mockdev =
+ std::make_shared<MockDevice>(dev_id_, unique_tcp_dev_name_);
+ EXPECT_CALL(*mock_tcp_ta_, FindDevice(unique_tcp_dev_name_))
+ .WillRepeatedly(Return(mockdev));
+ const int app_handle = 1;
+ EXPECT_CALL(*mock_tcp_ta_, Connect(unique_tcp_dev_name_, app_handle))
+ .Times(0);
+ EXPECT_CALL(*mock_tcp_ta_, Terminate());
+}
- ON_CALL(mock_last_state, get_dictionary())
- .WillByDefault(ReturnRef(custom_dictionary));
+void TestTransportManagerDefault::ExpectationsUSB_TA() {
+ // Expectations for Mock of USB transport adapter
+#if defined(USB_SUPPORT)
+ EXPECT_CALL(*mock_usb_aoa_ta_, AddListener(_));
+ EXPECT_CALL(*mock_usb_aoa_ta_, IsInitialised()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_usb_aoa_ta_, Init())
+ .WillRepeatedly(Return(TransportAdapter::OK));
+ EXPECT_CALL(*mock_usb_aoa_ta_, Terminate());
+#endif
+}
- EXPECT_CALL(transport_manager_settings, use_last_state())
+void TestTransportManagerDefault::ExpectationsCloudWebsocket_TA() {
+ // Expectations for Mock of Cloud Websocket transport adapter
+#if defined(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
+ EXPECT_CALL(*mock_cloud_websocket_ta_, AddListener(_));
+ EXPECT_CALL(*mock_cloud_websocket_ta_, IsInitialised())
.WillRepeatedly(Return(true));
- EXPECT_CALL(transport_manager_settings, transport_manager_tcp_adapter_port())
- .WillRepeatedly(Return(1u));
- std::string network_interface = "";
- EXPECT_CALL(transport_manager_settings,
- transport_manager_tcp_adapter_network_interface())
- .WillRepeatedly(ReturnRef(network_interface));
- EXPECT_CALL(transport_manager_settings, bluetooth_uuid())
- .WillRepeatedly(Return(kBTUUID.data()));
- transport_manager.Init(mock_last_state);
- transport_manager.Stop();
+ EXPECT_CALL(*mock_cloud_websocket_ta_, Init())
+ .WillRepeatedly(Return(TransportAdapter::OK));
+ EXPECT_CALL(*mock_cloud_websocket_ta_, Terminate());
+#endif
+}
+
+TEST_F(TestTransportManagerDefault, Init_LastStateNotUsed) {
+ const bool use_last_state = false;
+ ExpectationsSettings_TM(use_last_state);
+
+ ExpectationsBluetooth_TA();
+ ExpectationsTCP_TA();
+ ExpectationsUSB_TA();
+ ExpectationsCloudWebsocket_TA();
+
+ // Act
+ transport_manager_->Init(mock_last_state_);
+ transport_manager_->Stop();
+}
+
+TEST_F(TestTransportManagerDefault, Init_LastStateUsed) {
+ const bool use_last_state = true;
+ ExpectationsSettings_TM(use_last_state);
+
+ ExpectationsBluetooth_TA();
+ ExpectationsTCP_TA();
+ ExpectationsUSB_TA();
+ ExpectationsCloudWebsocket_TA();
+
+ // Act
+ transport_manager_->Init(mock_last_state_);
+ transport_manager_->Stop();
}
} // namespace transport_manager_test
diff --git a/src/components/transport_manager/test/websocket_connection_test.cc b/src/components/transport_manager/test/websocket_connection_test.cc
index d096d351f5..6f6baa82fd 100644
--- a/src/components/transport_manager/test/websocket_connection_test.cc
+++ b/src/components/transport_manager/test/websocket_connection_test.cc
@@ -276,8 +276,7 @@ TEST_F(WebsocketConnectionTest, WSConnection_SUCCESS) {
.hybrid_app_preference = "CLOUD"};
// Start server
- std::thread t1(&WebsocketConnectionTest::StartWSServer, this, "/");
- usleep(5000);
+ StartWSServer("/");
// Start client
InitWebsocketClient(properties, ws_client);
@@ -294,7 +293,6 @@ TEST_F(WebsocketConnectionTest, WSConnection_SUCCESS) {
// Stop server thread
ws_session->Stop();
- t1.join();
}
TEST_F(WebsocketConnectionTest, WSConnection_SUCCESS_ValidTarget) {
@@ -308,8 +306,7 @@ TEST_F(WebsocketConnectionTest, WSConnection_SUCCESS_ValidTarget) {
.hybrid_app_preference = "CLOUD"};
// Start server
- std::thread t1(&WebsocketConnectionTest::StartWSServer, this, kPath);
- usleep(5000);
+ StartWSServer(kPath);
// Start client
InitWebsocketClient(properties, ws_client);
@@ -326,7 +323,6 @@ TEST_F(WebsocketConnectionTest, WSConnection_SUCCESS_ValidTarget) {
// Stop server thread
ws_session->Stop();
- t1.join();
}
TEST_F(WebsocketConnectionTest, WSConnection_FAILURE_InvalidTarget) {
@@ -340,8 +336,7 @@ TEST_F(WebsocketConnectionTest, WSConnection_FAILURE_InvalidTarget) {
.hybrid_app_preference = "CLOUD"};
// Start server
- std::thread t1(&WebsocketConnectionTest::StartWSServer, this, "/");
- usleep(5000);
+ StartWSServer("/");
// Start client
InitWebsocketClient(properties, ws_client);
@@ -358,7 +353,6 @@ TEST_F(WebsocketConnectionTest, WSConnection_FAILURE_InvalidTarget) {
// Stop server thread
ws_session->Stop();
- t1.join();
}
TEST_F(WebsocketConnectionTest, WSSConnection_SUCCESS) {
@@ -371,8 +365,7 @@ TEST_F(WebsocketConnectionTest, WSSConnection_SUCCESS) {
.hybrid_app_preference = "CLOUD"};
// Start server
- std::thread t1(&WebsocketConnectionTest::StartWSSServer, this, "/");
- usleep(5000);
+ StartWSSServer("/");
// Start client
InitWebsocketClient(properties, ws_client);
@@ -389,7 +382,6 @@ TEST_F(WebsocketConnectionTest, WSSConnection_SUCCESS) {
// Stop server thread
wss_session->Stop();
- t1.join();
}
TEST_F(WebsocketConnectionTest, WSSConnection_SUCCESS_ValidTarget) {
@@ -402,10 +394,7 @@ TEST_F(WebsocketConnectionTest, WSSConnection_SUCCESS_ValidTarget) {
.hybrid_app_preference = "CLOUD"};
// Start server
- std::thread t1(&WebsocketConnectionTest::StartWSSServer,
- this,
- (kPath + kQuery + kFragment));
- usleep(5000);
+ StartWSSServer((kPath + kQuery + kFragment));
// Start client
InitWebsocketClient(properties, ws_client);
@@ -422,7 +411,6 @@ TEST_F(WebsocketConnectionTest, WSSConnection_SUCCESS_ValidTarget) {
// Stop server thread
wss_session->Stop();
- t1.join();
}
#ifdef ENABLE_SECURITY
@@ -436,8 +424,7 @@ TEST_F(WebsocketConnectionTest, WSSConnection_FAILURE_InvalidTarget) {
.hybrid_app_preference = "CLOUD"};
// Start server
- std::thread t1(&WebsocketConnectionTest::StartWSSServer, this, kPath);
- usleep(5000);
+ StartWSSServer(kPath);
// Start client
InitWebsocketClient(properties, ws_client);
@@ -454,7 +441,6 @@ TEST_F(WebsocketConnectionTest, WSSConnection_FAILURE_InvalidTarget) {
// Stop server thread
wss_session->Stop();
- t1.join();
}
TEST_F(WebsocketConnectionTest, WSSConnection_FAILURE_IncorrectCert) {
@@ -467,8 +453,7 @@ TEST_F(WebsocketConnectionTest, WSSConnection_FAILURE_IncorrectCert) {
.hybrid_app_preference = "CLOUD"};
// Start server
- std::thread t1(&WebsocketConnectionTest::StartWSSServer, this, "/");
- usleep(5000);
+ StartWSSServer("/");
// Start client
InitWebsocketClient(properties, ws_client);
@@ -485,7 +470,6 @@ TEST_F(WebsocketConnectionTest, WSSConnection_FAILURE_IncorrectCert) {
// Stop server thread
wss_session->Stop();
- t1.join();
}
#endif // ENABLE_SECURITY
} // namespace transport_manager_test