prefix_set_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 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/prefix_set.h" 6 7#include <algorithm> 8 9#include "base/logging.h" 10#include "base/rand_util.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13namespace { 14 15SBPrefix GenPrefix() { 16 return static_cast<SBPrefix>(base::RandUint64()); 17} 18 19// Test that a small sparse random input works. 20TEST(PrefixSetTest, Baseline) { 21 std::vector<SBPrefix> prefixes; 22 23 static const size_t kCount = 50000; 24 25 for (size_t i = 0; i < kCount; ++i) { 26 prefixes.push_back(GenPrefix()); 27 } 28 29 std::sort(prefixes.begin(), prefixes.end()); 30 safe_browsing::PrefixSet prefix_set(prefixes); 31 32 // Check that |GetPrefixes()| returns exactly the same set of 33 // prefixes as was passed in. 34 std::set<SBPrefix> check(prefixes.begin(), prefixes.end()); 35 std::vector<SBPrefix> prefixes_copy; 36 prefix_set.GetPrefixes(&prefixes_copy); 37 EXPECT_EQ(prefixes_copy.size(), check.size()); 38 EXPECT_TRUE(std::equal(check.begin(), check.end(), prefixes_copy.begin())); 39 40 // Check that the set flags all of the inputs, and also check items 41 // just above and below the inputs to make sure they aren't there. 42 for (size_t i = 0; i < prefixes.size(); ++i) { 43 EXPECT_TRUE(prefix_set.Exists(prefixes[i])); 44 45 const SBPrefix left_sibling = prefixes[i] - 1; 46 if (check.count(left_sibling) == 0) 47 EXPECT_FALSE(prefix_set.Exists(left_sibling)); 48 49 const SBPrefix right_sibling = prefixes[i] + 1; 50 if (check.count(right_sibling) == 0) 51 EXPECT_FALSE(prefix_set.Exists(right_sibling)); 52 } 53} 54 55// Test that the empty set doesn't appear to have anything in it. 56TEST(PrefixSetTest, Empty) { 57 std::vector<SBPrefix> prefixes; 58 safe_browsing::PrefixSet prefix_set(prefixes); 59 for (size_t i = 0; i < 500; ++i) { 60 EXPECT_FALSE(prefix_set.Exists(GenPrefix())); 61 } 62} 63 64// Use artificial inputs to test various edge cases in Exists(). 65// Items before the lowest item aren't present. Items after the 66// largest item aren't present. Create a sequence of items with 67// deltas above and below 2^16, and make sure they're all present. 68// Create a very long sequence with deltas below 2^16 to test crossing 69// |kMaxRun|. 70TEST(PrefixSetTest, EdgeCases) { 71 std::vector<SBPrefix> prefixes; 72 73 const SBPrefix kVeryPositive = 1000 * 1000 * 1000; 74 const SBPrefix kVeryNegative = -kVeryPositive; 75 76 // Put in a very negative prefix. 77 SBPrefix prefix = kVeryNegative; 78 prefixes.push_back(prefix); 79 80 // Add a sequence with very large deltas. 81 unsigned delta = 100 * 1000 * 1000; 82 for (int i = 0; i < 10; ++i) { 83 prefix += delta; 84 prefixes.push_back(prefix); 85 } 86 87 // Add a sequence with deltas that start out smaller than the 88 // maximum delta, and end up larger. Also include some duplicates. 89 delta = 256 * 256 - 100; 90 for (int i = 0; i < 200; ++i) { 91 prefix += delta; 92 prefixes.push_back(prefix); 93 prefixes.push_back(prefix); 94 delta++; 95 } 96 97 // Add a long sequence with deltas smaller than the maximum delta, 98 // so a new index item will be injected. 99 delta = 256 * 256 - 1; 100 prefix = kVeryPositive - delta * 1000; 101 prefixes.push_back(prefix); 102 for (int i = 0; i < 1000; ++i) { 103 prefix += delta; 104 prefixes.push_back(prefix); 105 delta--; 106 } 107 108 std::sort(prefixes.begin(), prefixes.end()); 109 safe_browsing::PrefixSet prefix_set(prefixes); 110 111 // Check that |GetPrefixes()| returns the same set of prefixes as 112 // was passed in. 113 std::vector<SBPrefix> prefixes_copy; 114 prefix_set.GetPrefixes(&prefixes_copy); 115 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), prefixes.end()); 116 EXPECT_EQ(prefixes_copy.size(), prefixes.size()); 117 EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), 118 prefixes_copy.begin())); 119 120 // Items before and after the set are not present, and don't crash. 121 EXPECT_FALSE(prefix_set.Exists(kVeryNegative - 100)); 122 EXPECT_FALSE(prefix_set.Exists(kVeryPositive + 100)); 123 124 // Check that the set correctly flags all of the inputs, and also 125 // check items just above and below the inputs to make sure they 126 // aren't present. 127 for (size_t i = 0; i < prefixes.size(); ++i) { 128 EXPECT_TRUE(prefix_set.Exists(prefixes[i])); 129 130 EXPECT_FALSE(prefix_set.Exists(prefixes[i] - 1)); 131 EXPECT_FALSE(prefix_set.Exists(prefixes[i] + 1)); 132 } 133} 134 135} // namespace 136