From edcad5dc4c35aa7393a9e76391270e6b5e7bce1b Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sat, 13 Jun 2020 23:47:52 +0200 Subject: [PATCH] fix: fixed deadlock in tests (wait for client to connect, instead on relying on the server) --- test/webfuse/tests/adapter/test_client.cc | 77 +++++++++++------------ test/webfuse/utils/timeout_watcher.cc | 14 +++++ test/webfuse/utils/timeout_watcher.hpp | 2 + 3 files changed, 54 insertions(+), 39 deletions(-) diff --git a/test/webfuse/tests/adapter/test_client.cc b/test/webfuse/tests/adapter/test_client.cc index a8ad723..5a224fd 100644 --- a/test/webfuse/tests/adapter/test_client.cc +++ b/test/webfuse/tests/adapter/test_client.cc @@ -66,22 +66,21 @@ TEST(AdapterClient, Connect) EXPECT_CALL(callback, Invoke(_, WF_CLIENT_GET_TLS_CONFIG, _)).Times(1); EXPECT_CALL(callback, Invoke(_, WF_CLIENT_CLEANUP, nullptr)).Times(1); - EXPECT_CALL(callback, Invoke(_, WF_CLIENT_CONNECTED, nullptr)).Times(1); - EXPECT_CALL(callback, Invoke(_, WF_CLIENT_DISCONNECTED, nullptr)).Times(1); + bool connected = false; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_CONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { connected = true; })); + + bool disconnected = false; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_DISCONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { disconnected = true; })); AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), server.GetUrl()); client.Connect(); - while (!server.IsConnected()) - { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return connected; })); client.Disconnect(); - while (server.IsConnected()) - { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return disconnected; })); } TEST(AdapterClient, Authenticate) @@ -95,32 +94,32 @@ TEST(AdapterClient, Authenticate) MockAdapterClientCallback callback; EXPECT_CALL(callback, Invoke(_, _, _)).Times(AnyNumber()); + + bool connected = false; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_CONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { connected = true; })); + + bool disconnected = false; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_DISCONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { disconnected = true; })); + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_AUTHENTICATE_GET_CREDENTIALS, _)).Times(1) .WillOnce(Invoke(GetCredentials)); - bool called = false; + + bool authenticated = false; EXPECT_CALL(callback, Invoke(_, WF_CLIENT_AUTHENTICATED, nullptr)).Times(1) - .WillOnce(Invoke([&called] (wf_client *, int, void *) mutable { - called = true; - })); + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { authenticated = true; })); AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), server.GetUrl()); client.Connect(); - while (!server.IsConnected()) - { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return connected; })); client.Authenticate(); - while (!called) { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return authenticated; })); client.Disconnect(); - while (server.IsConnected()) - { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return disconnected; })); } TEST(AdapterClient, AuthenticateFailedWithoutConnect) @@ -140,9 +139,7 @@ TEST(AdapterClient, AuthenticateFailedWithoutConnect) AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), ""); client.Authenticate(); - while (!called) { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return called; })); } TEST(AdapterClient, AuthenticationFailed) @@ -156,8 +153,18 @@ TEST(AdapterClient, AuthenticationFailed) MockAdapterClientCallback callback; EXPECT_CALL(callback, Invoke(_, _, _)).Times(AnyNumber()); + + bool connected = false; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_CONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { connected = true; })); + + bool disconnected = false; + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_DISCONNECTED, nullptr)).Times(1) + .WillOnce(Invoke([&] (wf_client *, int, void *) mutable { disconnected = true; })); + EXPECT_CALL(callback, Invoke(_, WF_CLIENT_AUTHENTICATE_GET_CREDENTIALS, _)).Times(1) .WillOnce(Invoke(GetCredentials)); + bool called = false; EXPECT_CALL(callback, Invoke(_, WF_CLIENT_AUTHENTICATION_FAILED, nullptr)).Times(1) .WillOnce(Invoke([&called] (wf_client *, int, void *) mutable { @@ -167,19 +174,11 @@ TEST(AdapterClient, AuthenticationFailed) AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), server.GetUrl()); client.Connect(); - while (!server.IsConnected()) - { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return connected; })); client.Authenticate(); - while (!called) { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return called; })); client.Disconnect(); - while (server.IsConnected()) - { - watcher.check(); - } + ASSERT_TRUE(watcher.waitUntil([&]() mutable { return disconnected; })); } diff --git a/test/webfuse/utils/timeout_watcher.cc b/test/webfuse/utils/timeout_watcher.cc index 8d9add7..705f1f3 100644 --- a/test/webfuse/utils/timeout_watcher.cc +++ b/test/webfuse/utils/timeout_watcher.cc @@ -1,5 +1,6 @@ #include "webfuse/utils/timeout_watcher.hpp" #include +#include using std::chrono::milliseconds; using std::chrono::duration_cast; @@ -41,4 +42,17 @@ void TimeoutWatcher::check() } } +bool TimeoutWatcher::waitUntil(std::function predicate) +{ + bool result = predicate(); + while ((!result) && (!isTimeout())) + { + std::this_thread::yield(); + result = predicate(); + } + + return result; +} + + } \ No newline at end of file diff --git a/test/webfuse/utils/timeout_watcher.hpp b/test/webfuse/utils/timeout_watcher.hpp index 278d25f..3696dd1 100644 --- a/test/webfuse/utils/timeout_watcher.hpp +++ b/test/webfuse/utils/timeout_watcher.hpp @@ -2,6 +2,7 @@ #define WF_TEST_TIMEOUT_WATCHER_HPP #include +#include namespace webfuse_test { @@ -15,6 +16,7 @@ public: ~TimeoutWatcher(); bool isTimeout(); void check(); + bool waitUntil(std::function predicate); private: std::chrono::milliseconds startedAt; std::chrono::milliseconds timeout_;