1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // BlobCache_unittest.h: Unit tests for the blob cache.
7
8 #include <gtest/gtest.h>
9
10 #include "libANGLE/BlobCache.h"
11
12 namespace egl
13 {
14
15 // Note: this is fairly similar to SizedMRUCache_unittest, and makes sure the
16 // BlobCache usage of SizedMRUCache is not broken.
17
18 using BlobPut = angle::MemoryBuffer;
19 using Blob = BlobCache::Value;
20 using Key = BlobCache::Key;
21
22 template <typename T>
MakeSequence(T & seq,uint8_t start)23 void MakeSequence(T &seq, uint8_t start)
24 {
25 for (uint8_t i = 0; i < seq.size(); ++i)
26 {
27 seq[i] = i + start;
28 }
29 }
30
MakeBlob(size_t size,uint8_t start=0)31 BlobPut MakeBlob(size_t size, uint8_t start = 0)
32 {
33 BlobPut blob;
34 EXPECT_TRUE(blob.resize(size));
35 MakeSequence(blob, start);
36 return blob;
37 }
38
MakeKey(uint8_t start=0)39 Key MakeKey(uint8_t start = 0)
40 {
41 Key key;
42 MakeSequence(key, start);
43 return key;
44 }
45
46 // Test a cache with a value that takes up maximum size.
TEST(BlobCacheTest,MaxSizedValue)47 TEST(BlobCacheTest, MaxSizedValue)
48 {
49 constexpr size_t kSize = 32;
50 BlobCache blobCache(kSize);
51
52 blobCache.populate(MakeKey(0), MakeBlob(kSize));
53 EXPECT_EQ(32u, blobCache.size());
54 EXPECT_FALSE(blobCache.empty());
55
56 blobCache.populate(MakeKey(1), MakeBlob(kSize));
57 EXPECT_EQ(32u, blobCache.size());
58 EXPECT_FALSE(blobCache.empty());
59
60 Blob blob;
61 EXPECT_FALSE(blobCache.get(nullptr, nullptr, MakeKey(0), &blob));
62
63 blobCache.clear();
64 EXPECT_TRUE(blobCache.empty());
65 }
66
67 // Test a cache with many small values, that it can handle unlimited inserts.
TEST(BlobCacheTest,ManySmallValues)68 TEST(BlobCacheTest, ManySmallValues)
69 {
70 constexpr size_t kSize = 32;
71 BlobCache blobCache(kSize);
72
73 for (size_t value = 0; value < kSize; ++value)
74 {
75 blobCache.populate(MakeKey(value), MakeBlob(1, value));
76
77 Blob qvalue;
78 EXPECT_TRUE(blobCache.get(nullptr, nullptr, MakeKey(value), &qvalue));
79 if (qvalue.size() > 0)
80 {
81 EXPECT_EQ(value, qvalue[0]);
82 }
83 }
84
85 EXPECT_EQ(32u, blobCache.size());
86 EXPECT_FALSE(blobCache.empty());
87
88 // Putting one element evicts the first element.
89 blobCache.populate(MakeKey(kSize), MakeBlob(1, kSize));
90
91 Blob qvalue;
92 EXPECT_FALSE(blobCache.get(nullptr, nullptr, MakeKey(0), &qvalue));
93
94 // Putting one large element cleans out the whole stack.
95 blobCache.populate(MakeKey(kSize + 1), MakeBlob(kSize, kSize + 1));
96 EXPECT_EQ(32u, blobCache.size());
97 EXPECT_FALSE(blobCache.empty());
98
99 for (size_t value = 0; value <= kSize; ++value)
100 {
101 EXPECT_FALSE(blobCache.get(nullptr, nullptr, MakeKey(value), &qvalue));
102 }
103 EXPECT_TRUE(blobCache.get(nullptr, nullptr, MakeKey(kSize + 1), &qvalue));
104 if (qvalue.size() > 0)
105 {
106 EXPECT_EQ(kSize + 1, qvalue[0]);
107 }
108
109 // Put a bunch of items in the cache sequentially.
110 for (size_t value = 0; value < kSize * 10; ++value)
111 {
112 blobCache.populate(MakeKey(value), MakeBlob(1, value));
113 }
114
115 EXPECT_EQ(32u, blobCache.size());
116 }
117
118 // Tests putting an oversize element.
TEST(BlobCacheTest,OversizeValue)119 TEST(BlobCacheTest, OversizeValue)
120 {
121 constexpr size_t kSize = 32;
122 BlobCache blobCache(kSize);
123
124 blobCache.populate(MakeKey(5), MakeBlob(100));
125
126 Blob qvalue;
127 EXPECT_FALSE(blobCache.get(nullptr, nullptr, MakeKey(5), &qvalue));
128 }
129
130 } // namespace egl
131