Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / PurgeableVectorTest.cpp
blobfe55865e44d694b0ff279d6b6cf64c977689553e
1 /*
2 * Copyright (C) 2014 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "config.h"
32 #include "platform/PurgeableVector.h"
34 #include "platform/TestingPlatformSupport.h"
35 #include "public/platform/WebDiscardableMemory.h"
36 #include "wtf/Vector.h"
37 #include <algorithm>
38 #include <cstdlib>
39 #include <gtest/gtest.h>
41 namespace blink {
43 const size_t kTestSize = 32 * 1024;
45 enum DiscardableMemorySupport {
46 DontSupportDiscardableMemory,
47 SupportDiscardableMemory,
50 class PurgeableVectorTestWithPlatformSupport : public testing::TestWithParam<DiscardableMemorySupport> {
51 public:
52 PurgeableVectorTestWithPlatformSupport() : m_testingPlatformSupport(makeTestingPlatformSupportConfig()) { }
54 protected:
55 bool isDiscardableMemorySupported() const { return GetParam() == SupportDiscardableMemory; }
57 TestingPlatformSupport::Config makeTestingPlatformSupportConfig() const
59 TestingPlatformSupport::Config config;
60 config.hasDiscardableMemorySupport = isDiscardableMemorySupported();
61 return config;
64 PurgeableVector::PurgeableOption makePurgeableOption() const
66 return isDiscardableMemorySupported() ? PurgeableVector::Purgeable : PurgeableVector::NotPurgeable;
69 private:
70 TestingPlatformSupport m_testingPlatformSupport;
73 TEST_P(PurgeableVectorTestWithPlatformSupport, grow)
75 PurgeableVector purgeableVector(makePurgeableOption());
76 purgeableVector.grow(kTestSize);
77 ASSERT_EQ(kTestSize, purgeableVector.size());
78 // Make sure the underlying buffer was actually (re)allocated.
79 memset(purgeableVector.data(), 0, purgeableVector.size());
82 TEST_P(PurgeableVectorTestWithPlatformSupport, clear)
84 Vector<char> testData(kTestSize);
85 std::generate(testData.begin(), testData.end(), &std::rand);
87 PurgeableVector purgeableVector(makePurgeableOption());
88 purgeableVector.append(testData.data(), testData.size());
89 EXPECT_EQ(testData.size(), purgeableVector.size());
91 purgeableVector.clear();
92 EXPECT_EQ(0U, purgeableVector.size());
93 EXPECT_EQ(0, purgeableVector.data());
96 TEST_P(PurgeableVectorTestWithPlatformSupport, clearDoesNotResetLockCounter)
98 PurgeableVector purgeableVector(makePurgeableOption());
99 purgeableVector.clear();
100 EXPECT_TRUE(purgeableVector.isLocked());
101 purgeableVector.unlock();
102 EXPECT_FALSE(purgeableVector.isLocked());
105 TEST_P(PurgeableVectorTestWithPlatformSupport, reserveCapacityDoesNotChangeSize)
107 PurgeableVector purgeableVector(makePurgeableOption());
108 EXPECT_EQ(0U, purgeableVector.size());
109 purgeableVector.reserveCapacity(kTestSize);
110 EXPECT_EQ(0U, purgeableVector.size());
113 TEST_P(PurgeableVectorTestWithPlatformSupport, multipleAppends)
115 Vector<char> testData(kTestSize);
116 std::generate(testData.begin(), testData.end(), &std::rand);
118 PurgeableVector purgeableVector(makePurgeableOption());
119 // Force an allocation.
120 const char kSmallString[] = "hello";
121 purgeableVector.append(kSmallString, sizeof(kSmallString));
122 const char* const data = purgeableVector.data();
124 // Append all the testing data in 4 iterations. The |data| pointer should
125 // have been changed at the end of the unit test due to reallocations.
126 const size_t kIterationCount = 4;
127 ASSERT_EQ(0U, testData.size() % kIterationCount);
128 for (size_t i = 0; i < kIterationCount; ++i) {
129 const char* const testDataStart = testData.data() + i * (testData.size() / kIterationCount);
130 purgeableVector.append(testDataStart, testData.size() / kIterationCount);
131 ASSERT_EQ((i + 1) * testData.size() / kIterationCount, purgeableVector.size() - sizeof(kSmallString));
134 ASSERT_EQ(sizeof(kSmallString) + testData.size(), purgeableVector.size());
135 EXPECT_NE(data, purgeableVector.data());
136 EXPECT_EQ(0, memcmp(purgeableVector.data() + sizeof(kSmallString), testData.data(), testData.size()));
139 TEST_P(PurgeableVectorTestWithPlatformSupport, multipleAppendsAfterReserveCapacity)
141 Vector<char> testData(kTestSize);
142 std::generate(testData.begin(), testData.end(), &std::rand);
144 PurgeableVector purgeableVector(makePurgeableOption());
145 purgeableVector.reserveCapacity(testData.size());
146 const char* const data = purgeableVector.data();
148 // The |data| pointer should be unchanged at the end of the unit test
149 // meaning that there should not have been any reallocation.
150 const size_t kIterationCount = 4;
151 ASSERT_EQ(0U, testData.size() % kIterationCount);
152 for (size_t i = 0; i < kIterationCount; ++i) {
153 const char* const testDataStart = testData.data() + i * (testData.size() / kIterationCount);
154 purgeableVector.append(testDataStart, testData.size() / kIterationCount);
155 ASSERT_EQ((i + 1) * testData.size() / kIterationCount, purgeableVector.size());
158 ASSERT_EQ(testData.size(), purgeableVector.size());
159 EXPECT_EQ(data, purgeableVector.data());
160 EXPECT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
163 TEST_P(PurgeableVectorTestWithPlatformSupport, reserveCapacityUsesExactCapacityWhenVectorIsEmpty)
165 Vector<char> testData(kTestSize);
166 std::generate(testData.begin(), testData.end(), &std::rand);
168 PurgeableVector purgeableVector(makePurgeableOption());
169 purgeableVector.reserveCapacity(kTestSize);
170 const char* const data = purgeableVector.data();
172 purgeableVector.append(testData.data(), testData.size());
173 EXPECT_EQ(data, purgeableVector.data());
174 EXPECT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
176 // This test is not reliable if the PurgeableVector uses a plain WTF::Vector
177 // for storage, as it does if discardable memory is not supported; the vectors
178 // capacity will always be expanded to fill the PartitionAlloc bucket.
179 if (isDiscardableMemorySupported()) {
180 // Appending one extra byte should cause a reallocation since the first
181 // allocation happened while the purgeable vector was empty. This behavior
182 // helps us guarantee that there is no memory waste on very small vectors
183 // (which SharedBuffer requires).
184 purgeableVector.append(testData.data(), 1);
185 EXPECT_NE(data, purgeableVector.data());
189 TEST_P(PurgeableVectorTestWithPlatformSupport, appendReservesCapacityIfNeeded)
191 Vector<char> testData(kTestSize);
192 std::generate(testData.begin(), testData.end(), &std::rand);
194 PurgeableVector purgeableVector(makePurgeableOption());
195 // No reserveCapacity().
196 ASSERT_FALSE(purgeableVector.data());
198 purgeableVector.append(testData.data(), testData.size());
199 ASSERT_EQ(testData.size(), purgeableVector.size());
200 ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
203 TEST_P(PurgeableVectorTestWithPlatformSupport, adopt)
205 Vector<char> testData(kTestSize);
206 std::generate(testData.begin(), testData.end(), &std::rand);
207 const Vector<char> testDataCopy(testData);
208 const char* const testDataPtr = testData.data();
210 PurgeableVector purgeableVector(makePurgeableOption());
211 purgeableVector.adopt(testData);
212 EXPECT_TRUE(testData.isEmpty());
213 EXPECT_EQ(kTestSize, purgeableVector.size());
214 ASSERT_EQ(0, memcmp(purgeableVector.data(), testDataCopy.data(), testDataCopy.size()));
216 if (isDiscardableMemorySupported()) {
217 // An extra discardable memory allocation + memcpy() should have happened.
218 EXPECT_NE(testDataPtr, purgeableVector.data());
219 } else {
220 // Vector::swap() should have been used.
221 EXPECT_EQ(testDataPtr, purgeableVector.data());
225 TEST_P(PurgeableVectorTestWithPlatformSupport, adoptEmptyVector)
227 Vector<char> testData;
228 PurgeableVector purgeableVector(makePurgeableOption());
229 purgeableVector.adopt(testData);
232 TEST(PurgeableVectorTestWithPlatformSupport, adoptDiscardsPreviousData)
234 Vector<char> testData;
235 std::generate(testData.begin(), testData.end(), &std::rand);
237 PurgeableVector purgeableVector(PurgeableVector::NotPurgeable);
238 static const char smallString[] = "hello";
239 purgeableVector.append(smallString, sizeof(smallString));
240 ASSERT_EQ(0, memcmp(purgeableVector.data(), smallString, sizeof(smallString)));
242 purgeableVector.adopt(testData);
243 EXPECT_EQ(testData.size(), purgeableVector.size());
244 ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
247 TEST_P(PurgeableVectorTestWithPlatformSupport, unlockWithoutHintAtConstruction)
249 Vector<char> testData(30000);
250 std::generate(testData.begin(), testData.end(), &std::rand);
252 unsigned length = testData.size();
253 PurgeableVector purgeableVector(PurgeableVector::NotPurgeable);
254 purgeableVector.append(testData.data(), length);
255 ASSERT_EQ(length, purgeableVector.size());
256 const char* data = purgeableVector.data();
258 purgeableVector.unlock();
260 // Note that the purgeable vector must be locked before calling data().
261 const bool wasPurged = !purgeableVector.lock();
262 if (isDiscardableMemorySupported()) {
263 // The implementation of purgeable memory used for testing always purges data upon unlock().
264 EXPECT_TRUE(wasPurged);
267 if (isDiscardableMemorySupported()) {
268 // The data should have been moved from the heap-allocated vector to a purgeable buffer.
269 ASSERT_NE(data, purgeableVector.data());
270 } else {
271 ASSERT_EQ(data, purgeableVector.data());
274 if (!wasPurged)
275 ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), length));
278 TEST(PurgeableVectorTest, unlockOnEmptyPurgeableVector)
280 PurgeableVector purgeableVector;
281 ASSERT_EQ(0U, purgeableVector.size());
282 purgeableVector.unlock();
283 ASSERT_FALSE(purgeableVector.isLocked());
286 TEST_P(PurgeableVectorTestWithPlatformSupport, unlockOnPurgeableVectorWithPurgeableHint)
288 Vector<char> testData(kTestSize);
289 std::generate(testData.begin(), testData.end(), &std::rand);
291 PurgeableVector purgeableVector;
292 purgeableVector.append(testData.data(), kTestSize);
293 const char* const data = purgeableVector.data();
295 // unlock() should happen in place, i.e. without causing any reallocation.
296 // Note that the instance must be locked when data() is called.
297 purgeableVector.unlock();
298 EXPECT_FALSE(purgeableVector.isLocked());
299 purgeableVector.lock();
300 EXPECT_TRUE(purgeableVector.isLocked());
301 EXPECT_EQ(data, purgeableVector.data());
304 TEST_P(PurgeableVectorTestWithPlatformSupport, lockingUsesACounter)
306 Vector<char> testData(kTestSize);
307 std::generate(testData.begin(), testData.end(), &std::rand);
309 PurgeableVector purgeableVector(PurgeableVector::NotPurgeable);
310 purgeableVector.append(testData.data(), testData.size());
311 ASSERT_EQ(testData.size(), purgeableVector.size());
313 ASSERT_TRUE(purgeableVector.isLocked()); // SharedBuffer is locked at creation.
314 ASSERT_TRUE(purgeableVector.lock()); // Add an extra lock.
315 ASSERT_TRUE(purgeableVector.isLocked());
317 purgeableVector.unlock();
318 ASSERT_TRUE(purgeableVector.isLocked());
320 purgeableVector.unlock();
321 ASSERT_FALSE(purgeableVector.isLocked());
323 if (purgeableVector.lock())
324 ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
327 // Instantiates all the unit tests using the SharedBufferTestWithPlatformSupport fixture both with
328 // and without discardable memory support.
329 INSTANTIATE_TEST_CASE_P(testsWithPlatformSetUp, PurgeableVectorTestWithPlatformSupport,
330 ::testing::Values(DontSupportDiscardableMemory, SupportDiscardableMemory));
332 } // namespace blink