OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/safe_browsing/bloom_filter.h" | |
6 | |
7 #include <limits.h> | |
8 | |
9 #include <set> | |
10 #include <vector> | |
11 | |
12 #include "base/file_util.h" | |
13 #include "base/logging.h" | |
14 #include "base/memory/ref_counted.h" | |
15 #include "base/path_service.h" | |
16 #include "base/rand_util.h" | |
17 #include "base/scoped_temp_dir.h" | |
18 #include "base/string_util.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace { | |
22 | |
23 SBPrefix GenHash() { | |
24 return static_cast<SBPrefix>(base::RandUint64()); | |
25 } | |
26 | |
27 } | |
28 | |
29 TEST(SafeBrowsingBloomFilter, BloomFilterUse) { | |
30 // Use a small number for unit test so it's not slow. | |
31 int count = 1000; | |
32 | |
33 // Build up the bloom filter. | |
34 scoped_refptr<BloomFilter> filter( | |
35 new BloomFilter(count * BloomFilter::kBloomFilterSizeRatio)); | |
36 | |
37 typedef std::set<SBPrefix> Values; | |
38 Values values; | |
39 for (int i = 0; i < count; ++i) { | |
40 SBPrefix value = GenHash(); | |
41 values.insert(value); | |
42 filter->Insert(value); | |
43 } | |
44 EXPECT_TRUE(filter->CheckChecksum()); | |
45 | |
46 // Check serialization works. | |
47 char* data_copy = new char[filter->size()]; | |
48 memcpy(data_copy, filter->data(), filter->size()); | |
49 scoped_refptr<BloomFilter> filter_copy( | |
50 new BloomFilter(data_copy, filter->size(), filter->hash_keys_)); | |
51 EXPECT_TRUE(filter_copy->CheckChecksum()); | |
52 | |
53 // Check no false negatives by ensuring that every time we inserted exists. | |
54 for (Values::const_iterator i = values.begin(); i != values.end(); ++i) | |
55 EXPECT_TRUE(filter_copy->Exists(*i)); | |
56 | |
57 // Check false positive error rate by checking the same number of items that | |
58 // we inserted, but of different values, and calculating what percentage are | |
59 // "found". | |
60 int found_count = 0; | |
61 int checked = 0; | |
62 while (true) { | |
63 SBPrefix value = GenHash(); | |
64 if (values.count(value)) | |
65 continue; | |
66 | |
67 if (filter_copy->Exists(value)) | |
68 found_count++; | |
69 | |
70 checked++; | |
71 if (checked == count) | |
72 break; | |
73 } | |
74 | |
75 // The FP rate should be 1.2%. Keep a large margin of error because we don't | |
76 // want to fail this test because we happened to randomly pick a lot of FPs. | |
77 double fp_rate = found_count * 100.0 / count; | |
78 CHECK(fp_rate < 5.0); | |
79 | |
80 VLOG(1) << "For safe browsing bloom filter of size " << count | |
81 << ", the FP rate was " << fp_rate << " %"; | |
82 } | |
83 | |
84 // Test that we can read and write the bloom filter file. | |
85 TEST(SafeBrowsingBloomFilter, BloomFilterFile) { | |
86 // Create initial filter. | |
87 const int kTestEntries = BloomFilter::kBloomFilterMinSize; | |
88 scoped_refptr<BloomFilter> filter_write( | |
89 new BloomFilter(kTestEntries * BloomFilter::kBloomFilterSizeRatio)); | |
90 | |
91 for (int i = 0; i < kTestEntries; ++i) | |
92 filter_write->Insert(GenHash()); | |
93 EXPECT_TRUE(filter_write->CheckChecksum()); | |
94 | |
95 // Remove any left over test filters and serialize. | |
96 ScopedTempDir temp_dir; | |
97 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
98 FilePath filter_path = temp_dir.path().AppendASCII("SafeBrowsingTestFilter"); | |
99 ASSERT_TRUE(filter_write->WriteFile(filter_path)); | |
100 | |
101 // Create new empty filter and load from disk. | |
102 BloomFilter* filter = BloomFilter::LoadFile(filter_path); | |
103 ASSERT_TRUE(filter != NULL); | |
104 scoped_refptr<BloomFilter> filter_read(filter); | |
105 EXPECT_TRUE(filter_read->CheckChecksum()); | |
106 | |
107 // Check data consistency. | |
108 EXPECT_EQ(filter_write->hash_keys_.size(), filter_read->hash_keys_.size()); | |
109 | |
110 for (size_t i = 0; i < filter_write->hash_keys_.size(); ++i) | |
111 EXPECT_EQ(filter_write->hash_keys_[i], filter_read->hash_keys_[i]); | |
112 | |
113 EXPECT_EQ(filter_write->size(), filter_read->size()); | |
114 | |
115 EXPECT_EQ(0, | |
116 memcmp(filter_write->data(), filter_read->data(), filter_read->size())); | |
117 } | |
OLD | NEW |