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

Side by Side 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.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/BaseJsTest.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2017 eyeo GmbH 3 * Copyright (C) 2006-2017 eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 { 148 {
149 return false; 149 return false;
150 } 150 }
151 }; 151 };
152 int i = 5; 152 int i = 5;
153 while ((i-- > 0 && weakJsEngine.lock()) || !safeRemove()) 153 while ((i-- > 0 && weakJsEngine.lock()) || !safeRemove())
154 std::this_thread::sleep_for(std::chrono::seconds(2)); 154 std::this_thread::sleep_for(std::chrono::seconds(2));
155 } 155 }
156 }; 156 };
157 157
158 class FilterEngineIsAllowedConnectionTest : public ::testing::Test 158 class FilterEngineIsSubscriptionDownloadAllowedTest : public ::testing::Test
159 { 159 {
160 class MockWebRequest : public LazyWebRequest
161 {
162 public:
163 std::map</*beginning of url*/std::string, AdblockPlus::ServerResponse> res ponses;
164
165 AdblockPlus::ServerResponse GET(const std::string& url,
166 const AdblockPlus::HeaderList& requestHeaders) const
167 {
168 for (const auto& response : responses)
169 {
170 if (Utils::BeginsWith(url, response.first))
171 {
172 return response.second;
173 }
174 }
175 return LazyWebRequest::GET(url, requestHeaders);
176 }
177 };
178 class SyncStrings
sergei 2017/05/10 17:04:40 since there are no threads there is no need for so
179 {
180 public:
181 void Add(const std::string* value)
182 {
183 std::lock_guard<std::mutex> lock(mutex);
184 strings.emplace_back(!!value, value ? *value : "");
sergei 2017/05/10 17:04:40 this functionality is in the callback body now.
185 }
186 std::vector<std::pair<bool, std::string>> GetStrings() const
187 {
188 std::lock_guard<std::mutex> lock(mutex);
189 return strings;
190 }
191 void Clear()
192 {
193 std::lock_guard<std::mutex> lock(mutex);
194 strings.clear();
195 }
196 private:
197 mutable std::mutex mutex;
198 std::vector<std::pair<bool, std::string>> strings;
199 };
200 protected: 160 protected:
201 std::shared_ptr<MockWebRequest> webRequest; 161 typedef std::vector<std::pair<bool, std::string>> ConnectionTypes;
202 std::string subscriptionUrlPrefix; 162 DelayedWebRequest::SharedTasks webRequestTasks;
163 DelayedTimer::SharedTasks timerTasks;
203 FilterEngine::CreationParameters createParams; 164 FilterEngine::CreationParameters createParams;
204 // HACK: it's a shared pointer to keep it available in 165 ConnectionTypes capturedConnectionTypes;
205 // isConnectionAllowedCallback after destroying of the test. 166 bool isConnectionAllowed;
206 struct SharedData 167 std::vector<std::function<void(bool)>> isSubscriptionDowloadAllowedCallbacks ;
207 {
208 SyncStrings capturedConnectionTypes;
209 bool isConnectionAllowed;
210 struct
211 {
212 std::string url;
213 std::mutex mutex;
214 std::condition_variable cv;
215 } downloadStatusChanged;
216 };
217 std::shared_ptr<SharedData> data;
218 FilterEnginePtr filterEngine; 168 FilterEnginePtr filterEngine;
219 JsEnginePtr jsEngine; 169 JsEnginePtr jsEngine;
220 170
221 void SetUp() 171 void SetUp()
222 { 172 {
223 data = std::make_shared<SharedData>(); 173 isConnectionAllowed = true;
174
224 JsEngineCreationParameters jsEngineParams; 175 JsEngineCreationParameters jsEngineParams;
225 jsEngineParams.logSystem.reset(new LazyLogSystem()); 176 jsEngineParams.logSystem.reset(new LazyLogSystem());
226 jsEngineParams.fileSystem.reset(new LazyFileSystem()); 177 jsEngineParams.fileSystem.reset(new LazyFileSystem());
227 jsEngineParams.timer = CreateDefaultTimer(); 178 jsEngineParams.timer = DelayedTimer::New(timerTasks);
179 jsEngineParams.webRequest = DelayedWebRequest::New(webRequestTasks);
228 jsEngine = CreateJsEngine(std::move(jsEngineParams)); 180 jsEngine = CreateJsEngine(std::move(jsEngineParams));
229 jsEngine->SetWebRequest(webRequest = std::make_shared<MockWebRequest>());
230 181
231 subscriptionUrlPrefix = "http://example";
232 ServerResponse exampleSubscriptionResponse;
233 exampleSubscriptionResponse.responseStatus = 200;
234 exampleSubscriptionResponse.status = IWebRequest::NS_OK;
235 exampleSubscriptionResponse.responseText = "[Adblock Plus 2.0]\n||example. com";
236 webRequest->responses.emplace(subscriptionUrlPrefix, exampleSubscriptionRe sponse);
237 createParams.preconfiguredPrefs.emplace("first_run_subscription_auto_selec t", jsEngine->NewValue(false)); 182 createParams.preconfiguredPrefs.emplace("first_run_subscription_auto_selec t", jsEngine->NewValue(false));
238 data->isConnectionAllowed = true; 183
239 auto closure = data; 184 createParams.isSubscriptionDowloadAllowedCallback = [this](const std::stri ng* allowedConnectionType,
240 createParams.isConnectionAllowedCallback = [closure](const std::string* al lowedConnectionType)->bool{ 185 const std::function<void(bool)>& isSubscriptionDowloadAllowedCallback){
241 closure->capturedConnectionTypes.Add(allowedConnectionType); 186 capturedConnectionTypes.emplace_back(!!allowedConnectionType, allowedCon nectionType ? *allowedConnectionType : std::string());
242 return closure->isConnectionAllowed; 187 isSubscriptionDowloadAllowedCallbacks.emplace_back(isSubscriptionDowload AllowedCallback);
243 }; 188 };
244 } 189 }
245 190
246 Subscription EnsureExampleSubscriptionAndForceUpdate(const std::string& appp endToUrl = std::string()) 191 Subscription EnsureExampleSubscriptionAndForceUpdate(const std::string& appp endToUrl = std::string())
247 { 192 {
193 auto subscriptionUrl = "http://example" + apppendToUrl;
194 bool isSubscriptionDownloadStatusReceived = false;
248 if (!filterEngine) 195 if (!filterEngine)
249 { 196 {
250 filterEngine = FilterEngine::Create(jsEngine, createParams); 197 filterEngine = FilterEngine::Create(jsEngine, createParams);
251 auto closure = data; 198 filterEngine->SetFilterChangeCallback([&isSubscriptionDownloadStatusRece ived, &subscriptionUrl](const std::string& action, JsValue&& item)
252 filterEngine->SetFilterChangeCallback([closure](const std::string& actio n, JsValue&& item)
253 { 199 {
254 if (action == "subscription.downloadStatus") 200 if (action == "subscription.downloadStatus" && item.GetProperty("url") .AsString() == subscriptionUrl)
255 { 201 isSubscriptionDownloadStatusReceived = true;
256 {
257 std::lock_guard<std::mutex> lock(closure->downloadStatusChanged.mu tex);
258 closure->downloadStatusChanged.url = item.GetProperty("url").AsStr ing();
259 }
260 closure->downloadStatusChanged.cv.notify_one();
261 }
262 }); 202 });
263 } 203 }
264 auto subscriptionUrl = subscriptionUrlPrefix + apppendToUrl;
265 auto subscription = filterEngine->GetSubscription(subscriptionUrl); 204 auto subscription = filterEngine->GetSubscription(subscriptionUrl);
266 EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size()) << subs criptionUrl; 205 EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size()) << subs criptionUrl;
267 EXPECT_TRUE(subscription.GetProperty("downloadStatus").IsNull()) << subscr iptionUrl; 206 EXPECT_TRUE(subscription.GetProperty("downloadStatus").IsNull()) << subscr iptionUrl;
268 subscription.UpdateFilters(); 207 subscription.UpdateFilters();
208
209 // Since currently the check is called from implemenation of web request
210 // they have to been firstly scheduled, namely before processing of
211 // 'is subscription download allowed' callbacks;
212 DelayedTimer::ProcessImmediateTimers(timerTasks);
213
214 for (const auto& isSubscriptionDowloadAllowedCallback : isSubscriptionDowl oadAllowedCallbacks)
sergei 2017/05/10 17:04:40 actually, there should be only one callback and on
269 { 215 {
270 std::unique_lock<std::mutex> lock(data->downloadStatusChanged.mutex); 216 isSubscriptionDowloadAllowedCallback(isConnectionAllowed);
271 data->downloadStatusChanged.cv.wait_for(lock, 217 }
272 /*don't block tests forever*/std::chrono::seconds(300), 218 isSubscriptionDowloadAllowedCallbacks.clear();
273 [this, subscriptionUrl]()->bool 219
220 {
221 auto ii_webRequest = std::find_if(webRequestTasks->begin(), webRequestTa sks->end(), [&subscriptionUrl](const DelayedWebRequest::Task& task)->bool
274 { 222 {
275 return subscriptionUrl == data->downloadStatusChanged.url; 223 return Utils::BeginsWith(task.url, subscriptionUrl);
276 }); 224 });
277 // Basically it's enough to wait only for downloadStatus although there 225
278 // is still some JS code being executed. Any following attempt to work 226 // if download is allowed then there should be a web request
279 // with subscription object will result in execution of JS, which will 227 EXPECT_EQ(isConnectionAllowed, ii_webRequest != webRequestTasks->end());
280 // be blocked until finishing of currently running code. 228 if (ii_webRequest != webRequestTasks->end())
229 {
230 ServerResponse exampleSubscriptionResponse;
231 exampleSubscriptionResponse.responseStatus = 200;
232 exampleSubscriptionResponse.status = IWebRequest::NS_OK;
233 exampleSubscriptionResponse.responseText = "[Adblock Plus 2.0]\n||exam ple.com";
234 ii_webRequest->getCallback(exampleSubscriptionResponse);
235 }
281 } 236 }
237 EXPECT_TRUE(isSubscriptionDownloadStatusReceived);
282 return subscription; 238 return subscription;
283 } 239 }
284 }; 240 };
285 } 241 }
286 242
287 TEST_F(FilterEngineTest, FilterCreation) 243 TEST_F(FilterEngineTest, FilterCreation)
288 { 244 {
289 AdblockPlus::Filter filter1 = filterEngine->GetFilter("foo"); 245 AdblockPlus::Filter filter1 = filterEngine->GetFilter("foo");
290 ASSERT_EQ(AdblockPlus::Filter::TYPE_BLOCKING, filter1.GetType()); 246 ASSERT_EQ(AdblockPlus::Filter::TYPE_BLOCKING, filter1.GetType());
291 AdblockPlus::Filter filter2 = filterEngine->GetFilter("@@foo"); 247 AdblockPlus::Filter filter2 = filterEngine->GetFilter("@@foo");
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 } 1008 }
1053 } 1009 }
1054 ASSERT_TRUE(aaSubscription); 1010 ASSERT_TRUE(aaSubscription);
1055 aaSubscription->RemoveFromList(); 1011 aaSubscription->RemoveFromList();
1056 } 1012 }
1057 1013
1058 testSubscriptionState(parameter.expectedAAStatus, otherSubscriptionsNumber); 1014 testSubscriptionState(parameter.expectedAAStatus, otherSubscriptionsNumber);
1059 } 1015 }
1060 } 1016 }
1061 1017
1062 TEST_F(FilterEngineIsAllowedConnectionTest, AbsentCallbackAllowsUpdating) 1018 TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, AbsentCallbackAllowsUpdati ng)
1063 { 1019 {
1064 createParams.isConnectionAllowedCallback = FilterEngine::IsConnectionAllowedCa llback(); 1020 createParams.isSubscriptionDowloadAllowedCallback = FilterEngine::IsConnection AllowedAsyncCallback();
1065 auto subscription = EnsureExampleSubscriptionAndForceUpdate(); 1021 auto subscription = EnsureExampleSubscriptionAndForceUpdate();
1066 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStrin g()); 1022 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStrin g());
1067 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size()); 1023 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
1068 } 1024 }
1069 1025
1070 TEST_F(FilterEngineIsAllowedConnectionTest, AllowingCallbackAllowsUpdating) 1026 TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, AllowingCallbackAllowsUpda ting)
1071 { 1027 {
1072 // no stored allowed_connection_type preference 1028 // no stored allowed_connection_type preference
1073 auto subscription = EnsureExampleSubscriptionAndForceUpdate(); 1029 auto subscription = EnsureExampleSubscriptionAndForceUpdate();
1074 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStrin g()); 1030 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStrin g());
1075 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size()); 1031 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
1076 auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
1077 ASSERT_EQ(1u, capturedConnectionTypes.size()); 1032 ASSERT_EQ(1u, capturedConnectionTypes.size());
1078 EXPECT_FALSE(capturedConnectionTypes[0].first); 1033 EXPECT_FALSE(capturedConnectionTypes[0].first);
1079 } 1034 }
1080 1035
1081 TEST_F(FilterEngineIsAllowedConnectionTest, NotAllowingCallbackDoesNotAllowUpdat ing) 1036 TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, NotAllowingCallbackDoesNot AllowUpdating)
1082 { 1037 {
1083 data->isConnectionAllowed = false; 1038 isConnectionAllowed = false;
1084 // no stored allowed_connection_type preference 1039 // no stored allowed_connection_type preference
1085 auto subscription = EnsureExampleSubscriptionAndForceUpdate(); 1040 auto subscription = EnsureExampleSubscriptionAndForceUpdate();
1086 EXPECT_EQ("synchronize_connection_error", subscription.GetProperty("downloadSt atus").AsString()); 1041 EXPECT_EQ("synchronize_connection_error", subscription.GetProperty("downloadSt atus").AsString());
1087 EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size()); 1042 EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size());
1088 auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
1089 EXPECT_EQ(1u, capturedConnectionTypes.size()); 1043 EXPECT_EQ(1u, capturedConnectionTypes.size());
1090 } 1044 }
1091 1045
1092 TEST_F(FilterEngineIsAllowedConnectionTest, PredefinedAllowedConnectionTypeIsPas sedToCallback) 1046 TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, PredefinedAllowedConnectio nTypeIsPassedToCallback)
1093 { 1047 {
1094 std::string predefinedAllowedConnectionType = "non-metered"; 1048 std::string predefinedAllowedConnectionType = "non-metered";
1095 createParams.preconfiguredPrefs.insert(std::make_pair("allowed_connection_type ", 1049 createParams.preconfiguredPrefs.insert(std::make_pair("allowed_connection_type ",
1096 jsEngine->NewValue(predefinedAllowedConnectionType))); 1050 jsEngine->NewValue(predefinedAllowedConnectionType)));
1097 auto subscription = EnsureExampleSubscriptionAndForceUpdate(); 1051 auto subscription = EnsureExampleSubscriptionAndForceUpdate();
1098 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStrin g()); 1052 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStrin g());
1099 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size()); 1053 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
1100 auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
1101 ASSERT_EQ(1u, capturedConnectionTypes.size()); 1054 ASSERT_EQ(1u, capturedConnectionTypes.size());
1102 EXPECT_TRUE(capturedConnectionTypes[0].first); 1055 EXPECT_TRUE(capturedConnectionTypes[0].first);
1103 EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second); 1056 EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second);
1104 } 1057 }
1105 1058
1106 TEST_F(FilterEngineIsAllowedConnectionTest, ConfiguredConnectionTypeIsPassedToCa llback) 1059 TEST_F(FilterEngineIsSubscriptionDownloadAllowedTest, ConfiguredConnectionTypeIs PassedToCallback)
1107 { 1060 {
1108 // FilterEngine->RemoveSubscription is not usable here because subscriptions 1061 // FilterEngine->RemoveSubscription is not usable here because subscriptions
1109 // are cached internally by URL. So, different URLs are used in diffirent 1062 // are cached internally by URL. So, different URLs are used in diffirent
1110 // checks. 1063 // checks.
1111 { 1064 {
1112 std::string predefinedAllowedConnectionType = "non-metered"; 1065 std::string predefinedAllowedConnectionType = "non-metered";
1113 createParams.preconfiguredPrefs.insert(std::make_pair( 1066 createParams.preconfiguredPrefs.insert(std::make_pair(
1114 "allowed_connection_type", jsEngine->NewValue(predefinedAllowedConnectionT ype))); 1067 "allowed_connection_type", jsEngine->NewValue(predefinedAllowedConnectionT ype)));
1115 auto subscription = EnsureExampleSubscriptionAndForceUpdate(); 1068 auto subscription = EnsureExampleSubscriptionAndForceUpdate();
1116 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing()); 1069 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing());
1117 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size()); 1070 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
1118 auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
1119 ASSERT_EQ(1u, capturedConnectionTypes.size()); 1071 ASSERT_EQ(1u, capturedConnectionTypes.size());
1120 EXPECT_TRUE(capturedConnectionTypes[0].first); 1072 EXPECT_TRUE(capturedConnectionTypes[0].first);
1121 EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second ); 1073 EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second );
1122 } 1074 }
1123 data->capturedConnectionTypes.Clear(); 1075 capturedConnectionTypes.clear();
1124 { 1076 {
1125 // set no value 1077 // set no value
1126 filterEngine->SetAllowedConnectionType(nullptr); 1078 filterEngine->SetAllowedConnectionType(nullptr);
1127 auto subscription = EnsureExampleSubscriptionAndForceUpdate("subA"); 1079 auto subscription = EnsureExampleSubscriptionAndForceUpdate("subA");
1128 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing()); 1080 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing());
1129 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size()); 1081 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
1130 auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
1131 ASSERT_EQ(1u, capturedConnectionTypes.size()); 1082 ASSERT_EQ(1u, capturedConnectionTypes.size());
1132 EXPECT_FALSE(capturedConnectionTypes[0].first); 1083 EXPECT_FALSE(capturedConnectionTypes[0].first);
1133 subscription.RemoveFromList(); 1084 subscription.RemoveFromList();
1134 data->capturedConnectionTypes.Clear();
1135 } 1085 }
1136 data->capturedConnectionTypes.Clear(); 1086 capturedConnectionTypes.clear();
1137 { 1087 {
1138 // set some value 1088 // set some value
1139 std::string testConnection = "test connection"; 1089 std::string testConnection = "test connection";
1140 filterEngine->SetAllowedConnectionType(&testConnection); 1090 filterEngine->SetAllowedConnectionType(&testConnection);
1141 auto subscription = EnsureExampleSubscriptionAndForceUpdate("subB"); 1091 auto subscription = EnsureExampleSubscriptionAndForceUpdate("subB");
1142 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing()); 1092 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing());
1143 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size()); 1093 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
1144 auto capturedConnectionTypes = data->capturedConnectionTypes.GetStrings();
1145 ASSERT_EQ(1u, capturedConnectionTypes.size()); 1094 ASSERT_EQ(1u, capturedConnectionTypes.size());
1146 EXPECT_TRUE(capturedConnectionTypes[0].first); 1095 EXPECT_TRUE(capturedConnectionTypes[0].first);
1147 EXPECT_EQ(testConnection, capturedConnectionTypes[0].second); 1096 EXPECT_EQ(testConnection, capturedConnectionTypes[0].second);
1148 } 1097 }
1149 } 1098 }
OLDNEW
« 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