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

Side by Side Diff: test/FilterEngine.cpp

Issue 29499583: Issue 4938 - fix race conditions related to LazyFileSystem (Closed) Base URL: https://github.com/adblockplus/libadblockplus.git
Patch Set: Created July 27, 2017, 8:53 a.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.cpp ('k') | test/Notification.cpp » ('j') | 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 16 matching lines...) Expand all
27 { 27 {
28 inline bool BeginsWith(const std::string& str, const std::string& beginning) 28 inline bool BeginsWith(const std::string& str, const std::string& beginning)
29 { 29 {
30 return 0 == str.compare(0, beginning.size(), beginning); 30 return 0 == str.compare(0, beginning.size(), beginning);
31 } 31 }
32 } 32 }
33 } 33 }
34 34
35 namespace 35 namespace
36 { 36 {
37 class VeryLazyFileSystem : public LazyFileSystem 37 class NoFilesFileSystem : public LazyFileSystem
38 { 38 {
39 public: 39 public:
40 StatResult Stat(const std::string& path) const 40 void Stat(const std::string& path, const StatCallback& callback) const overr ide
41 { 41 {
42 return StatResult(); 42 scheduler([callback]
43 {
44 callback(StatResult(), "");
45 });
43 } 46 }
44 }; 47 };
45 48
46 template<class FileSystem, class LogSystem> 49 template<class LazyFileSystemT, class LogSystem>
47 class FilterEngineTestGeneric : public ::testing::Test 50 class FilterEngineTestGeneric : public ::testing::Test
48 { 51 {
49 protected: 52 protected:
50 FilterEnginePtr filterEngine; 53 FilterEnginePtr filterEngine;
51 54
52 void SetUp() override 55 void SetUp() override
53 { 56 {
57 LazyFileSystemT* fileSystem;
54 JsEngineCreationParameters jsEngineParams; 58 JsEngineCreationParameters jsEngineParams;
55 jsEngineParams.fileSystem.reset(new FileSystem()); 59 jsEngineParams.fileSystem.reset(fileSystem = new LazyFileSystemT());
56 jsEngineParams.logSystem.reset(new LogSystem()); 60 jsEngineParams.logSystem.reset(new LogSystem());
57 jsEngineParams.timer.reset(new NoopTimer()); 61 jsEngineParams.timer.reset(new NoopTimer());
58 jsEngineParams.webRequest.reset(new NoopWebRequest()); 62 jsEngineParams.webRequest.reset(new NoopWebRequest());
59 auto jsEngine = CreateJsEngine(std::move(jsEngineParams)); 63 auto jsEngine = CreateJsEngine(std::move(jsEngineParams));
60 filterEngine = AdblockPlus::FilterEngine::Create(jsEngine); 64 filterEngine = CreateFilterEngine(*fileSystem, jsEngine);
61 }
62 void TearDown() override
63 {
64 // Workaround for issue 5198
65 std::this_thread::sleep_for(std::chrono::milliseconds(100));
sergei 2017/07/27 09:15:32 Since there is no class waiting for its internal t
66 } 65 }
67 }; 66 };
68 67
69 typedef FilterEngineTestGeneric<LazyFileSystem, AdblockPlus::DefaultLogSystem> FilterEngineTest; 68 typedef FilterEngineTestGeneric<LazyFileSystem, AdblockPlus::DefaultLogSystem> FilterEngineTest;
70 typedef FilterEngineTestGeneric<VeryLazyFileSystem, LazyLogSystem> FilterEngin eTestNoData; 69 typedef FilterEngineTestGeneric<NoFilesFileSystem, LazyLogSystem> FilterEngine TestNoData;
71 70
72 class FilterEngineWithFreshFolder : public ::testing::Test 71 class FilterEngineWithFreshFolder : public ::testing::Test
73 { 72 {
74 protected: 73 protected:
75 FileSystemPtr fileSystem; 74 FileSystemPtr fileSystem;
76 std::weak_ptr<JsEngine> weakJsEngine; 75 std::weak_ptr<JsEngine> weakJsEngine;
77 76
78 void SetUp() override 77 void SetUp() override
79 { 78 {
80 fileSystem = CreateDefaultFileSystem(); 79 fileSystem = CreateDefaultFileSystem();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 protected: 142 protected:
144 typedef std::vector<std::pair<bool, std::string>> ConnectionTypes; 143 typedef std::vector<std::pair<bool, std::string>> ConnectionTypes;
145 DelayedWebRequest::SharedTasks webRequestTasks; 144 DelayedWebRequest::SharedTasks webRequestTasks;
146 DelayedTimer::SharedTasks timerTasks; 145 DelayedTimer::SharedTasks timerTasks;
147 FilterEngine::CreationParameters createParams; 146 FilterEngine::CreationParameters createParams;
148 ConnectionTypes capturedConnectionTypes; 147 ConnectionTypes capturedConnectionTypes;
149 bool isConnectionAllowed; 148 bool isConnectionAllowed;
150 std::vector<std::function<void(bool)>> isSubscriptionDownloadAllowedCallback s; 149 std::vector<std::function<void(bool)>> isSubscriptionDownloadAllowedCallback s;
151 FilterEnginePtr filterEngine; 150 FilterEnginePtr filterEngine;
152 JsEnginePtr jsEngine; 151 JsEnginePtr jsEngine;
152 LazyFileSystem* fileSystem;
153 153
154 void SetUp() 154 void SetUp()
155 { 155 {
156 isConnectionAllowed = true; 156 isConnectionAllowed = true;
157 157
158 JsEngineCreationParameters jsEngineParams; 158 JsEngineCreationParameters jsEngineParams;
159 jsEngineParams.logSystem.reset(new LazyLogSystem()); 159 jsEngineParams.logSystem.reset(new LazyLogSystem());
160 jsEngineParams.fileSystem.reset(new LazyFileSystem()); 160 jsEngineParams.fileSystem.reset(fileSystem = new LazyFileSystem());
161 jsEngineParams.timer = DelayedTimer::New(timerTasks); 161 jsEngineParams.timer = DelayedTimer::New(timerTasks);
162 jsEngineParams.webRequest = DelayedWebRequest::New(webRequestTasks); 162 jsEngineParams.webRequest = DelayedWebRequest::New(webRequestTasks);
163 jsEngine = CreateJsEngine(std::move(jsEngineParams)); 163 jsEngine = CreateJsEngine(std::move(jsEngineParams));
164 164
165 createParams.preconfiguredPrefs.emplace("first_run_subscription_auto_selec t", jsEngine->NewValue(false)); 165 createParams.preconfiguredPrefs.emplace("first_run_subscription_auto_selec t", jsEngine->NewValue(false));
166 166
167 createParams.isSubscriptionDownloadAllowedCallback = [this](const std::str ing* allowedConnectionType, 167 createParams.isSubscriptionDownloadAllowedCallback = [this](const std::str ing* allowedConnectionType,
168 const std::function<void(bool)>& isSubscriptionDownloadAllowedCallback){ 168 const std::function<void(bool)>& isSubscriptionDownloadAllowedCallback){
169 capturedConnectionTypes.emplace_back(!!allowedConnectionType, allowedCon nectionType ? *allowedConnectionType : std::string()); 169 capturedConnectionTypes.emplace_back(!!allowedConnectionType, allowedCon nectionType ? *allowedConnectionType : std::string());
170 isSubscriptionDownloadAllowedCallbacks.emplace_back(isSubscriptionDownlo adAllowedCallback); 170 isSubscriptionDownloadAllowedCallbacks.emplace_back(isSubscriptionDownlo adAllowedCallback);
171 }; 171 };
172 } 172 }
173 173
174 Subscription EnsureExampleSubscriptionAndForceUpdate(const std::string& appp endToUrl = std::string()) 174 Subscription EnsureExampleSubscriptionAndForceUpdate(const std::string& appp endToUrl = std::string())
175 { 175 {
176 auto subscriptionUrl = "http://example" + apppendToUrl; 176 auto subscriptionUrl = "http://example" + apppendToUrl;
177 bool isSubscriptionDownloadStatusReceived = false; 177 bool isSubscriptionDownloadStatusReceived = false;
178 if (!filterEngine) 178 if (!filterEngine)
179 { 179 {
180 filterEngine = FilterEngine::Create(jsEngine, createParams); 180 filterEngine = CreateFilterEngine(*fileSystem, jsEngine, createParams);
181 filterEngine->SetFilterChangeCallback([&isSubscriptionDownloadStatusRece ived, &subscriptionUrl](const std::string& action, JsValue&& item) 181 filterEngine->SetFilterChangeCallback([&isSubscriptionDownloadStatusRece ived, &subscriptionUrl](const std::string& action, JsValue&& item)
182 { 182 {
183 if (action == "subscription.downloadStatus" && item.GetProperty("url") .AsString() == subscriptionUrl) 183 if (action == "subscription.downloadStatus" && item.GetProperty("url") .AsString() == subscriptionUrl)
184 isSubscriptionDownloadStatusReceived = true; 184 isSubscriptionDownloadStatusReceived = true;
185 }); 185 });
186 } 186 }
187 auto subscription = filterEngine->GetSubscription(subscriptionUrl); 187 auto subscription = filterEngine->GetSubscription(subscriptionUrl);
188 EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size()) << subs criptionUrl; 188 EXPECT_EQ(0u, subscription.GetProperty("filters").AsList().size()) << subs criptionUrl;
189 EXPECT_TRUE(subscription.GetProperty("downloadStatus").IsNull()) << subscr iptionUrl; 189 EXPECT_TRUE(subscription.GetProperty("downloadStatus").IsNull()) << subscr iptionUrl;
190 subscription.UpdateFilters(); 190 subscription.UpdateFilters();
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 } 584 }
585 585
586 TEST_F(FilterEngineTestNoData, FirstRunFlag) 586 TEST_F(FilterEngineTestNoData, FirstRunFlag)
587 { 587 {
588 ASSERT_TRUE(filterEngine->IsFirstRun()); 588 ASSERT_TRUE(filterEngine->IsFirstRun());
589 } 589 }
590 590
591 TEST_F(FilterEngineTest, SetRemoveFilterChangeCallback) 591 TEST_F(FilterEngineTest, SetRemoveFilterChangeCallback)
592 { 592 {
593 int timesCalled = 0; 593 int timesCalled = 0;
594 std::this_thread::sleep_for(std::chrono::milliseconds(200));
sergei 2017/07/27 09:15:32 #4937 is also fixed now
595 filterEngine->SetFilterChangeCallback([&timesCalled](const std::string&, Adblo ckPlus::JsValue&&) 594 filterEngine->SetFilterChangeCallback([&timesCalled](const std::string&, Adblo ckPlus::JsValue&&)
596 { 595 {
597 timesCalled++; 596 timesCalled++;
598 }); 597 });
599 filterEngine->GetFilter("foo").AddToList(); 598 filterEngine->GetFilter("foo").AddToList();
600 EXPECT_EQ(1, timesCalled); 599 EXPECT_EQ(1, timesCalled);
601 600
602 // we want to actually check the call count didn't change. 601 // we want to actually check the call count didn't change.
603 filterEngine->RemoveFilterChangeCallback(); 602 filterEngine->RemoveFilterChangeCallback();
604 filterEngine->GetFilter("foo").RemoveFromList(); 603 filterEngine->GetFilter("foo").RemoveFromList();
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 std::string testConnection = "test connection"; 1024 std::string testConnection = "test connection";
1026 filterEngine->SetAllowedConnectionType(&testConnection); 1025 filterEngine->SetAllowedConnectionType(&testConnection);
1027 auto subscription = EnsureExampleSubscriptionAndForceUpdate("subB"); 1026 auto subscription = EnsureExampleSubscriptionAndForceUpdate("subB");
1028 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing()); 1027 EXPECT_EQ("synchronize_ok", subscription.GetProperty("downloadStatus").AsStr ing());
1029 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size()); 1028 EXPECT_EQ(1u, subscription.GetProperty("filters").AsList().size());
1030 ASSERT_EQ(1u, capturedConnectionTypes.size()); 1029 ASSERT_EQ(1u, capturedConnectionTypes.size());
1031 EXPECT_TRUE(capturedConnectionTypes[0].first); 1030 EXPECT_TRUE(capturedConnectionTypes[0].first);
1032 EXPECT_EQ(testConnection, capturedConnectionTypes[0].second); 1031 EXPECT_EQ(testConnection, capturedConnectionTypes[0].second);
1033 } 1032 }
1034 } 1033 }
OLDNEW
« no previous file with comments | « test/BaseJsTest.cpp ('k') | test/Notification.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld