/src/mozilla-central/toolkit/components/url-classifier/tests/gtest/Common.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "Common.h" |
2 | | #include "HashStore.h" |
3 | | #include "Classifier.h" |
4 | | #include "nsAppDirectoryServiceDefs.h" |
5 | | #include "nsTArray.h" |
6 | | #include "nsIThread.h" |
7 | | #include "nsThreadUtils.h" |
8 | | #include "nsUrlClassifierUtils.h" |
9 | | |
10 | | using namespace mozilla; |
11 | | using namespace mozilla::safebrowsing; |
12 | | |
13 | 0 | #define GTEST_SAFEBROWSING_DIR NS_LITERAL_CSTRING("safebrowsing") |
14 | 0 | #define GTEST_TABLE NS_LITERAL_CSTRING("gtest-malware-proto") |
15 | | |
16 | | template<typename Function> |
17 | 0 | void RunTestInNewThread(Function&& aFunction) { |
18 | 0 | nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction( |
19 | 0 | "RunTestInNewThread", std::forward<Function>(aFunction)); |
20 | 0 | nsCOMPtr<nsIThread> testingThread; |
21 | 0 | nsresult rv = |
22 | 0 | NS_NewNamedThread("Testing Thread", getter_AddRefs(testingThread), r); |
23 | 0 | ASSERT_EQ(rv, NS_OK); |
24 | 0 | testingThread->Shutdown(); |
25 | 0 | } Unexecuted instantiation: Unified_cpp_tests_gtest0.cpp:void RunTestInNewThread<testOpenLookupCache()::$_7>(testOpenLookupCache()::$_7&&) Unexecuted instantiation: Unified_cpp_tests_gtest0.cpp:void RunTestInNewThread<TestHasPrefix(nsTString<char> const&, bool, bool)::$_3>(TestHasPrefix(nsTString<char> const&, bool, bool)::$_3&&) Unexecuted instantiation: Unified_cpp_tests_gtest0.cpp:void RunTestInNewThread<UrlClassifierPerProviderDirectory_LookupCache_Test::TestBody()::$_4>(UrlClassifierPerProviderDirectory_LookupCache_Test::TestBody()::$_4&&) Unexecuted instantiation: Unified_cpp_tests_gtest0.cpp:void RunTestInNewThread<UrlClassifierPerProviderDirectory_HashStore_Test::TestBody()::$_5>(UrlClassifierPerProviderDirectory_HashStore_Test::TestBody()::$_5&&) |
26 | | |
27 | | nsresult SyncApplyUpdates(RefPtr<Classifier> aClassifier, |
28 | | TableUpdateArray& aUpdates) |
29 | 0 | { |
30 | 0 | // We need to spin a new thread specifically because the callback |
31 | 0 | // will be on the caller thread. If we call Classifier::AsyncApplyUpdates |
32 | 0 | // and wait on the same thread, this function will never return. |
33 | 0 |
|
34 | 0 | nsresult ret = NS_ERROR_FAILURE; |
35 | 0 | bool done = false; |
36 | 0 | auto onUpdateComplete = [&done, &ret](nsresult rv) { |
37 | 0 | // We are on the "ApplyUpdate" thread. Post an event to main thread |
38 | 0 | // so that we can avoid busy waiting on the main thread. |
39 | 0 | nsCOMPtr<nsIRunnable> r = |
40 | 0 | NS_NewRunnableFunction("SyncApplyUpdates", [&done, &ret, rv] { |
41 | 0 | ret = rv; |
42 | 0 | done = true; |
43 | 0 | }); |
44 | 0 | NS_DispatchToMainThread(r); |
45 | 0 | }; |
46 | 0 |
|
47 | 0 | nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("SyncApplyUpdates", [&]() { |
48 | 0 | nsresult rv = aClassifier->AsyncApplyUpdates(aUpdates, onUpdateComplete); |
49 | 0 | if (NS_FAILED(rv)) { |
50 | 0 | onUpdateComplete(rv); |
51 | 0 | } |
52 | 0 | }); |
53 | 0 |
|
54 | 0 | nsCOMPtr<nsIThread> testingThread; |
55 | 0 | NS_NewNamedThread("ApplyUpdates", getter_AddRefs(testingThread)); |
56 | 0 | if (!testingThread) { |
57 | 0 | return NS_ERROR_FAILURE; |
58 | 0 | } |
59 | 0 | |
60 | 0 | testingThread->Dispatch(r, NS_DISPATCH_NORMAL); |
61 | 0 |
|
62 | 0 | // NS_NewCheckSummedOutputStream in HashStore::WriteFile |
63 | 0 | // will synchronously init NS_CRYPTO_HASH_CONTRACTID on |
64 | 0 | // the main thread. As a result we have to keep processing |
65 | 0 | // pending event until |done| becomes true. If there's no |
66 | 0 | // more pending event, what we only can do is wait. |
67 | 0 | MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return done; })); |
68 | 0 |
|
69 | 0 | return ret; |
70 | 0 | } |
71 | | |
72 | | already_AddRefed<nsIFile> |
73 | | GetFile(const nsTArray<nsString>& path) |
74 | 0 | { |
75 | 0 | nsCOMPtr<nsIFile> file; |
76 | 0 | nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(file)); |
77 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
78 | 0 | return nullptr; |
79 | 0 | } |
80 | 0 | |
81 | 0 | for (uint32_t i = 0; i < path.Length(); i++) { |
82 | 0 | file->Append(path[i]); |
83 | 0 | } |
84 | 0 | return file.forget(); |
85 | 0 | } |
86 | | |
87 | | void ApplyUpdate(TableUpdateArray& updates) |
88 | 0 | { |
89 | 0 | nsCOMPtr<nsIFile> file; |
90 | 0 | NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(file)); |
91 | 0 |
|
92 | 0 | RefPtr<Classifier> classifier = new Classifier(); |
93 | 0 | classifier->Open(*file); |
94 | 0 |
|
95 | 0 | { |
96 | 0 | // Force nsIUrlClassifierUtils loading on main thread |
97 | 0 | // because nsIUrlClassifierDBService will not run in advance |
98 | 0 | // in gtest. |
99 | 0 | nsresult rv; |
100 | 0 | nsCOMPtr<nsIUrlClassifierUtils> dummy = |
101 | 0 | do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID, &rv); |
102 | 0 | ASSERT_TRUE(NS_SUCCEEDED(rv)); |
103 | 0 | } |
104 | 0 |
|
105 | 0 | SyncApplyUpdates(classifier, updates); |
106 | 0 | } |
107 | | |
108 | | void ApplyUpdate(TableUpdate* update) |
109 | 0 | { |
110 | 0 | TableUpdateArray updates = { update }; |
111 | 0 | ApplyUpdate(updates); |
112 | 0 | } |
113 | | |
114 | | void |
115 | | PrefixArrayToPrefixStringMap(const nsTArray<nsCString>& prefixArray, |
116 | | PrefixStringMap& out) |
117 | 0 | { |
118 | 0 | out.Clear(); |
119 | 0 |
|
120 | 0 | for (uint32_t i = 0; i < prefixArray.Length(); i++) { |
121 | 0 | const nsCString& prefix = prefixArray[i]; |
122 | 0 | nsCString* prefixString = out.LookupOrAdd(prefix.Length()); |
123 | 0 | prefixString->Append(prefix.BeginReading(), prefix.Length()); |
124 | 0 | } |
125 | 0 | } |
126 | | |
127 | | nsresult |
128 | | PrefixArrayToAddPrefixArrayV2(const nsTArray<nsCString>& prefixArray, |
129 | | AddPrefixArray& out) |
130 | 0 | { |
131 | 0 | out.Clear(); |
132 | 0 |
|
133 | 0 | for (size_t i = 0; i < prefixArray.Length(); i++) { |
134 | 0 | // Create prefix hash from string |
135 | 0 | Prefix hash; |
136 | 0 | static_assert(sizeof(hash.buf) == PREFIX_SIZE, "Prefix must be 4 bytes length"); |
137 | 0 | memcpy(hash.buf, prefixArray[i].BeginReading(), PREFIX_SIZE); |
138 | 0 |
|
139 | 0 | AddPrefix *add = out.AppendElement(fallible); |
140 | 0 | if (!add) { |
141 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
142 | 0 | } |
143 | 0 | |
144 | 0 | add->addChunk = i; |
145 | 0 | add->prefix = hash; |
146 | 0 | } |
147 | 0 |
|
148 | 0 | return NS_OK; |
149 | 0 | } |
150 | | |
151 | | nsCString |
152 | | GeneratePrefix(const nsCString& aFragment, uint8_t aLength) |
153 | 0 | { |
154 | 0 | Completion complete; |
155 | 0 | complete.FromPlaintext(aFragment); |
156 | 0 |
|
157 | 0 | nsCString hash; |
158 | 0 | hash.Assign((const char *)complete.buf, aLength); |
159 | 0 | return hash; |
160 | 0 | } |
161 | | |
162 | | static nsresult |
163 | | BuildCache(LookupCacheV2* cache, const _PrefixArray& prefixArray) |
164 | 0 | { |
165 | 0 | AddPrefixArray prefixes; |
166 | 0 | AddCompleteArray completions; |
167 | 0 | nsresult rv = PrefixArrayToAddPrefixArrayV2(prefixArray, prefixes); |
168 | 0 | if (NS_FAILED(rv)) { |
169 | 0 | return rv; |
170 | 0 | } |
171 | 0 | |
172 | 0 | EntrySort(prefixes); |
173 | 0 | return cache->Build(prefixes, completions); |
174 | 0 | } |
175 | | |
176 | | static nsresult |
177 | | BuildCache(LookupCacheV4* cache, const _PrefixArray& prefixArray) |
178 | 0 | { |
179 | 0 | PrefixStringMap map; |
180 | 0 | PrefixArrayToPrefixStringMap(prefixArray, map); |
181 | 0 | return cache->Build(map); |
182 | 0 | } |
183 | | |
184 | | template<typename T> |
185 | | RefPtr<T> |
186 | | SetupLookupCache(const _PrefixArray& prefixArray) |
187 | 0 | { |
188 | 0 | nsCOMPtr<nsIFile> file; |
189 | 0 | NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(file)); |
190 | 0 |
|
191 | 0 | file->AppendNative(GTEST_SAFEBROWSING_DIR); |
192 | 0 |
|
193 | 0 | RefPtr<T> cache = new T(GTEST_TABLE, EmptyCString(), file); |
194 | 0 | nsresult rv = cache->Init(); |
195 | 0 | EXPECT_EQ(rv, NS_OK); |
196 | 0 |
|
197 | 0 | rv = BuildCache(cache, prefixArray); |
198 | 0 | EXPECT_EQ(rv, NS_OK); |
199 | 0 |
|
200 | 0 | return cache; |
201 | 0 | } Unexecuted instantiation: RefPtr<mozilla::safebrowsing::LookupCacheV2> SetupLookupCache<mozilla::safebrowsing::LookupCacheV2>(nsTArray<nsTString<char> > const&) Unexecuted instantiation: RefPtr<mozilla::safebrowsing::LookupCacheV4> SetupLookupCache<mozilla::safebrowsing::LookupCacheV4>(nsTArray<nsTString<char> > const&) |