Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: test/FilterEngine.cpp

Issue 29435650: Issue 5182, 4688 - improve IsSubscriptionDowloadAllowedCallback and corresponding tests (Closed) Base URL: https://github.com/adblockplus/libadblockplus.git
Patch Set: Created May 10, 2017, 4:55 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/BaseJsTest.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/FilterEngine.cpp
diff --git a/test/FilterEngine.cpp b/test/FilterEngine.cpp
index d486335cda6f54ab1eff7efb91a9adca623084cc..28004417bf313874d490de731c3df7229eb68594 100644
--- a/test/FilterEngine.cpp
+++ b/test/FilterEngine.cpp
@@ -155,130 +155,86 @@ namespace
}
};
- class FilterEngineIsAllowedConnectionTest : public ::testing::Test
+ class FilterEngineIsSubscriptionDownloadAllowedTest : public ::testing::Test
{
- class MockWebRequest : public LazyWebRequest
- {
- public:
- std::map</*beginning of url*/std::string, AdblockPlus::ServerResponse> responses;
-
- AdblockPlus::ServerResponse GET(const std::string& url,
- const AdblockPlus::HeaderList& requestHeaders) const
- {
- for (const auto& response : responses)
- {
- if (Utils::BeginsWith(url, response.first))
- {
- return response.second;
- }
- }
- return LazyWebRequest::GET(url, requestHeaders);
- }
- };
- class SyncStrings
sergei 2017/05/10 17:04:40 since there are no threads there is no need for so
- {
- public:
- void Add(const std::string* value)
- {
- std::lock_guard<std::mutex> lock(mutex);
- strings.emplace_back(!!value, value ? *value : "");
sergei 2017/05/10 17:04:40 this functionality is in the callback body now.
- }
- std::vector<std::pair<bool, std::string>> GetStrings() const
- {
- std::lock_guard<std::mutex> lock(mutex);
- return strings;
- }
- void Clear()
- {
- std::lock_guard<std::mutex> lock(mutex);
- strings.clear();
- }
- private:
- mutable std::mutex mutex;
- std::vector<std::pair<bool, std::string>> strings;
- };
protected:
- std::shared_ptr<MockWebRequest> webRequest;
- std::string subscriptionUrlPrefix;
+ typedef std::vector<std::pair<bool, std::string>> ConnectionTypes;
+ DelayedWebRequest::SharedTasks webRequestTasks;
+ DelayedTimer::SharedTasks timerTasks;
FilterEngine::CreationParameters createParams;
- // HACK: it's a shared pointer to keep it available in
- // isConnectionAllowedCallback after destroying of the test.
- struct SharedData
- {
- SyncStrings capturedConnectionTypes;
- bool isConnectionAllowed;
- struct
- {
- std::string url;
- std::mutex mutex;
- std::condition_variable cv;
- } downloadStatusChanged;
- };
- std::shared_ptr<SharedData> data;
+ ConnectionTypes capturedConnectionTypes;
+ bool isConnectionAllowed;
+ std::vector<std::function<void(bool)>> isSubscriptionDowloadAllowedCallbacks;
FilterEnginePtr filterEngine;
JsEnginePtr jsEngine;
void SetUp()
{
- data = std::make_shared<SharedData>();
+ isConnectionAllowed = true;
+
JsEngineCreationParameters jsEngineParams;
jsEngineParams.logSystem.reset(new LazyLogSystem());
jsEngineParams.fileSystem.reset(new LazyFileSystem());
- jsEngineParams.timer = CreateDefaultTimer();
+ jsEngineParams.timer = DelayedTimer::New(timerTasks);
+ jsEngineParams.webRequest = DelayedWebRequest::New(webRequestTasks);
jsEngine = CreateJsEngine(std::move(jsEngineParams));
- jsEngine->SetWebRequest(webRequest = std::make_shared<MockWebRequest>());
-
- subscriptionUrlPrefix = "http://example";
- ServerResponse exampleSubscriptionResponse;
- exampleSubscriptionResponse.responseStatus = 200;
- exampleSubscriptionResponse.status = IWebRequest::NS_OK;
- exampleSubscriptionResponse.responseText = "[Adblock Plus 2.0]\n||example.com";
- webRequest->responses.emplace(subscriptionUrlPrefix, exampleSubscriptionResponse);
+
createParams.preconfiguredPrefs.emplace("first_run_subscription_auto_select", jsEngine->NewValue(false));
- data->isConnectionAllowed = true;
- auto closure = data;
- createParams.isConnectionAllowedCallback = [closure](const std::string* allowedConnectionType)->bool{
- closure->capturedConnectionTypes.Add(allowedConnectionType);
- return closure->isConnectionAllowed;
+
+ createParams.isSubscriptionDowloadAllowedCallback = [this](const std::string* allowedConnectionType,
+ const std::function<void(bool)>& isSubscriptionDowloadAllowedCallback){
+ capturedConnectionTypes.emplace_back(!!allowedConnectionType, allowedConnectionType ? *allowedConnectionType : std::string());
+ isSubscriptionDowloadAllowedCallbacks.emplace_back(isSubscriptionDowloadAllowedCallback);
};
}
Subscription EnsureExampleSubscriptionAndForceUpdate(const std::string& apppendToUrl = std::string())
{
+ auto subscriptionUrl = "http://example" + apppendToUrl;
+ bool isSubscriptionDownloadStatusReceived = false;
if (!filterEngine)
{
filterEngine = FilterEngine::Create(jsEngine, createParams);
- auto closure = data;
- filterEngine->SetFilterChangeCallback([closure](const std::string& action, JsValue&& item)
+ filterEngine->SetFilterChangeCallback([&isSubscriptionDownloadStatusReceived, &subscriptionUrl](const std::string& action, JsValue&& item)
{
- if (action == "subscription.downloadStatus")
- {
- {
- std::lock_guard<std::mutex> lock(closure->downloadStatusChanged.mutex);
- closure->downloadStatusChanged.url = item.GetProperty("url").AsString();
- }
- closure->downloadStatusChanged.cv.notify_one();
- }
+ if (action == "subscription.downloadStatus" && item.GetProperty("url").AsString() == subscriptionUrl)
+ isSubscriptionDownloadStatusReceived = true;
});
}
- auto subscriptionUrl = subscriptionUrlPrefix + apppendToUrl;
auto subscription = filterEngine->GetSubscription(subscriptionUrl);
EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size()) << subscriptionUrl;
EXPECT_TRUE(subscription.GetProperty("downloadStatus").IsNull()) << subscriptionUrl;
subscription.UpdateFilters();
+
+ // Since currently the check is called from implemenation of web request
+ // they have to been firstly scheduled, namely before processing of
+ // 'is subscription download allowed' callbacks;
+ DelayedTimer::ProcessImmediateTimers(timerTasks);
+
+ for (const auto& isSubscriptionDowloadAllowedCallback : isSubscriptionDowloadAllowedCallbacks)
sergei 2017/05/10 17:04:40 actually, there should be only one callback and on
+ {
+ isSubscriptionDowloadAllowedCallback(isConnectionAllowed);
+ }
+ isSubscriptionDowloadAllowedCallbacks.clear();
+
{
- std::unique_lock<std::mutex> lock(data->downloadStatusChanged.mutex);
- data->downloadStatusChanged.cv.wait_for(lock,
- /*don't block tests forever*/std::chrono::seconds(300),
- [this, subscriptionUrl]()->bool
+ auto ii_webRequest = std::find_if(webRequestTasks->begin(), webRequestTasks->end(), [&subscriptionUrl](const DelayedWebRequest::Task& task)->bool
{
- return subscriptionUrl == data->downloadStatusChanged.url;
+ return Utils::BeginsWith(task.url, subscriptionUrl);
});
- // Basically it's enough to wait only for downloadStatus although there
- // is still some JS code being executed. Any following attempt to work
- // with subscription object will result in execution of JS, which will
- // be blocked until finishing of currently running code.
+
+ // if download is allowed then there should be a web request
+ EXPECT_EQ(isConnectionAllowed, ii_webRequest != webRequestTasks->end());
+ if (ii_webRequest != webRequestTasks->end())
+ {
+ ServerResponse exampleSubscriptionResponse;
+ exampleSubscriptionResponse.responseStatus = 200;
+ exampleSubscriptionResponse.status = IWebRequest::NS_OK;
+ exampleSubscriptionResponse.responseText = "[Adblock Plus 2.0]\n||example.com";
+ ii_webRequest->getCallback(exampleSubscriptionResponse);
+ }
}
+ EXPECT_TRUE(isSubscriptionDownloadStatusReceived);
return subscription;
}
};
@@ -1059,37 +1015,35 @@ namespace AA_ApiTest
}
}
-TEST_F(FilterEngineIsAllowedConnectionTest, AbsentCallbackAllowsUpdating)
+TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, AbsentCallbackAllowsUpdating)
{
- createParams.isConnectionAllowedCallback = FilterEngine::IsConnectionAllowedCallback();
+ createParams.isSubscriptionDowloadAllowedCallback = FilterEngine::IsConnectionAllowedAsyncCallback();
auto subscription = EnsureExampleSubscriptionAndForceUpdate();
EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsString());
EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
}
-TEST_F(FilterEngineIsAllowedConnectionTest, AllowingCallbackAllowsUpdating)
+TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, AllowingCallbackAllowsUpdating)
{
// no stored allowed_connection_type preference
auto subscription = EnsureExampleSubscriptionAndForceUpdate();
EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsString());
EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
- auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
ASSERT_EQ(1u, capturedConnectionTypes.size());
EXPECT_FALSE(capturedConnectionTypes[0].first);
}
-TEST_F(FilterEngineIsAllowedConnectionTest, NotAllowingCallbackDoesNotAllowUpdating)
+TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, NotAllowingCallbackDoesNotAllowUpdating)
{
- data->isConnectionAllowed = false;
+ isConnectionAllowed = false;
// no stored allowed_connection_type preference
auto subscription = EnsureExampleSubscriptionAndForceUpdate();
EXPECT_EQ("synchronize_connection_error", subscription.GetProperty("downloadStatus").AsString());
EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size());
- auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
EXPECT_EQ(1u, capturedConnectionTypes.size());
}
-TEST_F(FilterEngineIsAllowedConnectionTest, PredefinedAllowedConnectionTypeIsPassedToCallback)
+TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, PredefinedAllowedConnectionTypeIsPassedToCallback)
{
std::string predefinedAllowedConnectionType = "non-metered";
createParams.preconfiguredPrefs.insert(std::make_pair("allowed_connection_type",
@@ -1097,13 +1051,12 @@ TEST_F(FilterEngineIsAllowedConnectionTest, PredefinedAllowedConnectionTypeIsPas
auto subscription = EnsureExampleSubscriptionAndForceUpdate();
EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsString());
EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
- auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
ASSERT_EQ(1u, capturedConnectionTypes.size());
EXPECT_TRUE(capturedConnectionTypes[0].first);
EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second);
}
-TEST_F(FilterEngineIsAllowedConnectionTest, ConfiguredConnectionTypeIsPassedToCallback)
+TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, ConfiguredConnectionTypeIsPassedToCallback)
{
// FilterEngine->RemoveSubscription is not usable here because subscriptions
// are cached internally by URL. So, different URLs are used in diffirent
@@ -1115,25 +1068,22 @@ TEST_F(FilterEngineIsAllowedConnectionTest, ConfiguredConnectionTypeIsPassedToCa
auto subscription = EnsureExampleSubscriptionAndForceUpdate();
EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsString());
EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
- auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
ASSERT_EQ(1u, capturedConnectionTypes.size());
EXPECT_TRUE(capturedConnectionTypes[0].first);
EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second);
}
- data->capturedConnectionTypes.Clear();
+ capturedConnectionTypes.clear();
{
// set no value
filterEngine->SetAllowedConnectionType(nullptr);
auto subscription = EnsureExampleSubscriptionAndForceUpdate("subA");
EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsString());
EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
- auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
ASSERT_EQ(1u, capturedConnectionTypes.size());
EXPECT_FALSE(capturedConnectionTypes[0].first);
subscription.RemoveFromList();
- data->capturedConnectionTypes.Clear();
}
- data->capturedConnectionTypes.Clear();
+ capturedConnectionTypes.clear();
{
// set some value
std::string testConnection = "test connection";
@@ -1141,7 +1091,6 @@ TEST_F(FilterEngineIsAllowedConnectionTest, ConfiguredConnectionTypeIsPassedToCa
auto subscription = EnsureExampleSubscriptionAndForceUpdate("subB");
EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsString());
EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
- auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
ASSERT_EQ(1u, capturedConnectionTypes.size());
EXPECT_TRUE(capturedConnectionTypes[0].first);
EXPECT_EQ(testConnection, capturedConnectionTypes[0].second);
« no previous file with comments | « test/BaseJsTest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld